
今日は、ストーリーボードやNIBを使用せずに、コードを使用してシンプルなモバイルアプリケーションユーザーインターフェイスを作成する方法を説明します。 すべてが長所と短所を持っているので、どちらが良いかについては議論しません。したがって、 この問題に関連するリンクを残します。
このガイドの第2部では、ナビゲーションバー、テーブルビュー、動的サイズのセルなど、最も一般的に使用されるモバイルアプリケーションのユーザーインターフェイス要素をコードで作成します。
復習
このチュートリアルは、Xcode 9とSwift 4を使用して作成されました。Xcode、Swift、およびCocoaPodsに精通していることも前提としています。
さらに遅延することなく、単純な連絡先カードアプリケーションというプロジェクトの作成を始めましょう。 この記事の目的は、コードでアプリケーションのユーザーインターフェイスを作成する方法を説明することです。したがって、このガイドの目的で必要でない限り、アプリケーションの機能に関するロジックは含まれません。
PureLayoutを使用してプログラムで制約を作成する
プロジェクトのセットアップ
Xcodeを起動して開始します-> "新しいXcodeプロジェクトを作成します"。 「シングルビューアプリ」を選択し、「次へ」をクリックします。

プロジェクトに好きな名前を付けて、ContactCardと呼ぶことにしました。 以下の3つのオプションをすべてクリアし、プログラミング言語としてSwiftを選択して、[次へ]をクリックします。

プロジェクトを保存するコンピューター上の場所を選択します。 「私のMacでGitリポジトリを作成する」のチェックを外します。
このプロジェクトではストーリーボードまたはNIBを使用しないため、Project Navigatorにある「Main.storyboard」を削除します。

その後、プロジェクトナビゲータでプロジェクトをクリックし、[全般]タブで、展開に関する情報があるセクションを見つけ、[メインインターフェイス]に記述されているすべてを削除します。 これは、アプリケーションの起動時にロードするStoryboardファイルをXcodeに伝えるものですが、「Main.storyboard」を削除したばかりなので、Xcodeはこのファイルを見つけられず、アプリケーションがクラッシュします。

ViewControllerの作成
ここでアプリケーションを実行すると、黒い画面が表示されます。これは、アプリケーションにユーザーインターフェイスのソースがないため、次のパートで作成するためです。 「AppDelegate.swift」を開き、
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)
内に
application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)
、このコードの一部を貼り付けます:
self.window = UIWindow(frame: UIScreen.main.bounds) let viewController = ViewController() self.window?.rootViewController = viewController self.window?.makeKeyAndVisible()
このコードは、ユーザーがアプリケーションと対話するためのウィンドウを提供します。これは通常、「ViewController.swift」にあります。 すべてが機能することをすばやく確認するには、「ViewController.swift」に移動し、
viewDidLoad()
メソッドに次の行を挿入します。
self.view.backgroundColor = .blue
次に、アプリケーションを実行します。
Xcodeでファイル間を移動するには、「⇧⌘O」ホットキーを使用して、ファイル名または探しているコードスニペットを入力すると、選択可能なファイルのリストが画面に表示されます。
アプリケーションを起動すると、これがシミュレータの画面に表示されるはずです。

もちろん、このうんざりするような青は使用しないので、
viewDidLoad ()
内で
.blue
を
.white
置き換えて背景を白に変更するだけです。
UI開発
ユーザーインターフェイスを作成するには、私たちの生活をもっと楽にするライブラリを使用します 。 PureLayoutをインストールするには、まずターミナルを開いてcd、次にスペースを入力し、プロジェクトフォルダーをターミナルにドラッグして、「Enter」を押す必要があります。 ターミナル内で次のコマンドを実行します。
- ポッド初期化
- ポッドインストール
これは、2番目のコマンドの後のターミナルの出力です。

その後、Xcodeを閉じ、Finderでフォルダーを開くと、「<your project name> .xcworkspace」が見つかるはずです。 これは、CocoaPodsを使用する必要がある場合にアプリケーションにアクセスするために開くものです。 「PodFile」という名前のファイルを見つけて、
use_frameworks!
というフレーズの下に次の行を記述します
use_frameworks!
pod “PureLayout”
ターミナルで
pod install
再度実行し、「Command + B」を押してプロジェクトをビルドします。
コーヒーブレイク
すべてが設定されたので、実際の作業から始めましょう。 「ViewController.swift」に移動して、コーヒーを飲みます。これは、最終結果が次のようになるためです。

ImageViewを作成する
このファイルでライブラリを使用できるように、
import UIKit
下に
import PureLayout
行を挿入します。 次に、クラス宣言の下で、関数の外側で、次のようにレイジー(レイジー)
Avatar ImageView
変数を作成することから始めます。
lazy var avatar: UIImageView = { let imageView = UIImageView(image: UIImage(named: "avatar.jpg")) imageView.autoSetDimensions(to: CGSize(width: 128.0, height: 128.0)) imageView.layer.borderWidth = 3.0 imageView.layer.borderColor = UIColor.lightGray.cgColor imageView.layer.cornerRadius = 64.0 imageView.clipsToBounds = true return imageView }()
画像については、アバターとして使用するデスクトップ上の画像を保存し、それを<Your Project Name>フォルダー(私の場合は「ContactCard」と呼ばれる)フォルダーのXcodeにドラッグし、「必要に応じてアイテムをコピー」ボックスをチェックします。

その後、「avatar.jpg」の代わりに、UIImage宣言に拡張子とともにこのファイルの名前を記述します。
知らない人にとって、レイジー変数は通常の変数に似ていますが、必要になるか、初めて呼び出されるまで初期化されない(またはメモリ領域が割り当てられる)ことを除いて。 これは、Lazy変数はView Controllerの初期化時に初期化されず、実際に必要になったときに後のポイントを期待することを意味し、他のプロセスの処理能力とメモリスペースを節約します。 これは、ユーザーインターフェイスコンポーネントを初期化するときに特に役立ちます。
動作中のPureLayout
初期化の内部を見るとわかるように、
imageView.autoSetDimensions (to: CGSize (width: 128.0, height: 128.0))
は実際のPureLayoutです。 1行で、UIImageViewの高さと幅の両方に制限を設定し、必要なすべてのNSLayoutConstraintsは、巨大な関数呼び出しを必要とせずに作成されます。 プログラムで制限を作成する場合は、おそらくこの素晴らしいライブラリにすでに夢中になっているでしょう。
この画像を丸くするために、角度半径を幅または高さの半分(64.0ポイント)に設定します。 さらに、
clipsToBounds
プロパティを
true
に設定し
true
。これは、設定した半径の外側にあるすべてのものをクリップする必要があることを画像に伝えます。
次に、灰色のペイントされたアバターの背後にあるビューの上部として機能するUIViewの作成に進みます。 このビューに対して次の遅延変数を宣言します。
lazy var upperView: UIView = { let view = UIView() view.autoSetDimension(.height, toSize: 128) view.backgroundColor = .gray return view }()
サブビューを追加する
先に
func addSubviews ()
前に、作成したばかりのビュー(および作成する他のすべてのビュー)をサブビューとしてView Controllerに追加する
func addSubviews ()
関数を作成しましょう。
func addSubviews() { self.view.addSubview(avatar) self.view.addSubview(upperView) }
次に、
viewDidLoad (): self.addSubviews ()
次の行を追加します
viewDidLoad (): self.addSubviews ()
設定制限
私たちがどこまで来たかを知るために、これらの2種類に制限を設定しましょう。
func setupConstraints()
という別の関数を作成し、次の制約を挿入します。
func setupConstraints() { avatar.autoAlignAxis(toSuperviewAxis: .vertical) avatar.autoPinEdge(toSuperviewEdge: .top, withInset: 64.0) upperView.autoPinEdge(toSuperviewEdge: .left) upperView.autoPinEdge(toSuperviewEdge: .right) upperView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .bottom) }
今度は
viewDidLoad()
内で、次のように
setupConstraints()
viewDidLoad()
呼び出します:
self.setupConstraints()
。
addSubviews()
呼び出してからこの後追加します。 これが最終的な結論になります。

アバターを最前線に
残念ながら、これは私が受け取りたいものではありません。 ご覧のとおり、
upperView
はアバターの上にあります。 これは、
subviews
前に
upperView
としてアバターを追加したという事実に
upperView
であり、これらのサブビューはスタック上の何らかの形で配置されているため、この結果が得られます。 これを修正するために、これら2行を単純に置き換えることができますが、別のトリック、
self.view.bringSubview (toFront: avatar)
を紹介します。
この方法では、スタックの一番下から一番上にアバターが転送されるため、最適な方法を選択してください。 もちろん、読みやすくするために、最初に追加されたサブビューがスタックの一番下にあるため、交差する場合に表示される順序でサブビューを追加することをお勧めします。したがって、他の交差するビューはその上に表示されます。
そして、これは実際にどのように見えるかです:

セグメント化されたコントロールを作成する
次に、3つのセクションを含む灰色のバーであるセグメント化されたコントロールを作成します。 実際、セグメント化されたコントロールは簡単に作成できます。 以下を実行します。
lazy var segmentedControl: UISegmentedControl = { let control = UISegmentedControl(items: ["Personal", "Social", "Resumè"]) control.autoSetDimension(.height, toSize: 32.0) control.selectedSegmentIndex = 0 control.layer.borderColor = UIColor.gray.cgColor control.tintColor = .gray return control }()
すべてが明確であると信じていますが、唯一の違いは、初期化後に文字列の配列を提供し、各行が目的のセクションの見出しを表すことです。 また、
selectedSegmentIndex
を0に設定します。これは、セグメント化されたコントロールに、初期化中に最初のセグメントを選択/選択するよう指示します。 残りは、ただ遊ぶスタイルです。
では、
addCubviews(): self.view.addSubview(segmentedControl)
関数の最後に次の行を挿入して、サブビューとして追加してみましょう
addCubviews(): self.view.addSubview(segmentedControl)
その制限は次のようになります。
segmentedControl.autoPinEdge(toSuperviewEdge: .left, withInset: 8.0) segmentedControl.autoPinEdge(toSuperviewEdge: .right, withInset: 8.0) segmentedControl.autoPinEdge(.top, to: .bottom, of: avatar, withOffset: 16.0)
セグメント化されたコントロールに、スーパービューの左側にアタッチするように指示しますが、画面の端に直接アタッチせずに、間隔をわずかに増やしたいです。 気づいたら、私はすべての距離とサイズが8の倍数である、いわゆる8ポイントグリッドを使用します。 セグメント化されたコントロールの右側で同じことを行います。 最後の制限については、彼は、頂点を16ポイントの間隔でアバターのベースに取り付けると言います。
上記の制限を
func setupConstraints()
追加した後、コードを実行し、次のようになっていることを確認します。

ボタンを追加する
次に、教科書のユーザーインターフェイスの最後の部分、つまり「編集」ボタンに進みます。 次の遅延変数を追加します。
lazy var editButton: UIButton = { let button = UIButton() button.setTitle("Edit", for: .normal) button.setTitleColor(.gray, for: .normal) button.layer.cornerRadius = 4.0 button.layer.borderColor = UIColor.gray.cgColor button.layer.borderWidth = 1.0 button.tintColor = .gray button.backgroundColor = .clear button.autoSetDimension(.width, toSize: 96.0) button.autoSetDimension(.height, toSize: 32.0) return button }()
初期化の大きさについて心配する必要はありませんが、
button.setTitle
および
button.setTitleColor
呼び出してタイトルとその色を設定する方法に注意して
button.setTitle
。 特定の理由により、
titleLabel
に直接アクセスしてボタンのタイトルを設定することはできません。これは、ボタンの状態が異なるためです。多くの場合、状態ごとにヘッダー/色が異なると便利です。
次に、ボタンを他のコンポーネントと同様にサブビューとして追加し、次の制限を追加して、本来あるべき場所に表示されるようにします。
editButton.autoPinEdge(.top, to: .bottom, of: upperView, withOffset: 16.0) editButton.autoPinEdge(toSuperviewEdge: .right, withInset: 8.0)
ここでは、ボタンに適切な上限と上限のみを設定しました。これは、ボタンにサイズを与えたため、ボタンは拡大せず、他には何も必要ないためです。 プロジェクトを実行して、最終結果を確認します。

最近の注意事項
必要な数のインターフェース要素を追加する練習をします。 難しいと思うアプリケーションのビューを作成します。 シンプルに始めて、徐々に難易度を上げてください。 ユーザーインターフェイスコンポーネントを紙に描いて、どのように組み合わされるかを想像してみてください。
第2部では、このガイドを拡張して、ナビゲーションバー、テーブルビュー、および動的サイズのセルをコードで作成します。