UIKitは、iOSおよびmacOSアプリケーションでグラフィカルインターフェースを構築するためのフレームワークです。このセットにはUIView、UIViewController、制御要素、Auto Layoutシステムが含まれており、アダプティブでインタラクティブな画面を作成できます。Apple Developer Documentation(2025)によると、UIKitはウィンドウ、ビュー、アニメーション、ジェスチャー、テキストを扱う200以上のクラスを含み、すべてのiPhoneおよびiPadアプリケーションの基盤となっています。
重要なポイント
UIKitは、iOS、iPadOS、macOS(Mac Catalyst経由)でユーザーインターフェースを作成および管理するためのクラスを提供するAppleのフレームワークです。Core Animation、Core Graphics、Quartz Coreの上で動作し、低レベルのレンダリングをボタン、ラベル、画像、コンテナといった高レベルのオブジェクトに抽象化します。UIKitは2007年にiPhone OS 1とともに登場し、SwiftUIと並んでiOS開発の主要フレームワークであり続けています。
このフレームワークは命令型アプローチに従います。開発者はUIButton、UILabel、UIImageViewクラスのインスタンスを作成し、そのプロパティ(色、フォント、位置)を設定し、addSubviewを介してビュー階層に追加します。インターフェースの変更はすべて明示的に行われます。舞台裏での魔法のような更新はありません。これにより、UIKitは状態の記述が自動的にインターフェースを再描画するSwiftUIのような宣言型フレームワークと区別されます。
フレームワークにはいくつかのカテゴリのクラスが含まれています。UIViewは、すべての視覚コンポーネントが継承する基本要素です。UIWindowは、ビューが画面に表示される最上位のコンテナです。UIViewControllerは一連のビューを管理し、画面の回転、キーボードの表示、システム通知に応答します。UIApplicationは、タッチイベントとボタン押下を処理するエントリポイントです。
テキストには、UILabel(静的テキスト)、UITextField(単一行入力)、UITextView(複数行入力)が使用されます。ボタンにはUIButton(システム、カスタム、SF Symbolsアイコンを含む)が使用されます。ナビゲーションにはUINavigationController、UITabBarController、UISplitViewControllerが使用されます。UIKitには合計200以上の公開クラスがあります。
UIKitのアーキテクチャはレイヤー上に構築されています。各レイヤーは表示の特定の側面を担当します。最下層にはCore Graphicsがあり、パス、テキスト、画像のレンダリングエンジンです。その上にCore Animationがあり、レイヤー構成(CALayer)と状態間のアニメーションを管理します。UIKitはその上にオブジェクト指向API(UIView、UIViewController、UIResponder)を構築します。
すべてのアプリケーションにはビュー階層があります。ルートがUIWindowであるツリーです。その下にルートUIViewController、そのビュー、そして内部にネストされたサブビューがあります。タッチイベントはレスポンダーチェーンに沿って伝播します。最も深くネストされたビューからその親へ、そしてUIApplicationまで上がります。どのオブジェクトもタッチを処理しない場合、それは無視されます。
各UIViewには、画面上のピクセルレンダリングを処理するCALayerが含まれています。ビューはタッチとアクセシビリティを管理し、レイヤーはグラフィックス(シャドウ、cornerRadius、ボーダー、トランスフォーム)を処理します。この分離により、メインスレッドをブロックせずに、重いグラフィックスを別のスレッド(レンダーサーバー)にオフロードできます。Appleは、画面上に200を超えるビューがある場合、CALayerを直接操作することを推奨しています。これによりCPU負荷が軽減されます。
レスポンダーチェーンは、最初にタッチイベントを受け取るオブジェクトから始まります。そのオブジェクトがイベントを処理しない場合(touchesBeganメソッドがオーバーライドされていない場合)、イベントはチェーン内の次のレスポンダー(next、superview、next responder、UIViewController、UIWindow、UIApplication、App Delegate)に渡されます。これにより、すべてのビューにハンドラを追加することなく、シーンレベルでグローバルなジェスチャーやキーボードイベントをインターセプトできます。
各UIViewControllerは、厳密に定義された一連のイベントを通過します。ライフサイクルには、初期化、ビューのロード、画面への表示、回転時のレイアウト更新、非表示、画面からの退出、メモリ解放のフェーズが含まれます。開発者は各段階でカスタムコードを実行するために、対応するメソッドをオーバーライドします。
class ProfileViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
loadUserProfile()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
clearCache()
}
}
viewDidLoadでは、インターフェースが設定されます。サブビューが作成され、制約が設定され、デリゲートがサブスクライブされます。viewWillAppearでは、表示前の操作(ネットワークからの最新データの読み込み、値の更新)が実行されます。viewDidDisappearは、通知のサブスクライブ解除と一時データのクリーンアップを行う場所です。すべてのオーバーライドでsuperの呼び出しは必須です。そうしないと、イベントチェーンが壊れます。
古いバージョンのiOSには、メモリが不足したときに呼び出されるviewDidUnloadメソッドが存在しました。iOS 6以降、このメソッドは削除されました。現在はUIKitが非表示のコントローラーのビューを自動的にアンロードします。開発者は、システムから警告を受け取ったときにARCがメモリを適切に解放できるよう、ビューへの参照をすべてweakとして宣言するだけで済みます。
UIKitは2種類の遷移をサポートしています。segue(Storyboard経由)と、UINavigationControllerを介したプログラムによるナビゲーションです。プログラムによる遷移は次のようになります。navigationController?.pushViewController(detailVC, animated: true)。この場合、detailVCのライフサイクルは通常どおり進行します。viewDidLoadは1回呼び出され、viewWillAppearは表示されるたびに呼び出されます。
Auto Layoutは、数学的な関係(制約)に基づく位置決めシステムです。ハードコードされたX座標とY座標の代わりに、開発者はルールを記述します。「ボタンはラベルの右側に16ptの間隔で配置する」や「ビューは左右に20ptのマージンで画面幅いっぱいに広がる」などです。システムは実行時に結果の連立方程式を解き、任意の画面サイズにインターフェースを適応させます。
制約はInterface Builder(ドラッグアンドドロップ経由)またはプログラムでSwiftに設定できます。各制約は、firstItem、firstAttribute、relation、secondItem、secondAttribute、multiplier、constantのパラメーターを持つNSLayoutConstraintクラスのインスタンスです。制約はisActive = trueで、または一括でNSLayoutConstraint.activate()でアクティブ化されます。
iPhone X(2017)の導入に伴い、AppleはSafe Areaを導入しました。ノッチ、丸みを帯びたコーナー、ホームバーインジケーターのない画面領域です。制約はviewではなくview.safeAreaLayoutGuideにアタッチする必要があります。Layout Marginsはビューに内部パディングを追加し、デフォルトではコンテキストに応じて8ptまたは16ptです。safeAreaLayoutGuideを使用すると、すべての世代のiPhoneとiPadで正しく表示されます。
Auto Layoutは、制約の定数を変更することでアニメーションをサポートします。制約のconstantを更新し、アニメーションブロック内でlayoutIfNeededとともにUIView.animateを呼び出すだけです。システムは階層内のすべてのビューの位置をスムーズに再計算します。この手法は、展開可能なブロック、アダプティブキーボードパネル、画面の向きの変更に使用されます。
UITableViewとUICollectionViewは、リストとグリッドを表示するための2つの強力なUIKitツールです。UITableViewは、単一列の垂直リスト(チャット、設定、ニュースフィード)に適しています。UICollectionViewは、グリッド、水平リスト、カルーセル、カスタムレイアウト(ギャラリー、商品、カレンダー)に適しています。どちらのクラスも、委譲パターンを使用してデータと外観を分離します。
データソースはUITableViewDataSourceプロトコルで、必須メソッドはnumberOfRowsInSectionとcellForRowAtです。UITableViewDelegateは、セルのタップ、行の高さ、スクロールイベントを処理します。再利用識別子メカニズムは、画面外にスクロールしたセルを再利用します。これは大きなリストのパフォーマンスにとって重要です。
class ContactsViewController: UITableViewController {
private let contacts = ["アンナ", "ボリス", "ビクター"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,
forCellReuseIdentifier: "cell")
}
override func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return contacts.count
}
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",
for: indexPath)
var content = cell.defaultContentConfiguration()
content.text = contacts[indexPath.row]
cell.contentConfiguration = content
return cell
}
}
この例は、文字列の配列を表示するための最小限のコントローラーを示しています。セルはUIListContentConfiguration(iOS 14+のモダンAPIで、非推奨のtextLabelとdetailTextLabelを置き換え)を介して設定されます。viewDidLoadでのセルクラスの登録は必須です。そうしないと、アプリケーションは実行時例外でクラッシュします。
iOS 13以降、Appleは複雑なレイアウトを構築するためにUICollectionViewCompositionalLayoutを推奨しています。開発者はセクション、グループ、アイテム、およびそのサイズを宣言的に記述します。結果として、ストリップ、2x2グリッド、カルーセル、装飾など、任意のジオメトリのグリッドが得られます。Compositional Layoutは、すべての新しいプロジェクトで古いUICollectionViewFlowLayoutに取って代わりました。DiffableDataSourceと組み合わせると、コレクションの更新は1回のapply(snapshot)呼び出しに簡素化され、変更アニメーションは自動的に実行されます。
以下は、実際のタスクでUIKitを使用する2つの実践的な例です。シャドウと角丸を持つカスタムビューの作成、およびリストからアイテムを削除するためのスワイプジェスチャーの処理です。
extension UIView {
func applyCardStyle() {
layer.cornerRadius = 12
layer.shadowOpacity = 0.15
layer.shadowRadius = 8
layer.shadowOffset = CGSize(width: 0, height: 2)
layer.masksToBounds = false
}
}
@objc private func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
guard let swipedView = gesture.view else { return }
UIView.animate(withDuration: 0.3) {
swipedView.alpha = 0
swipedView.transform = CGAffineTransform(translationX: 300, y: 0)
} completion: { _ in
swipedView.removeFromSuperview()
}
}
applyCardStyle拡張は、任意のビューにシャドウと角丸を追加します。プロダクトカード、プロフィール、通知に便利です。アニメーション付きのhandleSwipeメソッドは、ユーザーがアイテム上で右にスワイプすると、そのアイテムを削除します。ハンドラはUISwipeGestureRecognizer(direction: .right)の設定でaddGestureRecognizerを介してビューに追加されます。masksToBounds = falseの設定は、シャドウがビューの境界でクリップされないようにするために重要です。
より複雑なインターフェースにはUIStackViewを使用します。これは、ネストされたビューを自動的に水平または垂直に配置するコンテナです。Stack Viewはレイアウトを簡素化します。各要素に制約を設定する必要はなく、スタック自体に1つの制約を設定するだけです。
よくある質問
Frameはsuperviewの座標系における矩形(位置+サイズ)です。Boundsはビュー自身の座標系における矩形(常に0,0から始まります)。Frameは回転や拡大縮小で変化しますが、boundsは変化しません。
UIKitは非表示のコントローラーのビューを自動的にアンロードします。開発者はビューのプロパティをweak varとして宣言するだけで、システムの警告時にARCがメモリを解放できます。
新しいプロジェクトでは、AppleはSwiftUIを推奨しています。プロジェクトがUIKitを使用している場合は、個別の画面にはXIBを使用するか、SnapKitを介したプログラムによるレイアウトを使用してください。Storyboardはマージ競合を引き起こし、ビルドを遅くします。
traitCollectionをサポートするUIColorを使用します。UIColor { $0.userInterfaceStyle == .dark ? ... : ... }。Info.plistでUIUserInterfaceStyleキーを使用してダークモードを有効にします。
UIStackViewは、alignment、distribution、spacingに基づいてネストされたビューの位置とサイズを自動的に計算します。制約コードを60–80%削減し、異なる画面への適応を簡素化します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。