Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

こんなにあった!ゆめみでの iOS 14 対応 / Towards iOS 14 in YUM...

Daichi Hayashi
November 06, 2020

こんなにあった!ゆめみでの iOS 14 対応 / Towards iOS 14 in YUMEMI.inc

Daichi Hayashi

November 06, 2020
Tweet

More Decks by Daichi Hayashi

Other Decks in Technology

Transcript

  1. iOS 14 までのバッファ無さ過ぎ問題 2020/09/16: #AppleEvent ! にて… Apple 「明日 iOS

    14 リリースしますんで。よろしく」 → ゆめみでも急遽対応が必要に
  2. てことで「iOS 14 対応まとめアプリ」作りました • daichikuwa0618/Towards14 という repo です • iOS13

    と iOS14 というブランチがあります。 • iOS13: iOS 13 以下で正常動作するブランチ • iOS14: iOS 14 に対応させたブランチ • PR やコードを見れば一通りの iOS 14 対応が分かるはず daichikuwa0618/Towards14 https://github.com/daichikuwa0618/Towards14
  3. UIScrollView + UIPageControl の View (iOS 13) • スクロールでページネーションする View

    • UIScrollView + UIPageControl によって実現 • TextField に総ページ数を入力して button を押すと 入力した総ページ数に変わる
  4. UIScrollView + UIPageControl の View (iOS 13) • スクロールでページネーションする View

    • UIScrollView + UIPageControl によって実現 • TextField に総ページ数を入力して button を押すと 入力した総ページ数に変わる
  5. UIScrollView + UIPageControl の View (iOS 13) UIScrollView UIPageControl •

    スクロールでページネーションする View • UIScrollView + UIPageControl によって実現 • TextField に総ページ数を入力して button を押すと 入力した総ページ数に変わる
  6. UIScrollView + UIPageControl の View (iOS 13) • スクロールでページネーションする View

    • UIScrollView + UIPageControl によって実現 • TextField に総ページ数を入力して button を押すと 入力した総ページ数に変わる UITextField UIButton
  7. 20 ドット表示した時の UIPageControl (iOS 13) • TextField に総ページ数を入力して button を押すと

    入力した総ページ数に変わる • UIPageControl の左右をタップすることで ページ移動することも可能 • UIPageControl のドット数は画面幅に応じて 20 ドットくらいは表示可能
  8. 20 ドット表示した時の UIPageControl (iOS 13) • TextField に総ページ数を入力して button を押すと

    入力した総ページ数に変わる • UIPageControl の左右をタップすることで ページ移動することも可能 • UIPageControl のドット数は画面幅に応じて 20 ドットくらいは表示可能
  9. 原因: UIPageControl の仕様変更 WWDC2020: Build with iOS pickers, menus and

    actions より ドットにイメージを割り当てられたりと、色々仕様が変わった
  10. 相違点 1: 幅とドットの数 iOS 13 iOS 14 • 幅が iOS

    14 の方が小さい • 半分くらいになっている • ドットの数も iOS 14 の方が少ない • iOS 13: 20 個 • iOS 14: 10 個
  11. 相違点 2: 端の方のドットの大きさ iOS 13 iOS 14 • iOS 13

    では全て同じ大きさ • iOS 14 では端につれて小さくなっている • 全ドット表示せず、一部だけ表示することで “Unlimited pages” を実現している
  12. 解決法: 今の所無し iOS 14 の仕様変更に付き合っていく 1 2 UIPageControl を別の表現に変える •

    工数 0 で修正は不要 • Human Interface Guidelines (HIG) によれば、 「10 ドットを超えるとページを一目で数えるのが難しくなり、 20 ドットを超えると任意のページに辿り着くのが困難になる。 総ページが 20 を超える可能性がある場合は、 別の非順次 View (グリッドなど) の使用を検討するべき。」 UIPageControlContentView の width は変わらなかった #
  13. ボタンを押すと外部ブラウザを開く (iOS 13) • ボタンタップで外部ブラウザを開く View • 開けない URL の場合はエラーアラートを表示する

    canOpenURL(url) == true canOpenURL(url) == false iOS Simulator での動作 • ブラウザを開く前に開ける URL かチェックしている
  14. ボタンを押すと外部ブラウザを開く (iOS 13) • ボタンタップで外部ブラウザを開く View • 開けない URL の場合はエラーアラートを表示する

    canOpenURL(url) == true canOpenURL(url) == false iOS Simulator での動作 • ブラウザを開く前に開ける URL かチェックしている
  15. ボタンを押すと外部ブラウザを開く (iOS 13) • ボタンタップで外部ブラウザを開く View • 開けない URL の場合はエラーアラートを表示する

    canOpenURL(url) == true canOpenURL(url) == false iOS Simulator での動作 • ブラウザを開く前に開ける URL かチェックしている
  16. 実装コード (一部) @IBAction func tapOpenURLButton(_ sender: Any) { let url

    = URL(string: "https://apple.com")! if UIApplication.shared.canOpenURL(url) { // canOpenURL(_:) == true Ͱ͋Ε͹։͘ UIApplication.shared.open(url) } else { // Τϥʔ࣌͸ΞϥʔτΛදࣔ showAlert("Error", message: "Cannot open this URL.") } } 1 2 3 canOpenURL(_:) で URL が開けるかチェック 1 canOpenURL == true であれば open(url) 2 canOpenURL == false であればアラート表示 3
  17. 原因: canOpenURL(_:) の公式 doc. にあった 要約 Info.plist の LSApplicationQueriesSchemes に

    開きたいカスタム URL スキームを宣言してね。 そうでないと常に false になります。 https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl • URL にはカスタムスキーム (twitter 等) や facetime や 通常のスキーム (http, https, tel) を持ちうる • → http, https も canOpenURL でチェックすることを想定している
  18. 解決法: Info.plist に追加する (diff) <plist version="1.0"> <dict> + <key>LSApplicationQueriesSchemes</key> +

    <array> + <string>http</string> + <string>https</string> + </array> <key>CFBundleDevelopmentRegion</key> … diff: Info.plist
  19. 解決法: Info.plist に追加する (Xcode) 1 2 3 4 1 2

    3 4 + ボタンを押す 「LSApplicationQueriesSchemes」を入力 Array にする http, https を追加する
  20. UIStackView を使った View • UIStackView を使った View • VStack (縦

    StackView) → HStack (横 StackView) の 入れ子になっている • HStack の中に UILabel が 2 つある • StackView に背景色は付けないデザイン
  21. UIStackView を使った View VStack HStack UILabel • UIStackView を使った View

    • VStack (縦 StackView) → HStack (横 StackView) の 入れ子になっている • HStack の中に UILabel が 2 つある • StackView に背景色は付けないデザイン
  22. 何が変わったのか iOS 13 iOS 14 • UIStackView はレンダリングされない UIView だった

    • あくまで役割としては「subview の配置を整理する」こと • IB, コードで backgroundColor を付けれるものの、 レンダリングされないので反映もされない • UIStackView がレンダリングされるようになった • 従って backgroundColor も見える • 本質的には CATransformLayer → CALayer に変わった
  23. Push 遷移する View (iOS 13) • 画面中央ボタンタップで Push 遷移する View

    • navigationItem.backBarButton の タイトルを空にするデザイン要求がある設定
  24. Push 遷移する View (iOS 13) • 画面中央ボタンタップで Push 遷移する View

    • navigationItem.backBarButton の タイトルを空にするデザイン要求がある設定
  25. どうやってタイトルを消しているか override func viewDidLoad() { super.viewDidLoad() self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "",

    style: .plain, target: nil, action: nil) } • title が空の UIBarButtonItem を backBarButton に設定 • self.title = “” でも OK • ちなみに、デフォルトだと “Back” になる (下図参照 ()
  26. iOS 14: backButton 長押しでメニューが表示 • iOS 14 ではメニュー系の変更が多くある • バックボタンの長押しによる履歴メニュー表示も追加要素

    • 遷移した履歴が一覧できるように • 今まで一つずつ戻っていたのが、一気に戻れるように
  27. iOS 14: backButton 長押しでメニューが表示 • iOS 14 ではメニュー系の変更が多くある • バックボタンの長押しによる履歴メニュー表示も追加要素

    • 遷移した履歴が一覧できるように • 今まで一つずつ戻っていたのが、一気に戻れるように
  28. backButtonDisplayMode の挙動まとめ title の取得元 title, navigationItem.title, navigationItem.backButtonTitle navigationItem.backBarButtonItem .default औಘݩ

    or දࣔ෯͕ڱ͍৔߹͸ “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .generic “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .minimal 空欄 औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back”
  29. backButtonDisplayMode の挙動まとめ title の取得元 title, navigationItem.title, navigationItem.backButtonTitle navigationItem.backBarButtonItem .default औಘݩ

    or දࣔ෯͕ڱ͍৔߹͸ “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .generic “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .minimal 空欄 औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” タイトルだけ変更する系統: ボタンアイテムごと作り直す系統:
  30. backButtonDisplayMode の挙動まとめ title の取得元 title, navigationItem.title, navigationItem.backButtonTitle navigationItem.backBarButtonItem .default औಘݩ

    or දࣔ෯͕ڱ͍৔߹͸ “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .generic “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .minimal 空欄 औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” タイトルだけ変更する系統: ボタンアイテムごと作り直す系統:
  31. backButtonDisplayMode の挙動まとめ title の取得元 title, navigationItem.title, navigationItem.backButtonTitle navigationItem.backBarButtonItem .default औಘݩ

    or දࣔ෯͕ڱ͍৔߹͸ “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .generic “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .minimal 空欄 औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” タイトルだけ変更する系統: ボタンアイテムごと作り直す系統:
  32. backButtonDisplayMode の挙動まとめ title の取得元 title, navigationItem.title, navigationItem.backButtonTitle navigationItem.backBarButtonItem .default औಘݩ

    or දࣔ෯͕ڱ͍৔߹͸ “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .generic “Back” औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” .minimal 空欄 औಘݩ or දࣔ෯͕ڱ͍৔߹͸ “Back” タイトルだけ変更する系統: ボタンアイテムごと作り直す系統:
  33. iOS14 から title の取得元は複数ある WWDC2020: Build with iOS pickers, menus

    and actions より 3 つのプロパティから最適な物を自動で選ぶっぽい + “Back”
  34. .minimal を使って iOS 14 に対応 // NOTE: iOS 14 Ͱ͸௕ԡ͠Ͱϝχϡʔ͕ग़ΔΑ͏ʹͳͬͨͷͰ

    UI/UX ཱ྆ͷͨΊʹॲཧΛ੾Γ෼͚͍ͯΔ if #available(iOS 14.0, *) { navigationItem.backButtonDisplayMode = .minimal // title = "1൪໨" ΋ OK navigationItem.backButtonTitle = "1൪໨" } else { // title = "" ΋ OK navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } OS バージョンによって切り替え (backButtonDisplayMode は iOS 14 から) 1 backButtonDisplayMode = .minimal に (バックボタンタイトルを表示しない) 2 履歴メニュータイトルに表示したいタイトルをセット 3 iOS 13 以下を今までの方法でケアする 4
  35. .minimal を使って iOS 14 に対応 // NOTE: iOS 14 Ͱ͸௕ԡ͠Ͱϝχϡʔ͕ग़ΔΑ͏ʹͳͬͨͷͰ

    UI/UX ཱ྆ͷͨΊʹॲཧΛ੾Γ෼͚͍ͯΔ if #available(iOS 14.0, *) { navigationItem.backButtonDisplayMode = .minimal // title = "1൪໨" ΋ OK navigationItem.backButtonTitle = "1൪໨" } else { // title = "" ΋ OK navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } 1 OS バージョンによって切り替え (backButtonDisplayMode は iOS 14 から) 1 backButtonDisplayMode = .minimal に (バックボタンタイトルを表示しない) 2 履歴メニュータイトルに表示したいタイトルをセット 3 iOS 13 以下を今までの方法でケアする 4
  36. .minimal を使って iOS 14 に対応 // NOTE: iOS 14 Ͱ͸௕ԡ͠Ͱϝχϡʔ͕ग़ΔΑ͏ʹͳͬͨͷͰ

    UI/UX ཱ྆ͷͨΊʹॲཧΛ੾Γ෼͚͍ͯΔ if #available(iOS 14.0, *) { navigationItem.backButtonDisplayMode = .minimal // title = "1൪໨" ΋ OK navigationItem.backButtonTitle = "1൪໨" } else { // title = "" ΋ OK navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } 2 OS バージョンによって切り替え (backButtonDisplayMode は iOS 14 から) 1 backButtonDisplayMode = .minimal に (バックボタンタイトルを表示しない) 2 履歴メニュータイトルに表示したいタイトルをセット 3 iOS 13 以下を今までの方法でケアする 4
  37. .minimal を使って iOS 14 に対応 // NOTE: iOS 14 Ͱ͸௕ԡ͠Ͱϝχϡʔ͕ग़ΔΑ͏ʹͳͬͨͷͰ

    UI/UX ཱ྆ͷͨΊʹॲཧΛ੾Γ෼͚͍ͯΔ if #available(iOS 14.0, *) { navigationItem.backButtonDisplayMode = .minimal // title = "1൪໨" ΋ OK navigationItem.backButtonTitle = "1൪໨" } else { // title = "" ΋ OK navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } 3 OS バージョンによって切り替え (backButtonDisplayMode は iOS 14 から) 1 backButtonDisplayMode = .minimal に (バックボタンタイトルを表示しない) 2 履歴メニュータイトルに表示したいタイトルをセット 3 iOS 13 以下を今までの方法でケアする 4
  38. .minimal を使って iOS 14 に対応 // NOTE: iOS 14 Ͱ͸௕ԡ͠Ͱϝχϡʔ͕ग़ΔΑ͏ʹͳͬͨͷͰ

    UI/UX ཱ྆ͷͨΊʹॲཧΛ੾Γ෼͚͍ͯΔ if #available(iOS 14.0, *) { navigationItem.backButtonDisplayMode = .minimal // title = "1൪໨" ΋ OK navigationItem.backButtonTitle = "1൪໨" } else { // title = "" ΋ OK navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) } 4 OS バージョンによって切り替え (backButtonDisplayMode は iOS 14 から) 1 backButtonDisplayMode = .minimal に (バックボタンタイトルを表示しない) 2 履歴メニュータイトルに表示したいタイトルをセット 3 iOS 13 以下を今までの方法でケアする 4
  39. 解決法: タイトルは付けて透過させる override func viewDidLoad() { super.viewDidLoad() self.navigationItem.backBarButtonItem = UIBarButtonItem(title:

    “0൪໨", style: .plain, target: nil, action: nil) } 長押しした時に表示したいタイトルを設定 1
  40. 解決法: タイトルは付けて透過させる override func viewDidLoad() { super.viewDidLoad() self.navigationItem.backBarButtonItem = UIBarButtonItem(title:

    “0൪໨", style: .plain, target: nil, action: nil) } 長押しした時に表示したいタイトルを設定 1 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let appearance = UINavigationBarAppearance() appearance.configureWithDefaultBackground() appearance.backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear] UINavigationBar.appearance().standardAppearance = appearance UINavigationBar.appearance().compactAppearance = appearance return true } AppDelegate に backButton を透過させる処理を追加 2
  41. iOS 14 以降の backButtonTitle の動作調査 self.title navigationItem.backButtonTitle backButtonTitle nil nil

    “Back” “0 ൪໨ͷ View” nil “0 ൪໨ͷ View” nil “” (ۭจࣈ) “” (ۭจࣈ) “0 ൪໨ͷ View” “” (ۭจࣈ) “” (ۭจࣈ) “” (ۭจࣈ) “0 ൪໨ͷ View” “0 ൪໨ͷ View” navigationItem.backButtonTitle が優先されるっぽい
  42. 1. UIPageControl の仕様が変わった iOS 13 iOS 14 • UIPageControlContentView が追加

    • 幅が拡がらなくなった • 画面幅が表示限界 → iOS 14 から無制限に • 表示されるドットが 11 個を超えないように 変更点: 対策: • 対策は無い • この仕様に付き合う • 別の表現に変える
  43. 2. デフォルトブラウザを変えるとエラー • 外部ブラウザのデフォルトを変更できるように • デフォルトメーラーも同様 • 何もしてないと canOpenURL(_:) が

    false になる 変更点: 対策: • Info.plist の LSApplicationQueriesSchemes に 開きたいカスタム URL スキームを宣言 • Web リンク: http, https • メール: mailto
  44. 2. デフォルトブラウザを変えるとエラー • 外部ブラウザのデフォルトを変更できるように • デフォルトメーラーも同様 • 何もしてないと canOpenURL(_:) が

    false になる 変更点: 対策: • Info.plist の LSApplicationQueriesSchemes に 開きたいカスタム URL スキームを宣言 • Web リンク: http, https • メール: mailto
  45. 3. UIStackView の背景色が突然現れた 変更点: 対策: • UIStackView の背景色が付くようになった • UIStackView

    は非レンダリング View → レンダリングされるように • 従って set した背景色が見た目に反映される • IB, コード上で背景色を指定してないか確認する
  46. 4. backButton 長押しメニューの対応 変更点: 対策: • バックボタン長押しで履歴メニューが追加に • iOS 13

    以下の方法でバックボタンタイトルを空にすると 履歴メニュータイトルが空になり UX が低下する • navigationItem.backButtonDisplayMode プロパティが追加 • バックボタンタイトルの表示方法を制御 • navigationItem.backButtonDisplayMode = .minimal と iOS 14 に設定してやる
  47. ちょっと「ゆめみ」の宣伝 • 弊社: ゆめみは BnB2C という形の受託制作会社 • お客様によりよいものづくりを提案しながら C 向けアプリを中心に作ってます

    • 変な制度が沢山ある (給与自己決定、有給取り放題など) • その中の一つに「一ヶ月で 16 時間 (2 日分) 自由に使っていい」という「10% ルール」がある • この Towards14 アプリの作成、スライド作成、発表練習全て 10% ルールの中でやった • 未経験で今年新卒入社した自分から見て、成長環境としてとても良い会社 「変わった会社で自由にやりたい」という方に向いてるかも?
  48. 最後に自己紹介 林 大地 (Daichi Hayashi) • 夢は宇宙飛行士 • ゆめみに未経験新卒として入社: iOS

    経験 1 年未満 • これから強い iOS 開発者になる (予定) @daichidaiji
  49. 参考文献: UIPageControl • WWDC2020: Build with iOS pickers, menus and

    actions • https://developer.apple.com/videos/play/wwdc2020/10052/ • HIG: Page Controls • https://developer.apple.com/design/human-interface-guidelines/ios/ controls/page-controls/ •
  50. 参考文献: UIStackView 背景色 • Stack View Background Color in iOS

    14 • https://useyourloaf.com/blog/stack-view-background-color-in-ios-14/ • CALayer | Apple • https://developer.apple.com/documentation/quartzcore/calayer • CATransformLayer | Apple • https://developer.apple.com/documentation/quartzcore/catransformlayer
  51. 参考文献: canOpenURL == false 問題 • Stack View Background Color

    in iOS 14 • https://useyourloaf.com/blog/stack-view-background-color-in-ios-14/ • 【iOS14】デフォルトブラウザを変更した時にcanOpenURLがfalseになる問題 • https://qiita.com/toto_kit/items/757dfe0a9fddb28eeff5 •
  52. 参考文献: backButton 長押しメニュー対応 • A new way to manage the

    back button title in iOS 14 with backButtonDisplayMode • https://sarunw.com/posts/new-way-to-manage-back-button-title-in-ios14/ • 色々実験されていて参考になります。 • WWDC2020: Build with iOS pickers, menus and actions • https://developer.apple.com/videos/play/wwdc2020/10052/ • iOS14Ͱ໭ΔϘλϯͷλΠτϧΛۭཝʹ͢Δ͖ͪΜͱͨ͠ํ๏ • https://spinners.work/posts/ios14_blank_back_button/ • ઌि౤ߘ͞ΕͯΔͷݟ͚ͭ·ͨ͠ɻ೔ຊޠͳͷͰ͔͜͜ΒಡΉͷ͋ΓͰ͢ɻ
  53. CATransformLayer • 「他の CALayer クラスで使用されている フラット化されたレンダリング層ではなく、 3Dレイヤー層を作成するために使用される」 • サブレイヤーのみがレンダリングされる •

    レイヤによってレンダリングされる CALayer プロパティは無視される • ここに backgroundColor, contents, border 等 のプロパティが含まれる