何がありますか?
UIは、データを表示し、イベントに応答し、同時に何らかの形で画面上に配置されるビューのセットとして定義できます。
画面に要素を配置する方法は?
- Qtは、特定の方法で内部に要素を配置できるコンテナを使用することを提案しています。 これらのコンテナを相互にネストすると、必要な配置を取得できます。
- WPF / XAMLは同様のコンテナーを提供します。
- Androidは同様のコンテナ+一定のシステムを提供します。
- iOSは自動レイアウトを提供します。 要素の配置を一貫して明確に記述する制約(方程式)のセットを記述する必要があります。 これらの制限を使用して連立方程式を解決すると、エンジンは要素の座標とサイズを受け取ります。
- Delphiにはアンカーがあります:コンテナにエッジを釘付けします。 iOSのマスクのサイズ変更に非常に似ています。
- 私が理解している限り、Webはネストコンテナを使用しており、その動作はスタイルによって記述されています。
これの問題は何ですか?
特別な場合にコードを使用する必要があります
記述されたツールは、典型的な場合に先鋭化されており、これらのツールを使用して要素の位置を記述できない場合があります(または、できませんが、これは非常に不便です)。 あなたはコードでそれをしなければなりません。 レイアウト記述のロジックは、いくつかの場所に広がっています。
より良い方法がなければなりません。
レイアウト-それは本当に何ですか?
レイアウトは機能です
レイアウトとは これは、要素の場所の説明です。 関数として表現できます。
入力では、関数はコンテナのサイズと要素の配列を受け取り、出力ではこれらの要素の座標を提供します。
理論的には、レイアウトは何でも構いません-それがデザイナーが描く方法です。 したがって、このような関数を記述するには、チューリング完全言語が必要です。 UIフレームワークは、チューリング完全言語以外の何かを提供してくれるため、問題があります。 プログラムの残りの部分が記述されている言語を使用するのは論理的です:iOSの場合-objc / swift、Androidの場合-java / kotlinなど
それはどういう意味ですか?
コードでレイアウトを簡単に記述することができます
コードでレイアウトを簡単に記述することができます! 1つの関数を記述するだけで十分です。 多くの場合、既存の要素に対して要素を配置します(右、下など)。 このような計算は、読みやすい名前の関数で非表示にできます。 iOSでは、これはライブラリFacade(objc) 、 Neon(swift)で行われます。 任意の言語で簡単に自分で書くことができます。
サンプルライブラリ
iOSでは、ビューのカスタムレイアウトを定義する場合は、 layoutSubviews()
(またはコントローラーのviewDidLayoutSubviews()
メソッドlayoutSubviews()
をオーバーライドし、そのフレームを子に設定する必要があります。 このメソッドは、ビューのサイズが変更されたときに呼び出されます。つまり、回転、ビューの分割などがこのメソッドの呼び出しを呼び出します。
公式のネオンページの例を次に示します。
let isLandscape : Bool = UIDevice.currentDevice().orientation.isLandscape.boolValue let bannerHeight : CGFloat = view.height() * 0.43 let avatarHeightMultipler : CGFloat = isLandscape ? 0.75 : 0.43 let avatarSize = bannerHeight * avatarHeightMultipler searchBar.fillSuperview() bannerImageView.anchorAndFillEdge(.Top, xPad: 0, yPad: 0, otherSize: bannerHeight) bannerMaskView.fillSuperview() avatarImageView.anchorInCorner(.BottomLeft, xPad: 15, yPad: 15, width: avatarSize, height: avatarSize) nameLabel.alignAndFillWidth(align: .ToTheRightCentered, relativeTo: avatarImageView, padding: 15, height: 120) cameraButton.anchorInCorner(.BottomRight, xPad: 10, yPad: 7, width: 28, height: 28) buttonContainerView.alignAndFillWidth(align: .UnderCentered, relativeTo: bannerImageView, padding: 0, height: 62) buttonContainerView.groupAndFill(group: .Horizontal, views: [postButton, updateInfoButton, activityLogButton, moreButton], padding: 10) buttonContainerView2.alignAndFillWidth(align: .UnderCentered, relativeTo: buttonContainerView, padding: 0, height: 128) buttonContainerView2.groupAndFill(group: .Horizontal, views: [aboutView, photosView, friendsView], padding: 10)
10行のコードでも悪くないでしょう?
長所
- フレームの計算は非常に高速です。 LayoutFrameworkBenchmarkによると、手動フレーム計算は自動レイアウトよりも10〜15倍高速です。
- レイアウトコードを1か所に-メンテナンスが簡単。
- 簡単なデバッグ。
- 完全な制御。任意のレイアウトを記述できます。
- コードでUIを記述すると、当然ビューの分解と再利用が行われます。
- コードでUIを記述すると、共有リソース(フォント、色など)の使用が簡単になります
短所
多くの場合、UIはマークアップ(xml、xaml、xib)の形式で宣言的に記述され、コード(Qt、Delphi、C#WinForms)に変換されるか、オブジェクトの既製のグラフが作成されます(xib、xaml)。 同時に、IDEにはプレビューツールがあり、非常に便利です。
コードでレイアウトを記述する場合、プレビューツールは使用しません。
通常、レイアウトは上から下に行きます。画面のサイズがあり、このサイズを知っているので、ビューの最初のレイヤーをレイアウトし、サイズを受け取ってから、さらに深くなります。 場合によっては、他の方法を使用する必要があります。内容に合わせてコンテナを引き伸ばします。 これを記述することは必ずしも便利ではありません。
RTL、Split View、iPhone Xはどうですか?
- RTL-手動で処理できます。 既製の開発もあります。Neonの場合、 PRは、Autolayoutのように先頭と末尾を使用するためにハングアップします。
- ビューの分割-特性コレクションの変更をキャッチし、サイズクラスごとに異なるレイアウト関数を呼び出すことができます。
- iPhone X-safeAreaGuideはビュー内で利用でき、対応するインデントを考慮することができます。
おわりに
私の意見では、すでにコードでUIを作成している場合、これは良いアプローチです。 この場合のコードは、Autolayoutを使用した場合とほぼ同じですが、より高速で予測どおりに動作します。
主なマイナス-プレビューツールの形式での可視性は失われます。