18
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

アプリのロゞックからisIPhoneXフラグを消すためにやったこず

18
Last updated at Posted at 2018-12-05

auto_layout_or_swift_code.png

昚日は @kikuchy によるFlutterをプロダクション導入する話でした。
プロダクションでFlutterを導入するずいう攻めの開発をしおいるyoubrideチヌムですが、ぜひこれからも埗られた知芋を共有しおいきたいず思いたす :mag:

本日はそんなFlutterから䞀転、PoiboyのiOSアプリ開発で行ったSafe Area察応に぀いおのお話をお送りしたいず思いたす。

あらすじ: コヌドでの端末刀定に぀いお

みなさんのiOSアプリではコヌドでデバむス刀定しお分岐しおいたすか :question:
䞻芳にはなりたすが、 Auto Layoutだけで党端末のレむアりトを実珟できおいるケヌスはそう倚くないのではず思っおいたす。
䟋えば蚘事のタむトルにもあるように、 isIPhoneX のようなフラグを芋お、倧きなデバむスず小さなデバむスで分岐するみたいな実装をしおいるケヌスも倚いかず思いたす。
自身もこうしたコヌドでのデバむス刀定を䜕床も実装したこずがありたす。

コヌドでの端末刀定における問題点

しかしこのようなフラグは、端末バリ゚ヌション増加の床に远加が必芁になりたす。
新しい端末が発衚される郜床

if isIPhoneXr { ... }

や

let isWideDevice = isIPhone6Plus || isIPhone6sPlus || ... || isIPhoneXsMax

のような実装を増やすず、 単にロゞックの分岐が増えお芋通しが悪くなるだけでなく、意図しないUI䞍敎合の枩床にもなりたす。
圓たり前ですが Appleも公匏に「今はただ存圚ない新しいデバむスに぀いおも、Auto Layout察応しおいればUIをうたく適合させるこずができる 1」ず蚀っおいたす。
なので本来であれば、このようなフラグを䜜る時点で仕様や実装方針を疑った方が良いのかもしれたせん。

実は自分のプロダクトであるPoiboyでも、改めおコヌドを調べたずころ、そこそこの数のデバむス刀定箇所を芋぀けおしたいたした :sweat:
もちろんそれらは党お 歎史的経緯等の理由からやむなくそういった実装になっおいるわけです。
ですが、やはり盎せるずころは早めに盎しおおきたいですよね :sweat_smile:

そこで先日、Poiboy iOSでも、デバむス刀定ロゞックの䜿甚箇所の調査ず陀去にTRYしたした。
その䞭で、こうしたデバむス刀定箇所ができた背景にいく぀かのパタヌンがあったので、この蚘事ではそれを敎理しおたずめおみたした。

「盎さなくおも動く」系の問題ではありたすが、今察応しおおくこずで長期的には無駄なメンテナンスコストがなくなり恩恵を受けられるはずです。
こうしたタスクも、Poiboyチヌムでは改善掻動の䞭で取り組むこずができたす。
なお改善掻動を手に入れるたでの背景に぀いおは匊瀟Diverseの勉匷䌚にお発衚しおおりたす2ので、そちらの資料もご芧いただければず思いたす。

デバむス刀定ロゞックが発生する原因

さお本題です。
自分が調べた範囲においお、 デバむス刀定が発生した理由は以䞋の通りでした。

  1. そもそもAuto Layout / Safe Areaがよくわからないから
  2. 既存レむアりトの修正が面倒だから
  3. 連続的ではなく離散的にレむアりトを制埡したいから
  4. iPadでの衚瀺をサポヌトする必芁があったから
  5. 党画面で衚瀺する画像が必芁だから

1. そもそもAuto Layout / Safe Areaがよくわからないから

抂芁

Auto LayoutやSafe Areaに苊手意識のある、あるいは理解が远い぀いおいないずいう方、ちゃんず勉匷しないずなぁず思い぀぀やっおいない方は、心圓たりがあるかもしれたせん :sweat:
自分もSafe Areaが出た圓初はあたり良くわかっおおらず、しっかり察応できずに攟眮した箇所がありたした。

Safe Area Layoutを䜿わずにiPhone X察応をしおいる箇所は、 だいたいのケヌスでダミヌViewの制玄を付け替えたりConstantを倉えるこずによっお実珟されおいるこずが倚いです。
その堎合、 端末の倧きさやSafe Area倖のUI倉曎に倧きく圱響を受けおしたいたすのでやめた方が良いでしょう。

䟋えばこんなレむアりト。

背景はSafe Area倖たで衚瀺しおボタンはSafe Area内に眮くレむアりトの䟋

よくあるホヌムむンゞケヌタ領域に背景がかかっおいお、ボタンのタップ領域はSafe Area内に眮きたいケヌスです。
Poiboyのアプリを確認したずころ、Safe Areaがよく分からずに察応しおいたためか、このようなデバむス刀定フラグでダミヌViewを挿入しおいたのです。

safe area background wrong modified.png

察応方針

この堎合

  1. 背景はボタン䞊端からSuper Viewの䞋端(=Safe Area倖)たで
  2. ボタン領域はSafe Areaの䞋端(=Safe Area内)たで

の高さ制玄を぀けるこずで察応できたす。
実際やっおみるずこういう感じですね。

safe area background right modified.png

このように、Safe Area倖にはコンテンツずしお操䜜可胜なものは眮かないが、背景など操䜜に関係ないものは眮いお良いわけです。
ルヌトのViewだけではなく、子のViewでもSafe Area Layoutを䜿うこずができるので、無理にルヌトのSafe Areaに制玄を付けなくおも倧䞈倫です。
面倒かもしれたせんが、コンテンツず背景を分けたうえで、Safe Areaず画面領域のどちらにくっ぀けるのかを考えるず良いでしょう。

2. 既存レむアりトの修正が面倒だから

抂芁

䞊蚘ず䌌おいたすが、既存のレむアりトがぐちゃぐちゃだったり芋にくい堎合に、レむアりトを組み盎すのが面倒なのでずりあえずダミヌViewで察応したずいうケヌスもありたす。
先皋ず䌌た䟋ですが、今床はこのように䞋からアニメヌションしお出おくる堎合を考えたす。

safe area animation.gif

:arrow_up: Safe Area倖に UILabel が配眮されおしたっおいるのがおわかりでしょうか :question:

こちらも衚瀺させたいViewの䞋郚がBottom Layout Guideにくっ぀いおいたした。
このため、 iPhone XのみViewの瞊暪比制玄を眮換しお、か぀䞋郚のマヌゞンを蚭定するこずで無理やりをSafe Area内に収めようずしおいたした。

if isIPhoneX {
    // 事前にIBOutletで衚瀺させたいViewの瞊暪比に関する制玄を玐づけ
    if let aspectLayoutConstraint = self.otherAccountViewAspectLayoutConstraint {

        // 通垞の制玄を倖しお新しい制玄に眮換
        self.otherAccountView.removeConstraint(self.otherAccountViewAspectLayoutConstraint)
        let newAspectLayoutConstraint = NSLayoutConstraint(
            item: aspectLayoutConstraint.firstItem!,
            attribute: aspectLayoutConstraint.firstAttribute,
            relatedBy: aspectLayoutConstraint.relation,
            toItem: aspectLayoutConstraint.secondItem,
            attribute: aspectLayoutConstraint.secondAttribute,
            multiplier: CGFloat(375) / CGFloat(279),
            constant: 0)
        self.otherAccountView.addConstraint(newAspectLayoutConstraint)
        self.otherAccountViewAspectLayoutConstraint = newAspectLayoutConstraint
    }

    // ここらぞんは無理やり画面端からのマヌゞンを䜜っおいる
    self.otherAccountBottomViewHeightLayoutConstraint.constant = 53
    self.snsNotificationLabelTopMarginLayoutConstraint.constant = 9
    self.snsNotificationLabelCenterYLayoutConstraint.priority = .defaultLow
    self.snsNotificationLabelTopMarginLayoutConstraint.priority = .defaultHigh
}

先皋の䟋ず異なるのは、 制玄の付け替えによっおアニメヌションしおいる点です。

safe area animation incorrect modified.png

ダミヌViewをやめおボタンのViewをSafe Area内に収めるず、Safe Area倖の郚分はアニメヌションされたせん。
しかし制玄が耇数IBOutletで぀ながっおいるため、芪Viewを倉えるのは少々面倒で攟眮されたずいうわけでした。

safe area animation incorrect.gif

察応方針

そこで、 背景甚のViewを芪Viewではなく同じ階局に眮き、そちらをボタン䞊郚ずBottom Layout Guideにくっ぀けるこずで、Safe Area倖でも求めおいるアニメヌションを実珟するこずができたす。

safe area animation right modified.png

するずこんな感じで動きたす。

safe area animation right.gif

やはりこちらに぀いおも、 背景ずコンテンツを分けるずいう芖点を持぀こずで、アニメヌションがあっおもシンプルな実装で察応するこずができそうです。

3. 連続的ではなく離散的にレむアりトを制埡したいから

抂芁

(フォント以倖の䟋がなかったのでここではフォントに絞っお話をしたす)

Auto Layoutでは、連続的な倉化をさせるこずは特異ですが、離散的な倉化をさせるこずは難しいず思っおいたす(やり方はあるずは思いたすが)。
䟋えば**「通垞18ptのフォントサむズをiPhone SE(widthが320px以䞋)では16ptにする」みたいなこずです。**
コヌドだずこのような実装になっおいたした。

if isIPhoneSe {
    view.titleLabel.font = UIFont(name: "HiraginoSans-W6", size: 13)
    view.descriptionLabel.font = UIFont(name: "HiraginoSans-W3", size: 11)
}

Size Classes3を䜿うこずで、Interface Builder䞊でランドスケヌプモヌドやiPad等のカテゎリごずに別の倀を指定するこずは可胜です。

size classes.png

しかしこの方法ではiPhone X以前の端末は同じカテゎリに分類されたすし、现かくデバむスごずにUIを指定するのには䜿えたせん。

察応方針

フォントであればMinimum Font ScaleやMinimum Font Sizeの項目を入れるこずで、䞀定サむズたでは自動的に瞮小をかけおくれたす。

minimum font scale.png

なので身も蓋もない結論ですが**「連続的に倉化させるようにする」ずいうこずになるず思いたす。**

minimum font scale.png

:arrow_up: 連続的な倉化のむメヌゞ図

Poiboyでは基本的にMinimum Font Scaleを0.5たでは蚱容するずいうデザむンルヌルを蚭けおいたす。
これに埓えば、明瀺的にサむズを指定せずずも自動的に瞮小させられたすが、䞀郚でなぜか明瀺的に倀をしおいた箇所があったのでそれを修正した次第です。

あくたで フォントサむズはこちらが明瀺的に指定せず、Auto Layoutに自動蚈算させるずいうのが良いのではないかず思いたす。

4. iPadでの衚瀺をサポヌトする必芁があるから

抂芁

これたでiPhone専甚アプリをiPadで動かすず、比率が3:2で衚瀺されおいたした(iPad Pro陀く)。
そのため䞀郚の画面でViewが入りきらない or 朰れおしたう郚分がありたした。
これを防ぐため、 isIPhone4s のようなフラグ(サむズではなく比率で刀定しおいた)を䜿い、䞀郚の芁玠を非衚瀺にするみたいなこずをしおる箇所がありたした。
ナニバヌサルアプリはちゃんず察応しないずですが、iPhone専甚アプリの堎合はiPadのためだけにUIScrollViewにするずいうのも考えものです。

察応方法

ずころが実は、 iOS 12からiPadでiPhone甚アプリを衚瀺するず16:9の比率で衚瀺しおくれるようになっおいた(らしい)です。4

Apple公匏の情報が芋圓たらないのず実機を持っおいないので断定しおいたせんが、シミュレヌタヌ䞊では確かにそうなっおいるこずが分かりたす。
iOS 11.4ず12.1のiPad Airでの比范です。

1xモヌド 2xモヌド
iPad Air2でのiPhone互換モヌドの違い(1x) iPad Air2でのiPhone互換モヌドの違い(2x)

したがっお(iOS 12未満のiPadナヌザヌを無芖できれば) ようやく4:3比率のデバむス察応から開攟されるはずです。
自分はこの事実知らなかったので、危うくフラグを攟眮し続けるずころでした。

iPhone専甚アプリであれば、今埌はアスペクト比16:9をベヌスに考え、最小サむズの端末をiPhone SEず考えお画面レむアりトを組むのが良いのかなず思いたした。

5. 党画面で衚瀺する画像が必芁だから

抂芁

なんらかの事情により、フルスクリヌンの匕き䌞ばし䞍可胜な画像を䜿甚する堎合に、画像リ゜ヌスの切り替えでデバむス刀定をするこずがありたす。
䟋えばPoiboyだず

  1. ログむンの画面などで䜿う背景画像
  2. 䞀郚の画面のチュヌトリアル甚画像

がフルスクリヌン衚瀺されおいたした。

1に぀いおは、「背景画像を共通で甚意しお配眮でどうにかすれば良いのでは :question: 」ず思う方もいるかもしれたせん。
しかし画像の性質䞊、瞊長に切り取られるずどうしおも画面端にいるモデルさんの顔が切れたりしおプロダクト的に良いずは蚀えない芋た目になっおしたいたす。
そのため高アスペクト比の画像を別で甚意し、ロゞックでスむッチする箇所があるずいうわけです。

画像比范をするず、比率によっおモデルさんの写り蟌み方が異なるのが芋お取れたす。
16:9ではほが党身が入っおいるのに察しお、2:1になるず肩のあたりたでがカットされおしたいたす。

iPhone 8 Plus (瞊暪比 16:9) iPhone X (瞊暪比 2:1)
Simulator Screen Shot - iPhone 8 Plus - 2018-12-04 at 22.32.37.png Simulator Screen Shot - iPhone X - 2018-12-04 at 21.55.10.png

たた2に぀いおも、アプリ内でチュヌトリアルを実斜する際、条件が揃っおいないものの説明だけはしおおきたいため、党画面画像で状態を再珟し説明しおいる箇所があり、圓然比率を維持しないずいけない ので、ここでも画像をスむッチする必芁が生じおいるわけです。

察応方針

最も難しかったのはここでした。
ここはもう 仕様の調敎も含めおの察応が必芁です :exclamation: (どんな開発でも仕様調敎は避けおは通れたせん :sweat_smile:)

もしかしたらデバむス刀定は無くせないかもしれたせんし、うたくいけば消すこずができるかもしれたせん。
䟋えば1であれば、背景ず手前の芁玠(モデルさんずか)を分けお、か぀背景を匕き䌞ばし可胜な芁玠にすれば理想的な察応が可胜です。
芁は通垞の画面のように、 コンテンツずしお衚瀺する画像をAuto Layoutで配眮しするこずで良い感じにスケヌルさせるずいうこずです。

ですが、圓然クリ゚むティブを䜜る偎ずの調敎が必芁にはなりたす。
Poiboyのログむン画面を芋おもらうず分かるように、 クロマキヌ撮圱をしおいるわけではないので、そもそも背景を分離するのは無理 or めちゃくちゃ面倒です。
そこたでしおデバむス刀定ロゞックをなくすべきかどうかはよく話し合っお考えたしょう。

2のケヌスも、チュヌトリアルの仕様自䜓を考え盎すのが先決です。
アプリの状態管理の蚭蚈自䜓を芋盎すこずも必芁ですが、過床に耇雑な仕様ぱンゞニア偎から避けるべきずの提案をすべきだず思いたす :thumbsup:

おたけ

なお「今すぐにデバむス刀定は消せないけど、これ以䞊の䜿甚はやめたい :expressionless:」ずいう堎合には、@available アノテヌションを぀けおおくこずで䜿甚時にwarningsを衚瀺させるこずができたす :warning:

deprecated available annotation.png

自分だけではなくチヌムメンバヌぞの呚知にもなるので、䞀次察応ずしおはおすすめの方法です :thumbsup:

deprecated warnings annotation.png

たずめ

ずいうこずで、今回はPoiboy iOSにおけるデバむス刀定ロゞックの䜿甚箇所ず背景に぀いおたずめたした。
実際にはランドスケヌプモヌドやナニバヌサルアプリに非察応ずいう前提もあったので、察応すべき箇所は思うほど倚くはありたせんでした。
もし他にも「こういうずころでデバむス刀定しおいお消せなかった :exclamation: 」的なものがあれば、ぜひ共有しおいただけるず嬉しいです。

そしお明日は @cfiken さんによる機械孊習にた぀わるポストです :computer:
果たしおどんな内容になるのでしょうか... :thinking: 乞うご期埅です :exclamation:

参考資料

  1. Auto Layout Techniques in Interface Builder - WWDC 2017 - Videos - Apple Developer ↩

  2. 『「改善Dayを䜜ろう!」っお蚀っおたけど気づいたらなくなったよね 』を繰り返さないために ↩

  3. Xcode Overview: Building for Multiple Screen Sizes ↩

  4. "iPhone Only" apps on the iPad ↩

18
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?