iOS Safari でキーボード表示時にフッターを固定するもう1つの方法
エディタを作っていると iOS Safari でキーボードを開いたときの挙動は本当に大変ですよね。 この記事では、キーボードを開いたままスクロールしてもフッターを固定できるようなワークアラウンドを最近見つけたので紹介します。 Safari 16 以降が必要。キーボード開閉時に追従が遅れる挙動は改善しません。
デモは https://mechairoi.github.io/ios-safari-virtual-keyboard/。iPhone か iOS Simulator でお試しください。
GitHub - mechairoi/ios-safari-virtual-keyboard
Virtual Keyboard の挙動
Virtual Keyboard を開いたときには以下のようなことが起こっていると推測しています。
- Visual_Viewport_API で取得できる Visual Viewport のサイズがキーボードを除いた領域のサイズまで小さくなります。
- レイアウトの計算をするときにはキーボード表示前の Visual Viewport が使われます。vh 単位や fixed, sticky 要素の位置などは表示前と変わりません。
- スクロールしたときに、キーボード表示前の Visual Viewport のうち画面に表示されている位置が変わることがあり、fixed 要素が動いて見えます。
- Layout Viewport の上に大小二つの Visual Viewport が重なっていてそこから見ている感じです、ややこしいですね。
- Layout Viewport の下?に謎の余白が追加されます。下にスクロールし続けると余白が表示されます。
- キーボードと重なる位置にある入力要素をタップしてキーボードを開いたとき、キーボードに隠れないようにするためかスクロールが発生します。
- また、キーボードを開いている状態で他の入力要素等にフォーカスが移動したときにもスクロールが発生します。
ワークアラウンド
まず画面全体にスクロール可能な要素を表示します。さらにSafari 16 から使えるようになった overscroll-behavior: contain
をすることでスワイプやフリック操作による window
のスクロールを防ぎます。window
がスクロールしなければ固定した要素が動いて見えることはありません。
#root { overflow-y: scroll; overscroll-behavior: contain; width: 100svw; height: 100svh; }
キーボード開閉時などどうしてもスクロールが発生してしまうタイミングでは JavaScript で計算して要素を移動したりするのはこれまでの方法と変わらないです。
ダイアログなど他の要素を画面に固定したいときは position:sticky
を使うか、position:fixed
か position:absolute
で固定した要素の内側もスクロール可能にしてoverscroll-behavior: contain
します。overscroll-behavior: contain
しないと固定した要素上でスワイプしたときにwindow
がスクロールしてしまいます。また選択範囲のすぐ隣にツールバー出すときはコンテンツに対して固定できれば良いので position:relative
と position:absolute
が使えます。
他にも以下のような工夫をしてます。
- コンテンツが少ないときも
overscroll-behavior
を効かせるためにmin-height
を指定して微妙にスクロールできるようにします。 overscroll-behavior-y:contain
があると Safari では pull to refresh できなくなってしまいます。キーボードを閉じているときは pull to refresh できるようにoverscroll-behavior-y:contain
はキーボードが開いている間だけ有効にします。maximum-scale=1
でツールバーを非表示
機能を使ったタイミングで微妙に拡大されてしまうのを防ぎます。指定していても最近のブラウザではピンチアウトで拡大できると思います…- キーボードを開いた時にカーソルがヘッダやフッタの下に隠れてしまうことがあるので調整が必要ですが、少し頑張ればなんとかなるでしょう。
この方法でも実現できるUIに制限があり現実的にはある程度妥協することになりそうです。Safari が interactive-widget=resizes-content
に対応してくれるとかなり解決する気がするので、なんとかお願いします。
参考文献
SQLiteでLinderaを使った日本語全文検索
これは はてなエンジニアアドベントカレンダー2023 3日目の記事です。
昨日は id:pokutuna さんの
でした。私も若い頃に同僚とGitHub上で白熱してしまい観光名所になってしまっていたような気がします。気を付けていきましょう。
さて、この記事では SQLiteでLinderaを使った日本語全文検索をする話を紹介します。
モチベーション
上の記事でも話題になっているように個人開発ではDBのコストは問題です。同様に全文検索したいときにもコストに頭を悩ませているのではないでしょうか?
たとえば Amazon OpenSearch Service は t2.micro でも東京リージョンでは $20.44 /月/台 から 、冗長化には最低で3台必要です。他にもマネージドなDBで全文検索するにもプラグインや拡張が自由に入れられず日本語の検索に向いたトークナイザが使えなかったりと、安価で楽に運用できる方法はあまりありません。
そこで fly.io の LiteFS Cloud なら10GBまでは $5/月/組織です。fly.io の請求は月 $5未満? *1*2 は $0 になるようなので実質無料(?)*3で冗長構成です 。あとはいい感じに全文検索ができるようになれば解決です。Litestream も良さそうですね。
SQLite のカスタムトークナイザ
SQLite には SQLite FTS5 Extension という全文検索用の Extension があり、これを使うとSQLで全文検索できます。
CREATE VIRTUAL TABLE email USING fts5(sender, title, body); SELECT * FROM email WHERE email MATCH ? ORDER BY bm25(fts);
デフォルトではあまり日本語の検索に向いたトークナイザはありませんがカスタムトークナイザを load して使うことができます。
既存の日本語向けのカスタムトークナイザは手元でうまく動かせなかったりしたので、signalapp/Signal-FTS5-Extension を fork してみました。オリジナルでは Unicode Text Segmentation を使ってますが、日本語を検索したいので lindera-morphology/lindera を使うように書き換えていきます。Lindera は Meilisearch などでも使われている Rust で書かれた形態素解析ライブラリです。動詞の活用や漢数字の正規化もやってくれます。
できたら .load
してテーブル作成時にtokenizerを指定して使います
.load "./lib/libsignal_tokenizer" "signal_fts5_tokenizer_init" CREATE VIRTUAL TABLE email USING fts5(sender, title, body, tokenize="signal_tokenizer");
signalapp/Signal-FTS5-Extension のライセンスは AGPL 3.0 なので忘れず公開しましょう。
https://github.com/mechairoi/Signal-FTS5-Extension
デモ
試しに簡単なWebアプリケーションを書いて、fly.ioの一番小さいマシン(shared 1 cpu, 256MB)にデプロイしてみます。
https://wispy-wildflower-1272.fly.dev/
アクセスが無いときは0台にスケールする設定にしているのでコールドスタートは遅いです。 辞書は lindera-ipadic、データセットは日本語 Wikipedia のサブセット(134万件、335MB) を使っていて、DBのファイルサイズは1021 MBになりました。 アプリケーションのソースコードはこちら
https://github.com/mechairoi/litefs-fts-demo
マッチする記事数が多くなるクエリでは少し遅くなりますが、インクリメンタルサーチでも違和感なく使える速度が出ていると思います。
この記事は はてなエンジニア Advent Calendar 2023 3日目の記事でした。 次は id:mizdra さんです。楽しみですね。
*1:https://community.fly.io/t/questions-on-100-billing-discount/11133
*2:先月はダッシュボードでは $5.06 でしたが 100% Discount でした
*3:無料で使うにはインスタンスのストレージがトータル3GBまで、詳しくは https://fly.io/docs/about/pricing/
ghq/fzf で選んだリポジトリに対応する tmux の session を作ったり探したりするスクリプト
gist41201c4579d17253b7bd26e699c6dccb
といったことを行うスクリプトです。
session の current directory がリポジトリのルートに設定されるので、別のシェルを使いたいときは tmux new-window
などで新しい端末を開けば cd する必要もありません。
作業リポジトリを切り替えたいときも、このスクリプトを起動して選ぶだけで、以前の session があれば記憶とともに蘇ることでしょう。
Wikipedia の作り方 / How to make Wikipedia
こんにちは。アプリケーションエンジニアの id:mechairoi です。
この記事は はてなエンジニアアドベントカレンダー2014 の10日目です。
昨日は id:hatz48 さんの Mackerel と fluentd でサービスの状態を可視化する - Hatena Developer Blog でした。
今日は Wikipedia の作り方について紹介します。
必要なもの
スチロール半球 450m/m【ディスプレイ用品・デコレーション】
- 出版社/メーカー: ドガ
- メディア:
- この商品を含むブログを見る
- 2つ必要。
- 出版社/メーカー: 清水製作所
- メディア: Tools & Hardware
- クリック: 2回
- この商品を含むブログを見る
- スチロールを切るのに使います。
- プリンタ、 白の塗料、 セロテープ、 やわらかい鉛筆、 はさみ、のり、お休みの日
作り方
なんとたった7ステップで完成です。
1. くっつける
450mmの半球が届くと想像より大きくてテンションがあがってしまいますが落ち着きます。輪っかにしたセロテープで2つの半球を貼りあわせて球にします。あとで剥がすのでさらっと貼るとよいでしょう。
2. 補助線をひく
くっつけた球にやわらかい鉛筆で補助線をひきます。
Wikimedia official marks/About the official Marks - Wikimedia Foundation のいろんな方向からみたWikipediaの様子が参考になります。
「W」と「И」の間を通っている線(上図の赤線)が赤道だとすると、南極と北極を結ぶ線を等間隔に10本ひいてから、赤道に平行な線を北半球と南半球に3本づつひきましょう。半球のつなぎ目(上図の青線)と赤道を直交させるとよいでしょう。
やわらかいメジャーやIKEAでもらえる紙の定規があると捗ります。
3. 下書き
スチロールカッターで切断する線を下書きします。
ステップ2と同じように Wikimedia official marks/About the official Marks - Wikimedia Foundation をみながら手で雑に書いていきます。ついでにピースに対応する文字も書いておきます。リンク先は各方向から見た様子と展開後とで文字の配置が微妙の異なるので嵌らないように気をつけましょう。
もちろんピースが無いところは自由に想像を膨らませて書きます。
4. スチロールカッターで切る
仮止めしたセロテープを剥がし、スチロールカッターで切ります。
一定のペースでカッターを動かすとなめらかに仕上がります。下書きから多少ずれても問題ありません。球の中心から出るレーザーで切るようなイメージでカッターを動かすとやりやすいかもしれません。スチロールの厚みでピースの噛み合わせがうまくいかないところもあるので断面の内側を削って調整します。削り過ぎると安定しなくなるのでほどほどに。半球の境界と重なったピースはセロテープでくっつけます。
ここまでくればパズルを組み立てて遊ぶのもよいでしょう。
5. 白く塗る
下書きで汚れたピースの表面を塗料で白く塗って綺麗にします。塗る前にピースの裏に対応する文字を書いておくと後で楽です。
6. 文字を入れる
Wikimedia official marks/About the official Marks - Wikimedia Foundation にある文字のSVGを Inkscape とかで適当に並べて印刷します。印刷した文字をはさみで切ってのりで浮かないように貼ります。文字のまわりに白い部分が残ってもほとんど目立たないのでシュッとやるとよいでしょう。
7. 装う
かぶって仮装パーティに向かうもよし、分解してコンパクトなまま持ち込んで現地で組み立てるもよしです。お気に入りのTシャツとコーディネートするのもオススメです。
おわりに
はてなでは、パーティを一緒に盛り上げてくれる方やScalaエンジニアも募集しています。
Wikipedia への寄付もお願いします。
Ways to Give - Wikimedia Foundation
明日は id:shimobayashi さんの予定です。よろしくお願いします!
追記
Wikipedia の作り方 - *iroi*塗装の塗料なにつかったんだろう。ポスカ?
2014/12/10 13:40
最初は
のマット ホワイトつや消しでやってたんですが、量が足りなかったので2年前に使った
の残りを使いました!
emacs から git-browse-remote で GitHub をいい感じにひらく
カーソル位置とかリージョンで選んだ範囲をブラウザで開けるやつです。
C-u
つけると --rev
になるのがおしゃれポイントです。
以上です。