Dynamic Island は、iPhone 14 ProおよびすべてのiPhone 15/16の上部にあるインタラクティブエリアで、通知、バックグラウンドアクティビティ、システムインジケーターを1つの動的ゾーンに統合します。従来のノッチとは異なり、Dynamic Islandは現在のコンテキストに応じて形状とサイズを変更します。Apple(WWDC 2024)によると、ユーザーはDynamic Islandと平均して1日12回インタラクションしています — タップ、長押し、ActivityKitを使用したLive Activitiesを通じて。iOSのアニメーションについて詳しくは、Corner Radiusの記事をご覧ください。
重要なポイント
Dynamic Island は、Appleのソフトウェア・ハードウェアソリューションに基づくインタラクティブエリアで、2022年9月にiPhone 14 Proとともに発表されました。物理的には、OLEDピクセルに囲まれたピル型のカットアウトで、動的に色と形状が変化します。Appleは、カメラとFace ID用のハードウェアカットアウトと、その周囲の黒い領域のソフトウェアレンダリングを組み合わせて使用し、「生きている」島のような錯覚を生み出します。
Dynamic Islandの主な目的は、システム通知とアクティブコンテンツの間のギャップを埋めることです。通知が画面の中央(Androidのように)や上部のバナー(古いiOSのように)に表示される代わりに、Dynamic Island はそれらをハードウェアゾーンに直接統合します。これにより気が散ることが減り、統一されたスペースの感覚が生まれます。
Appleのデータ(iOS 17採用統計、2024年)によると、Dynamic IslandはアクティブなiPhoneの38%で利用可能です。iPhone 15(2023年)以降、ベースモデルを含むラインアップの全モデルにDynamic Islandが搭載されました。iOS 18では、AppleはLive Activities APIを拡張し、Dynamic Island上で直接カウントダウンタイマーとスポーツスコアのサポートを追加しました。
Dynamic Island は、iPhone 14 Pro、iPhone 14 Pro Max、iPhone 15、iPhone 15 Plus、iPhone 15 Pro、iPhone 15 Pro Max、iPhone 16、iPhone 16 Plus、iPhone 16 Pro、iPhone 16 Pro Maxで利用可能です。iPadではDynamic Islandは利用できません。Dynamic Island向けの開発にはXcode 14.1+とiOS 16.1+が必要です。
Dynamic Island は、コンパクト、ミニマル、拡張の3つの表示状態をサポートしています。状態間の遷移はUIKitアニメーションとCore Animationを使用してアニメーション化されます。システム自体がアクティビティの優先順位を管理します。複数のアプリが同時にコンテンツを表示しようとすると、iOSは最後のアクティビティの開始時間に基づいてキューを使用します。
| 状態 | サイズ | コンテンツ | 例 |
|---|---|---|---|
| コンパクト | 49×18 pt | アプリアイコン+システムアイコン | タイマー、音楽、通話 |
| ミニマル | 最大66×18 pt | アイコン+短いテキスト | ナビゲーションの道順、歩数 |
| 拡張 | 最大364×160 pt | コンテンツ付きフルウィジェット | スポーツスコア、タクシーの状況 |
コンパクト状態 は、1つのバックグラウンドタスクがアクティブな場合のDynamic Islandの標準ビューです。左側にアプリアイコン、右側にシステムアイコンが表示された丸みを帯びたピルとして表示されます。デフォルトでは、すべてのLive Activitiesはコンパクト状態で開始されます。
ミニマル状態 は、2つ以上のタスクが同時にアクティブな場合に発生します。Dynamic Islandはカメラの左右に2つの別々の要素に「分割」されます。ミニマル状態 では、タクシーの到着時刻や現在のトラックなど、2つの独立した情報源を表示できます。
拡張状態 は、Dynamic Islandを長押しすることでアクティブになります。このモードでは、カスタマイズ可能なコンテンツ(タイトル、説明、プログレスバー、ボタン)を備えたフルウィジェットが表示されます。拡張状態はスクロールとインタラクティブ要素をサポートしています。
ActivityKit はiOS 16.1で導入されたSwiftフレームワークで、アプリがDynamic Islandとロック画面にLive Activitiesを公開できるようにします。ActivityKitはActivityViewとActivityAttributesに基づくアーキテクチャを使用します。前者はコンテンツタイプを定義し、後者は可変データを定義します。このフレームワークはWidgetKitと連携して動作しますが、ウィジェットとは異なり、Live Activitiesはアプリを開かなくてもリアルタイムで更新できます。
import ActivityKit
import SwiftUI
// アクティビティ属性を定義
struct DeliveryAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
var driverName: String
var distanceToArrival: Double
var estimatedMinutes: Int
}
var orderNumber: String
}
// Live Activityを開始
func startDeliveryActivity() {
let initialState = DeliveryAttributes.ContentState(
driverName: "アレクセイ",
distanceToArrival: 3.5,
estimatedMinutes: 12
)
let attributes = DeliveryAttributes(orderNumber: "ORD-2024-8912")
let activity = try? Activity.request(
attributes: attributes,
contentState: initialState,
pushType: .token
)
}
Live Activities はActivityViewを介して更新され、Dynamic Island用のSwiftUIコンテンツをレンダリングします。システム自体が、Dynamic Islandのサイズとアクティビティの数に応じて、使用するテンプレート(コンパクト、ミニマル、拡張)を決定します。コンテンツを更新するには、activity.update(using: contentState) を呼び出します。終了するには — activity.end(dismissalPolicy: .immediate) を呼び出します。
ActivityKitはAPNs(Apple Push Notification Service)を介したプッシュ更新をサポートしています。Live Activityを開始するときに、pushTokenを要求し、デバイスでアプリを起動せずにサーバーから更新を送信できます。プッシュ更新は、activity.pushTokenとリモートLive Activity開始用のActivity.pushToStartTokenを介して機能します。
// プッシュでLive Activityを更新
func updateActivity(activity: Activity<DeliveryAttributes>) {
let updatedState = DeliveryAttributes.ContentState(
driverName: "アレクセイ",
distanceToArrival: 1.2,
estimatedMinutes: 4
)
let alertConfiguration = AlertConfiguration(
title: "配達員が近くにいます",
body: "アレクセイは4分後に到着します",
sound: .default
)
await activity.update(
using: updatedState,
alertConfiguration: alertConfiguration
)
}
AlertConfiguration はオプションのパラメーターで、重要な更新(例:「配達員が到着しました」)の際にDynamic Islandの上に通知を表示します。AlertConfigurationがない場合、コンテンツは静かに更新され、プログレスバーやタイマーに適しています。
ノッチ は、iPhone X~13のハードウェアカットアウトで、フロントカメラ、Face IDセンサー、スピーカーを含んでいます。ノッチは静的で、サイズと形状は変化せず、通知はその下に標準バナーとして表示されます。一方、Dynamic Islandはカットアウト周辺のピクセルを使用してコンテンツを表示し、ハードウェア要素をインターフェースの一部にします。
| 基準 | Dynamic Island | ノッチ |
|---|---|---|
| インタラクティブ性 | タップ、長押し、スワイプをサポート | インタラクティブではない |
| コンテンツ適応 | コンテキストに応じて形状変更 | 静的、コンテンツはノッチの下 |
| Live Activities | ActivityKitによる組み込みサポート | なし — 標準通知のみ |
| マルチタスク | 2つの同時アクティビティ(左右) | 1つのアクティビティのみ |
| 利用可能性 | iOS 16.1+、iPhone 14 Pro以降 | iOS 11+、iPhone X~13 |
Apple Human Interface Guidelines(2025年)によると、Dynamic Islandは広告や静的コンテンツの永続的な表示に使用すべきではありません。Live Activitiesは、タイマー、配達、スポーツ、音楽、ナビゲーションといった明確なライフサイクルを持つバックグラウンドタスクのみを対象としています。これらのルールに違反すると、App Storeレビューでアプリが拒否されます。
Dynamic Island には厳格なライフサイクルがあります。アクティビティはActivity.request()を介したリクエストで開始され、アクティブ/一時停止/更新済みの状態を経て、activity.end()の呼び出しで終了します。システムはメモリが少ない場合(カメラ起動時など)、アクティビティを強制終了することがあります。この場合、アプリはActivityActivityState.finishedを介して通知を受け取ります。
ジェスチャー は、ActivityView内のSwiftUIコンテンツによって処理されます。標準ジェスチャー:コンパクト状態をタップするとアプリが開き、長押しで拡張状態が開き、下にスワイプで拡張状態が閉じます。カスタムジェスチャーは、アクティビティビュー内でSwiftUI修飾子(onTapGesture、onLongPressGesture)を介して追加されます。
システムがLive Activityを終了するか(ユーザーがスワイプで削除した場合)、アプリはリソースを解放するためにfinished状態を処理する必要があります。Activity.activityStateUpdates を購読し、完了後にアクティビティへのローカル参照を削除することをお勧めします。
import ActivityKit
func observeActivityState(activity: Activity<DeliveryAttributes>) {
Task {
for await state in activity.activityStateUpdates {
switch state {
case .active:
print("アクティビティはDynamic Islandでアクティブ")
case .dismissed:
print("アクティビティはユーザーにより非表示")
await activity.end(dismissalPolicy: .immediate)
case .finished:
print("アクティビティはシステムにより終了")
cleanupResources()
@unknown default:
break
}
}
}
}
Appleの推奨(WWDC 2024、セッション10146):ユーザーの注意を必要としないステータスの表示にDynamic Islandを使用しないでください。各Live Activityには明確な開始と終了のトリガーが必要です。UIのないバックグラウンド更新には、Live Activitiesの代わりにBackground Tasksを使用してください。
よくある質問
Dynamic Island は、iPhone 14 Pro、14 Pro Max、およびすべてのiPhone 15とiPhone 16モデル(ベースバージョンを含む)で利用可能です。開発にはiOS 16.1+とXcode 14.1が必要です。古いモデル(iPhone X~13)では、Live Activitiesをサポートしない静的ノッチが使用されています。
Dynamic Island は通知を画面のハードウェアゾーンに統合し、コンテンツを隠しません。通常の通知は上部にバナーとして表示され、数秒後に消えます。Dynamic Island上のLive Activitiesは何時間でもアクティブに保つことができ、リアルタイムで更新されます(配達状況、タイマー、音楽)。
APNsを介したプッシュ更新を使用します。Live Activityを開始するときに、activity.pushTokenを呼び出し、トークンをサーバーに送信します。サーバーは新しいContentStateを含む更新リクエストをAPNs経由で送信します。代替方法として、アプリ内からactivity.update(using:)を介してローカル更新を行うこともできます。
2つのLive Activitiesがアクティブな場合、iOSは自動的にDynamic Islandを2つのセグメントに分割します。各アクティビティはカメラの左右にミニマル状態で表示されます。いずれかのセグメントを長押しすると、そのアプリの拡張状態のみが開きます。
確認事項:(1)アプリのInfo.plistにNSSupportsLiveActivities = YESがある、(2)ActivityAttributesとContentStateがCodableとHashableを実装している、(3)iOSバージョンが16.1+である、(4)デバイスがDynamic Islandをサポートしている。シミュレーターでは、XcodeでiPhone 14 Pro以降を使用してください。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。