序章
AppleはiPhone 14 ProとiPhone 14 Pro MAXでSmart Islandを開始しました。スマート アイランドはタップ、長押し、スワイプによって操作でき、最大 2 つのアプリケーションが同時に「島に上陸」することができます。
Dynamic Island の正式名称は Dynamic Island で、iOS のライブ アクティビティ機能の一部として、リアルタイムで更新が必要なニュースを表示するために使用されます。
- プレゼンテーション形式プレゼンテーション形式は<Compact>、<Minimized>、 <Extended>
の 3 つがあり、開発および提出の際はこれら 3 つの形式に適応する必要があります。Compact
Minimal
Expanded
- UI サイズ適応 <次元単位ポイント>
フィレット半径は44です。
モデル | コンパクト<先端側> | コンパクト<トレーリング側> | 最小化する | 拡大 |
---|---|---|---|---|
14プロ | 52.33*36.67 | 52.33*36.67 | 36.67 * 36.67 | 371 * (84-160) |
14プロマックス | 62.33*36.67 | 62.33*36.67 | 36.67 * 36.67 | 408 * (84-160) |
-
カラーアダプテーションでは、
スマート アイランドの背景色は変更できません。スマート アイランドの文字色、マテリアルの色、境界線の色などのみが変更されます。UI の適応ではシステムのダーク モードを考慮する必要があり、必要に応じて 2 つの UI セットを使用できます。 -
発達適応
- Apple は
iOS 16.1
スマート アイランド適応フレームワークを外部に正式に公開しActivityKit
、サードパーティはApp
これらを使用してActivityKit
スマート アイランド適応作業を完了できます。現在は にのみ適用されるActivityKit
ことに注意してください。Smart Island は、と を使用してUI 開発作業を完了します。この作業では、 の作成、データの要求、データの更新、および終了の役割を果たします。API
iPhone
WidgetKit
SwiftUI
ActivityKit
Activity
Activity
- スマートアイランド機能を利用するには「リアルタイムアクティビティ許可」をオンにする必要があります。
- Apple は
-
開発ノート
- スマートアイランドのリアルタイム情報には、明確な開始時点と終了時点が必要です
- リアルタイム情報が8時間以上続くと、システムはこのアプリの情報をスマートアイランドから削除します
- リアルタイムイベントが終了すると、スマートアイランド上の表示情報もシステムによって即座に削除されます。
- アプリは、スマート アイランドのクリック情報に応答し、アプリのホームページに留まるのではなく、アプリ内の正しいサブページにジャンプできる必要があります。
開発する
権限の追加
メインプロジェクトにInfo.plist
追加されましたNSSupportsLiveActivities = YES
。
ウィジェットの作成
- でプロジェクトを
Xcode
開き、 (ファイル) > (新規) > (ターゲット)App
を選択します。File
New
Target
Application Extension
(App
拡張機能)グループからWidget Extension
(ウィジェット拡張機能)を選択し、Next
(次へ)をクリックします。- 拡張機能の名前を入力します。
- ウィジェットがユーザー構成可能なプロパティを提供する場合は、
Include Configuration Intent
(構成意図を含める) チェック ボックスをオンにします。 Finish
(完了)をタップします。
ウィジェットを書く
データモデルを書く
データモデル、ActivityAttributes
プロトコルに従う必要がある
struct DynamicAttributes: ActivityAttributes {
// 动态数据
public struct ContentState: Codable, Hashable {
var value: Int
}
// 静态数据
var name: String
}
ページスタイルの作成 < SwiftUI
>
struct DynamicLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: DynamicAttributes.self) {
context in
// 通知区域
// Lock screen/banner UI goes here
VStack {
Text("Hello")
}
.activityBackgroundTint(Color.cyan)
.activitySystemActionForegroundColor(Color.black)
} dynamicIsland: {
context in
DynamicIsland {
// 扩展
// Leading Space
DynamicIslandExpandedRegion(.leading) {
Text("Leading")
}
// Bottom
DynamicIslandExpandedRegion(.bottom) {
Text("bottom")
}
// Trailing Space
DynamicIslandExpandedRegion(.trailing) {
Text("trailing")
}
// Center Space
DynamicIslandExpandedRegion(.center) {
Text("center")
}
} compactLeading: {
// 紧凑
Text("L")
} compactTrailing: {
// 紧凑
Text("T")
} minimal: {
// 最小化
Text("Min")
}
.widgetURL(URL(string: "http://www.apple.com"))
.keylineTint(Color.red)
}
}
}
データ更新
class DynamicManager {
static let shared: DynamicManager = DynamicManager()
private init () {
}
/// 开始
/**
active 处于活动中
ended 已经终止且不会有任何更新,但依旧在锁屏界面展示
dismissed 结束且不再展示
*/
func stratDynamicActivity() {
// 初始化静态数据
let dynamicAttributes = DynamicAttributes(name: "ceshi", data: "ceshiData")
// 初始化动态数据
let initialContentState = DynamicAttributes.ContentState(value: 100, id: 1000)
do {
// 启用灵动岛
// 灵动岛只支持iPhone,areActivitiesEnabled用来判断设备是否支持,
// 即便是不支持的设备,依旧可以提供不支持的样式展示
if ActivityAuthorizationInfo().areActivitiesEnabled == true {
}
let deliveryActivity = try Activity<DynamicAttributes>.request(attributes: dynamicAttributes,contentState: initialContentState,pushType: nil)
// 判断启动成功后,获取推送令牌 ,发送给服务器,用于远程推送Live Activities更新
// 不是每次启动都会成功,当已经存在多个Live activity时会出现启动失败的情况
if deliveryActivity.activityState == .active{
_ = deliveryActivity.pushToken
}
// deliveryActivity.pushTokenUpdates //监听token变化
print("Current activity id -> \(deliveryActivity.id)")
} catch (let error) {
print("Error info -> \(error.localizedDescription)")
}
}
/// 更新
func updateDynamicActivity() {
Task {
let newContent = DynamicAttributes.ContentState(value: 10, id: 10)
//此处只有一个灵动岛,当一个项目有多个灵动岛时,需要判断更新对应的activity
for activity in Activity<DynamicAttributes>.activities {
await activity.update(using: newContent)
}
}
}
/// 停止
/**
结束分为两种
.default 系统默认,结束后在锁屏界面保留4小时
.immediate 立即结束,不会在锁屏界面停留
*/
func stopDynamicActivity() {
Task {
//此处只有一个灵动岛,当一个项目有多个灵动岛时,需要判断更新对应的activity
for activity in Activity<DynamicAttributes>.activities {
await activity.end(nil,dismissalPolicy: .immediate)
}
}
}
}
注意事項
スマートアイランドには、「
active
アクティブ」
ended
、「終了済みで更新されないがロック画面には表示される」、「
dismissed
終了し、表示されなくなる」の3 つのアクティブ状態があります。
参考リンク:Apple開発サイト