import SwiftUIimport WidgetKit@mainstruct PizzaDeliveryActivityWidget: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: PizzaDeliveryAttributes.self) { context in // Create the view that appears on the Lock Screen and as a // banner on the Home Screen of devices that don't support the // Dynamic Island. // ... } dynamicIsland: { context in // Create the views that appear in the Dynamic Island. // ... } }}LiveActivity是一个Widget,以是代码是写在Widget的target里边。可以看到灵动岛的主函数就是继续与Wdiget。
上边函数的ActivityConfiguration第一个block就是锁屏界面的view。第二个block为灵动岛view。
创建锁屏界面的视图
体系要求高度不能高出160,高出的话会截掉
@mainstruct PizzaDeliveryWidget: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: PizzaDeliveryAttributes.self) { context in // Create the view that appears on the Lock Screen and as a // banner on the Home Screen of devices that don't support the // Dynamic Island. LockScreenLiveActivityView(context: context) } dynamicIsland: { context in // Create the views that appear in the Dynamic Island. // ... } }}struct LockScreenLiveActivityView: View { let context: ActivityViewContext<izzaDeliveryAttributes> var body: some View { VStack { Spacer() Text("\(context.state.driverName) is on their way with your pizza!") Spacer() HStack { Spacer() Label { Text("\(context.attributes.numberOfPizzas) Pizzas") } icon: { Image(systemName: "bag") .foregroundColor(.indigo) } .font(.title2) Spacer() Label { Text(timerInterval: context.state.deliveryTimer, countsDown: true) .multilineTextAlignment(.center) .frame(width: 50) .monospacedDigit() } icon: { Image(systemName: "timer") .foregroundColor(.indigo) } .font(.title2) Spacer() } Spacer() } .activitySystemActionForegroundColor(.indigo) .activityBackgroundTint(.cyan) }}创建灵动岛视图
灵动岛视图分为两大部门
一部门是灵动岛默认状态,就是紧凑状态
一部门是长按灵动岛的扩展状态
创建紧凑和最小的视图
默认情况下,灵动岛中的紧凑和最小视图利用玄色配景颜色和白色文本。可以利用修改keylineTint(_
import SwiftUIimport WidgetKit@mainstruct PizzaDeliveryWidget: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: PizzaDeliveryAttributes.self) { context in // Create the view that appears on the Lock Screen and as a // banner on the Home Screen of devices that don't support the // Dynamic Island. // ... } dynamicIsland: { context in // Create the views that appear in the Dynamic Island. DynamicIsland { // Create the expanded view. // ... } compactLeading: { Label { Text("\(context.attributes.numberOfPizzas) Pizzas") } icon: { Image(systemName: "bag") .foregroundColor(.indigo) } .font(.caption2) } compactTrailing: { Text(timerInterval: context.state.deliveryTimer, countsDown: true) .multilineTextAlignment(.center) .frame(width: 40) .font(.caption2) } minimal: { VStack(alignment: .center) { Image(systemName: "timer") Text(timerInterval: context.state.deliveryTimer, countsDown: true) .multilineTextAlignment(.center) .monospacedDigit() .font(.caption2) } } .keylineTint(.cyan) } }}创建扩展视图
视图最高160,多余截断
扩展视图分为4部门
center将内容放置在原深感摄像头下方。
leading将内容沿睁开的 Live Activity 的前沿放置在原深感摄像头旁边,并在其下方包裹其他内容。
trailing将内容放置在 TrueDepth 摄像头旁边睁开的 Live Activity 的后沿,并在其下方包裹其他内容。
bottom将内容置于前导、尾随和居中内容之下。
struct PizzaDeliveryWidget: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: PizzaDeliveryAttributes.self) { context in // Create the view that appears on the Lock Screen and as a // banner on the Home Screen of devices that don't support the // Dynamic Island. LockScreenLiveActivityView(context: context) } dynamicIsland: { context in // Create the views that appear in the Dynamic Island. DynamicIsland { // Create the expanded view. DynamicIslandExpandedRegion(.leading) { Label("\(context.attributes.numberOfPizzas) Pizzas", systemImage: "bag") .foregroundColor(.indigo) .font(.title2) } DynamicIslandExpandedRegion(.trailing) { Label { Text(timerInterval: context.state.deliveryTimer, countsDown: true) .multilineTextAlignment(.trailing) .frame(width: 50) .monospacedDigit() } icon: { Image(systemName: "timer") .foregroundColor(.indigo) } .font(.title2) } DynamicIslandExpandedRegion(.center) { Text("\(context.state.driverName) is on their way!") .lineLimit(1) .font(.caption) } DynamicIslandExpandedRegion(.bottom) { Button { // Deep link into your app. } label: { Label("Call driver", systemImage: "phone") } .foregroundColor(.indigo) } } compactLeading: { // Create the compact leading view. // ... } compactTrailing: { // Create the compact trailing view. // ... } minimal: { // Create the minimal view. // ... } .keylineTint(.yellow) } }}利用自界说颜色
您启动 Live Activity 时,ActivityKit 会返回一个Activity对象。除了id唯一标识每个活动之外,Activity还提供观察内容状态、活动状态和推送令牌更新的序列。利用相应的序列在您的应用中接收更新,使您的应用和 Live Activity 保持同步,并相应更改的数据:
要观察正在举行的 Live Activity 的状态——比方,确定它是处于活动状态还是已经竣事——利用.activityStateUpdates
要观察 Live Activity 动态内容的厘革,请利用.contentState
要观察 Live Activity 的推送令牌的厘革,请利用.pushTokenUpdates
获取活动列表
您的应用可以启动多个 Live Activity。比方,体育应用步调大概允许用户为他们感爱好的每个现场体育角逐启动现场活动。假如启动多个现场活动,请利用该功能获取有关您的应用步调正在举行的现场活动的关照。跟踪正在举行的 Live Activity 以确保您的应用步调的数据与 ActivityKit 跟踪的活动 Live Activity 同步。activityUpdates
以下代码段体现了披萨外卖应用步调怎样检索正在举行的活动列表:
// Fetch all ongoing pizza delivery Live Activities.for await activity in Activity<izzaDeliveryAttributes>.activityUpdates { print("izza delivery details: \(activity.attributes)")}获取全部活动的另一个用例是维护正在举行的实时活动,并确保您不会让任何活动一连运行高出须要的时间。比方,体系大概会制止您的应用步调,大概您的应用步调大概会在 Live Activity 处于活动状态时瓦解。当应用下次启动时,查抄是否有任何活动仍处于活动状态,更新应用存储的 Live Activity 数据,并竣事任何不再干系的 Live Activity。
参考文档:
官方文档