みなさんこんにちは、FromAtomです。
2024年8月22日(木)〜8月24日(土)に開催されたiOSDC Japan 2024において、ピクシブから3名のエンジニアが登壇し、スポンサーブースの出展をしました! この記事では、それぞれの発表資料に発表者からの一言コメントを添えて紹介しつつ、ブースで出題していたクイズの回答・解説をまとめたいと思います。
詳解UIWindow
atsuyan:名前はよく知られているものの普段の開発であまり触る機会のないUIWindowについて、深掘りしてお話ししました!セッション聞いてくださった方からも「UIWindowの表示順やステータスバー挙動について知らなかった」「ふわっとしていたUIWindowに対する理解を固められて良かった」という感想をいただけて、UIWindowに対するまとまった知見を発信できて良かったです!
数値を文字列に整形する際の落とし穴とその解決策
glassfiber:初めての現地参加でルーキーズLTに登壇することになり、勝手がわからず右往左往していましたが、なんとか5分に収めて終わることができました。浮動小数点数の扱いを誤るといろいろ不具合が発生することは、Swiftに限らず昔から数値計算の領域で知られていますが、実際に直面したときに解決する方法を知っておきたいものだと思いました。
PencilKitで実装するPDFへの手書き注釈
Ras:Apple Pencilや指からのドローイングをアプリに組み込むためのApple標準ライブラリPencilKitの紹介でした!iOS18からはツールピッカーのカスタマイズやApple Pencil Pro向けのAPIが追加される予定で、今後もますますPencilKitが活用される場面が増えると思います。PencilKitを使ってアプリ機能を実装する際に今回の発表が参考になれば幸いです!
スポンサーブース
今年のスポンサーブースではピクシブのiOSアプリエンジニアからのクイズを出題していました。クイズに見事正解した方には、オリジナルのLGTM扇子をプレゼントしました。
全部で5問用意したので、その問題と解説を記載します。開催期間中にはたくさんの方に挑戦していただきました。ありがとうございました!
SafeAreaと背景色の性質 by tatsubee
正解:D
- Point 1:
proxy.size.height
は画面の縦の長さではなく、SafeAreaの縦の長さになる - Point 2: SafeArea外の背景色は、接触したViewの背景色を反映する
proxy.size.height - 1
の通り、SafeAreaの縦の長さよりちょっと小さいViewが、ZStackのalignmentによって中央寄せされているため、青色背景のTextはtop・bottomどちらのSafeArea外とも0.5ポイントだけ接しておらず、top・bottomの両方から赤色が見える。
- 補足1: マイナスせずに
proxy.size.height
とすると、SafeArea外は青くなる(回答Aと同じになる) - 補足2:
proxy.size.height - 0.3
くらいにすると、SafeArea外は青くなる。おそらく0.15ポイントという指定が小さすぎて無効化されていると思われる。 - 補足3: VStackに入れてSpacerで詰めるなど、何かしらの方法でSafeArea外と接触させると、接触した方のSafeArea外は青くなる
- 補足4: .backgroundにも引数に
ignoresSafeAreaEdges
があり、これでignoreしないようにすることで、SafeArea外への色の反映を行わないようにできる。デフォルトは.all
。
tatsubeeが個人開発を行なっている中で遭遇した挙動をクイズとして出してみました。正解された方でも、意外と補足1の内容は分からなかった方も多いのではないでしょうか?tatsubeeは分からなかったので解消までに結構時間を溶かしました。
SwiftUIを実装している中で、SafeArea外の色がおかしいなと思ったら、これを思い出してもらえると幸いです。
iPhoneの重さ by glassfiber
正解:C
ポイント: なぜか画面が小さいiPhone 14 Proの方がiPhone 14 Plusより重い
- iPhone 15 Pro:187g
- iPhone 15 Plus:201g
- iPhone 14 Pro:206g
- iPhone 14 Plus:203g
唯一、技術と関係ない問題でした。
「iPhone15は材質がチタンに変わって軽くなった」「Plusの方が画面が大きい」などの情報から推測したものと、実際の順番が食い違っていて面白いと思ったのですが、こんなの覚えてる人いませんよね…。
一応、その場で調べることは許容していたので、調べればわかるということで難易度は2にしていました。
SwiftUIのジェスチャー by ああうえ
正解:B
実際に実行してみないとわかりづらい問題だったので微妙な出題だったかもしれません。
minimumDuration: 0.1とした場合と同様に「1→2→4」と表示されそうですが、コンソールには「2→3→4」と表示されます。
実機やシミュレーターだとロングタップ中や後にドラッグしてしまっている可能性があるため、念の為XCTestのUIテストで press(forDuration:)
を使って検証して同様の結果を得ました。
minimumDuration: 0.0に指定するのがそもそも意味がないという話はあるんですが、この挙動のおかげで3日くらいバグに悩まされた記憶があります。
出題中にDeNAのojunさんがXcode 16 Betaでビルドをするとどちらも「2→3→4」となることを発見してくれました。LongPressGestureのonChangeが呼ばれる挙動が実は不具合だったのかもしれません。iOS 18 Betaのシミュレーターでも事前に実験していたのですが、Xcode 15でビルドをしていたので詰めが甘かったです。
この問題は挙動の謎さを伝えたかったというのもあるのですが、もう1つの出題意図としてSwiftUIのジェスチャーは sequenced(before:)
exclusively(before:)
simultaneously(with:)
で合成ができるのとても良いなと思っていて、良さを伝える目的でこの問題を作ってみました。
NSTextStorageDelegateで得られる文字入力イベント by FromAtom
正解:B
editedTextは editedMask
で指定されている範囲の文字列を取得しています。この範囲は日本語等の変換待ちや英語入力時のサジェストも含まれます。deltaは編集前の長さと編集後の長さの差を返します。そのため、 ky
から きょ
に変わる瞬間にはdeltaが0になっています。
結構クセがあるAPIのため「こんなん何に使うねん」という感じですが、Google DocsやNotionのような同時編集機能を実装したい場合にはUITextViewDelegateでは機能が足りないため、このAPIが役に立ちます。みなさんが同時編集機能を実装する時に思い出してみてください。
UIWindowの表示順 by atsuyan
正解:A
UIWindowの表示順に関しては windowLevel
の高いものほど前面に表示されるため、 windowLevel
の高い順に表示を確認していきます。
まず windowLevel
が一番高い greenWindow
ですが、インスタンスを保持しておらず解放されてしまうため画面には表示されません。
次に windowLevel
が高い blueWindow
ですが、表示のための実装がどこにもないため非表示のUIWindowが存在することになります。(UIWindowはデフォルトで isHidden: true
になっています)
redWindow
と yellowWindow
は同じ windowLevel
ですが、 yellowWindow
の makeKeyAndVisible()
後に redWindow
の isHidden = false
が実行されており、最後に表示状態になった redWindow
が前面に表示されます。
そのため、画面に表示される色は A: 🟥 red
になります。
今回iOSDCで発表した「詳解UIWindow」にちなんで、UIWindowの表示順というクイズを用意してみました。iOSDCのブースでは B: 🟨 yellow
が回答されることが多く、「makeKeyAndVisible()
を呼ぶことで (keyと付いているので) primary にできそう」「 yellowWindow
の方が先に定義されているから」という感想をいただくことが多かったです(作問者としてはAとBで悩んで欲しいなと思っていたので嬉しかったです)。 makeKeyAndVisible()
とは何なのか、 windowLevel
が同じ時の挙動がどうなるのか「詳解UIWindow」のスライドの方に書いてあるのでぜひそちらも見ていただけると嬉しいです。
まとめ
今年のiOSDC Japanではたこ焼きやクレープ、Swiftコードバトルやスポンサーブースビンゴなど、新しい企画がたくさんあり、楽しく快適な時間を過ごすことができました。また、冷蔵庫も新設されており、暑い夏に冷たい水やお茶がとても助かりました。
ブースには多くの人が訪れてクイズに挑戦していただきました。ちょっと難易度が高めかなと思ったのですが、多くの人が正解を出しており、扇子も喜んでいただいたのでとても嬉しかったです。
実行委員会のみなさま、スポンサー各社さま、スピーカーのみなさま、参加者のみなさまのおかげで、今年のiOSDCも楽しく過ごすことができました。本当にありがとうございました!