iOS 小组件开发:灵动岛开发

发布时间:2024年01月09日

灵动岛配置

首先,灵动岛实际上是一个小组件,就像 iOS 14 小部件一样,这也是为什么我会放在小组件的部分来讲。

1、创建 Target

让我们来创建一个新的?Widget Target,来到?File -> New -> Target...,创建一个?Widget Extension

一定要勾选?Include live Activity,然后输入名称,点击完成既可。

2、添加 Info.plist 配置

项目要启用灵动岛,需要在?Info.plist?文件中声明开启,打开?Info.plist?文件添加?NSSupportsLiveActivities,并将其布尔值设置为 YES。

展示部分

当我们创建这个?Target Extension?并且勾选了?Include live Activity?之后,Xcode 会自动帮我们创建出来一个灵动岛的模版,我目前用的是 Xcode 15,可以看下 Xcode 自动生成的模版预览:

灵动岛有三种渲染模式,第一种是紧凑型,当只有你的应用在应用在使用灵动岛时,会展示成这样:

第二种叫最小型样式,是当你的应用和别人的应用都在使用灵动岛时,会显示成下面这种样式,系统会决定展示哪个 App 的灵动岛,并使用每个活动的最小演示显示两个实时活动:

第三种是展开的灵动岛样式,当用户触摸并按住紧凑或最小的演示文稿时,它会显示,这种样式可以显示更多的内容:

代码部分

主要代码分为两部分,一部分是?ActivityAttributes,主要用来提供灵动岛上展示的数据:

 

css

复制代码

struct MyLiveActivityAttributes: ActivityAttributes { public struct ContentState: Codable, Hashable { var emoji: String } var name: String }

当我们需要展示灵动岛的时候需要创建一份?ActivityAttributes

另一部分是灵动岛的 UI 展示:

 

scss

复制代码

struct MyLiveActivityLiveActivity: Widget { var body: some WidgetConfiguration { ActivityConfiguration(for: MyLiveActivityAttributes.self) { context in // 展示锁屏页面的 UI VStack { Text("\(context.attributes.name) \(context.state.emoji)") } .activityBackgroundTint(Color.cyan) .activitySystemActionForegroundColor(Color.black) } dynamicIsland: { context in DynamicIsland { // 展开样式 UI DynamicIslandExpandedRegion(.leading) { Text("左侧") } DynamicIslandExpandedRegion(.trailing) { Text("右侧") } DynamicIslandExpandedRegion(.bottom) { Text("底部 \(context.state.emoji)") Text("内容:\(context.attributes.name) 自定义内容") } } compactLeading: { // 紧凑型样式左边 UI Text("左") } compactTrailing: { // 紧凑型样式右边 UI Text("右 \(context.state.emoji)") } minimal: { // 最小型样式 UI Text(context.state.emoji) } .widgetURL(URL(string: "http://www.apple.com")) .keylineTint(Color.red) } } }

ActivityConfiguration?的第一个 block 用来渲染展示锁屏页面的 UI,dynamicIsland?就是用来渲染灵动岛的内容了。

DynamicIsland?对象中,第一部分用来渲染展开样式的 UI,compactLeading?用来展示紧凑型样式左边 UI,compactTrailing?用来展示紧凑型样式右边 UI,minimal?用来展示最小型样式 UI。

关于 UI 部分,可以自由发挥,但要注意每个区域的大小。

启动灵动岛

我们在主?App?的?ViewController?中渲染三个按钮来模拟用户达到某个条件后启动/更新和关闭灵动岛:

 

swift

复制代码

import ActivityKit class ViewController: UIViewController { var activity: Activity<MyLiveActivityAttributes>? = nil override func viewDidLoad() { super.viewDidLoad() createButton(title: "启动灵动岛", y: view.center.y - 100, selector: #selector(start)) createButton(title: "更新灵动岛", y: view.center.y - 50, selector: #selector(update)) createButton(title: "关闭灵动岛", y: view.center.y, selector: #selector(end)) } private func createButton(title: String, y: CGFloat, selector: Selector) { let button = UIButton(type: .system) button.setTitle(title, for: .normal) button.sizeToFit() view.addSubview(button) button.center.x = view.center.x button.frame.origin.y = y button.addTarget(self, action: selector, for: .touchUpInside) } @objc private func start() { // 创建灵动岛 let attributes = MyLiveActivityAttributes(name: "iOS 新知") let state = MyLiveActivityAttributes.ContentState(emoji: " ") let content = ActivityContent<MyLiveActivityAttributes.ContentState>(state: state, staleDate: nil) do { self.activity = try Activity<MyLiveActivityAttributes>.request(attributes: attributes, content: content) } catch let error { print("出错了:\(error.localizedDescription)") } } @objc private func update() { let state = MyLiveActivityAttributes.ContentState(emoji: " ") Task { await activity?.update(using: state) } } @objc private func end() { Task { await activity?.end() } } }

启动灵动岛需要创建一个?ActivityAttributes,和一个?ActivityContent,然后调用?request(attributes: content:)?方法既可,这个方法会返回一个?Activity?对象,我们保留这个对象,后面更新和关闭灵动岛的时候使用。

更新灵动岛只需要使用上边的?Activity?对象,调用?update(using:)?方法。

关闭灵动岛只需要使用上边的?Activity?对象,调用?end()?方法。

最后看一下效果。

当我们启动 App,点击 "启动灵动岛" 按钮,然后把应用退到后台(前台不展示),就可以看到灵动岛上出现了我们设置的 UI:

然后看下锁屏页面,推送通知区域会看到出现了我们渲染的内容:

长按灵动岛,可以从紧凑模式变成扩展模式:

点击灵动岛可以打开 App,然后点击 "更新灵动岛" 按钮,再次退到后台,可以看到灵动岛已经刷新了:

最后点击 "关闭灵动岛" 按钮,再退到后台,灵动岛消失。

这里每天分享一个 iOS 的新知识,快来关注我吧

文章来源:https://blog.csdn.net/m0_60961651/article/details/135448577
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。