iOS_灵动岛<Dynamic Island>

这篇具有很好参考价值的文章主要介绍了iOS_灵动岛<Dynamic Island>。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

苹果在 iPhone 14 Pro 及 iPhone 14 Pro MAX 上推出了灵动岛。灵动岛可以通过点按、长按、轻扫来进行交互,最多支持两个应用同时“登岛”。
灵动岛全称 Dynamic Island,作为 iOS 中实时活动(Live Activities)功能的一部分,用来展示需要实时更新的消息。

  • 展现形式
    展现形式有三种:Compact <紧凑>、Minimal <最小化>、Expanded <扩展>,在开发提交的时候,必须适配这三种形式
  • UI尺寸适配<尺寸单位Points>
    圆角半径均为 44
机型 紧凑< Leading Side> 紧凑< Trailing Side > 最小化 扩展
14 Pro 52.33 * 36.67 52.33 * 36.67 36.67 * 36.67 371 * (84-160)
14 Pro Max 62.33 * 36.67 62.33 * 36.67 36.67 * 36.67 408 * (84-160)
  • 颜色适配
    无法更改灵动岛的背景颜色,只能更改文字颜色、素材颜色、灵动岛边框颜色等。UI 适配需要考虑系统的深色模式,必要情况可以使用两套 UI。

  • 开发适配

    • 苹果在 iOS 16.1 正式对外开放了灵动岛适配框架 ActivityKit,第三方 App 可以使用这些 ActivityKit 完成灵动岛适配工作。注意 ActivityKitAPI 目前仅适用于 iPhone。灵动岛使用 WidgetKitSwiftUI 完成 UI 开发工作,ActivityKit 在其中扮演创建 Activity,请求数据,更新数据,结束 Activity 的角色。
    • 需要打开"实时活动权限",才可以使用灵动岛功能。
  • 开发注意要点

    • 灵动岛的实时信息要有明确的开始和结束时间点
    • 当一个实时信息持续超过 8 小时,系统会从灵动岛移除这个 App 的信息
    • 当一个实时活动结束时,灵动岛上的展示信息也会立即被系统移除
    • App 要能够响应灵动岛的点击信息,跳转到 App 中的正确子页面,而不是停留在 App 的首页

开发

新增权限

在主项目的Info.plist中添加NSSupportsLiveActivities = YES

创建小组件

  1. Xcode 中打开你的 App 项目,并选取File(文件) >New(新建) >Target(目标)。
  2. Application Extension(App 扩展) 组中,选择Widget Extension(小组件扩展),然后点按Next(下一步)。
  3. 输入你的扩展的名称。
  4. 如果小组件提供用户可配置的属性,请选中Include Configuration Intent(包含配置意图) 复选框。
  5. 点按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)
            }
        }
    }
}


注意事项
灵动岛的活动状态一共有3种:
active 处于活动中
ended 已经终止且不会有任何更新,但依旧在锁屏界面展示
dismissed 结束且不再展示


参考链接:苹果开发网站文章来源地址https://www.toymoban.com/news/detail-518447.html

到了这里,关于iOS_灵动岛<Dynamic Island>的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【学习笔记】CF627F Island Puzzle

    好啊,树上贪心题。 首先可以用类似于拓扑排序的过程将无用的节点全部删掉。 具体的,如果两个叶子节点对应的值恰好相同,那么同时将叶子节点删去;如果其中一个叶子节点对应的是 0 0 0 ,并且与父节点交换后相同,因为操作是可逆的,那么花费 1 1 1 的代价将 0 0 0 往

    2024年02月02日
    浏览(41)
  • iOS —— xcode14兼容 iOS9~iOS10系统

    xcode14兼容 iOS9~iOS10系统 在Xcode升级到Xcode14以后,系统的支持版本升级到了iOS11.0。但是我们项目需要支持iOS9,脚本打包错误提示: The iOS deployment target \\\'IPHONEOS_DEPLOYMENT_TARGET\\\' is set to 9.0, but the range of supported deployment target versions is 11.0 to 16.2.99. 下面记录适配过程。 适配过程同

    2024年02月09日
    浏览(50)
  • C++中ios::in, ios::out, ios::trunc使用

    目录 一,ios::in 二,ios::out 三,ios::trunc 四,组合使用 在C++中,ios::in和ios::out是iostream库中定义的一些标志,用于控制文件流对象(如fstream、ifstream和ofstream)的行为。 ios::in: 这个标志用于以输入模式打开文件,即用于从文件中读取数据。如果你使用ifstream(输入文件流)来打

    2024年02月02日
    浏览(30)
  • ios_base::out和ios::out、ios_base::in和ios::in、ios_base::app和ios::app等之间有什么区别吗?

    2023年8月2日,周三晚上 今天我看到了这样的两行代码: 这让我产生了几个疑问: 为什么有时候用ios_base::out,有时候用ios::out? ios_base::out和ios::out之间有区别吗? 我花了一两个小时才搞清楚.... 目录 结论 ios_base类的 I/O 流控制标志有哪些 ios类的 I/O 流控制标志有哪些 证明它

    2024年02月14日
    浏览(36)
  • 【iOS】iOS持久化

    快速展示,提升体验 已经加载过的数据,用户下次查看时,不需要再次从网络(磁盘)加载,直接展示给用户 节省用户流量(节省服务器资源) 对于较大的资源数据进行缓存,下次展示无需下载消耗流量 同时降低了服务器的访问次数,节约服务器资源。(图片) 离线使用

    2024年02月15日
    浏览(74)
  • IO模型-信号驱动IO

    linux内核中存在一个信号SIGIO,这个信号就是用于实现信号驱动IO的。当应用程序中想要以信号驱动IO的模型读写硬件数据时,首先注册一个SIGIO信号的信号处理函数,当硬件数据就绪,硬件会发起一个中断,在硬件的中断处理函数中向当前进程发送SIGIO信号,此时进程捕获到SI

    2024年02月14日
    浏览(35)
  • 面试题:简单说一下阻塞IO、非阻塞IO、IO复用的区别 ?

    在《Unix网络编程》一书中提到了五种IO模型,分别是:阻塞IO、非阻塞IO、IO复用、信号驱动IO以及异步IO。本篇文章主要介绍IO的基本概念以及阻塞IO、非阻塞IO、IO复用三种模型,供大家参考学习。 计算机视角理解IO: 对于计算机而言,任何涉及到计算机核心(CPU和内存)与其

    2024年01月22日
    浏览(42)
  • 升级iOS17后可以降级吗?iOS17退回iOS16方法教程分享

    iOS 17已上线几天,从网上用户的反馈和媒体机构的报告来看,iOS17系统对旧机型来说并不友好,除了电池续航下降以外,占用大量储存空间,BUG也不少。 苹果于 9 月 7 日发布了 iOS 16.6.1 版本,如果升级iOS17后发现不适合自己,可参考以下方法退回到iOS16.6.1。 降级工具小编推荐

    2024年02月08日
    浏览(49)
  • IO、NIO、IO多路复用

    IO是什么? 网络IO是如何连接的? 下面是一次网络读取内容的I/O示意图,数据先从外设(网卡)到内核空间,再到用户空间(JVM),最后到应用程序的一个过程。 上述一次I/O读取,所谓的阻塞和非阻塞体现在哪里呢? Java最早期的版本的I/O就是这样实现的。当程序调用到读取

    2024年01月20日
    浏览(43)
  • 文件IO,目录IO的学习

    用法:#include“head.h”    -     在当前目录下寻找头文件 主函数的传参中,argc是传参的个数  ,const char *argv[]是一个指针数组,存放的指针类型数据 argv【n】,n=1/2/3 分别代表三个指针参数 标准示例:     off_t lseek(int fd, off_t offset, int whence);        功能:            

    2024年02月20日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包