iOS 小组件开发第九篇:在 iOS 17 上创建可交互的小组件

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

前言

小组件相关内容传送门:

iOS 小组件开发第一篇:基础介绍
iOS 小组件开发第二篇:时间线
iOS 小组件开发第三篇:实战
iOS 小组件开发第四篇:小组件的尺寸
iOS 小组件开发第五篇:开发可配置的小组件
iOS 小组件开发第六篇:点击事件和交互
iOS 小组件开发第七篇:锁屏小组件
iOS 小组件开发第八篇:灵动岛开发

今天继续讲小组件,在今年的 iOS 17 中,苹果对小组件的能力进一步升级,目前终于可以在不打开 App 的情况下进行交互了,今天就带大家一起实现这个新功能。

创建

首先还是先创建一个 Widget Target

AppIntent

要想实现可点击的按钮需要先自定义一个 AppIntent,比如我们要实现一个计数器的功能,可以这样实现一个 AppIntent

首先导入 import AppIntents,然后实现以下代码:

swift 复制代码
struct CalculateIntent: AppIntent {
    
    static var title: LocalizedStringResource = "Calculate Task"
    static var description: IntentDescription = IntentDescription("Calculate Number Task")
    
    @Parameter(title: "value")
    var value: Int
    
    init() { }
    init(value: Int) {
        self.value = value
    }
    
    func perform() async throws -> some IntentResult {
        NumberManager.number += value
        return .result()
    }
}

解释一下代码,我们实现一个名为 CalculateIntent 的结构体,遵守 AppIntent 协议,然后实现协议内容:titledescription,然后添加一个 value 属性,Int 类型,用来存储传入的数字,最后实现 perform() 方法。

最终这个 CalculateIntent 会用在我们可交互的按钮上,当点击按钮的时候会调用 perform() 方法。

除此之外,我们还需要一个全局属性存储计算的结果:

csharp 复制代码
struct NumberManager {
    static var number = 0
}

当我们执行完运算,return .result() 的时候,系统会自动调用刷新操作,此时会刷新小组件的时间线。

Widegt 代码部分

有了 CalculateIntent 结构体就可以来构建可交互的按钮了,Button 组件 和 Toggle 组件在 iOS 17 上新增了支持传入 AppIntent 协议的初始化方法:

swift 复制代码
@available(iOS 17.0, macOS 13.0, tvOS 17.0, watchOS 10.0, *)
extension Button {

    /// Creates a button that performs an `AppIntent`.
    ///
    /// - Parameters:
    ///   - intent: The `AppIntent` to execute.
    ///   - label: A view that describes the purpose of the button's `action`.
    public init<I>(intent: I, @ViewBuilder label: () -> Label) where I : AppIntent
}

@available(iOS 17.0, macOS 13.0, tvOS 17.0, watchOS 10.0, *)
extension Toggle {

    /// Creates a toggle performing an `AppIntent`.
    ///
    /// - Parameters:
    ///   - isOn: Whether the toggle is on or off.
    ///   - intent: The `AppIntent` to be performed.
    ///   - label: A view that describes the purpose of the toggle.
    public init<I>(isOn: Bool, intent: I, @ViewBuilder label: () -> Label) where I : AppIntent
}

利用这个方法可以创建出可交互的 Button,我们在页面上创建几个用来点击计算的按钮,另外再创建一个展示最终结果的 Text 组件:

less 复制代码
struct InteractivityWidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        VStack {
            Text("结果: \(NumberManager.number)")
            
            HStack {
                Button(intent: CalculateIntent(value: 10)) {
                    Text("加 10")
                }
                Button(intent: CalculateIntent(value: 1)) {
                    Text("加 1")
                }
                Button(intent: CalculateIntent(value: -1)) {
                    Text("减 1")
                }
                Button(intent: CalculateIntent(value: -10)) {
                    Text("减 10")
                }
            }
        }
    }
}

最后看下效果:

当点击下边几个按钮时,会执行数字计算,最后显示在上边的 Text 中。

最后

需要注意,可交互的组件仅支持 ButtonToggle 组件,其他控件都不起作用。

另外,因为 AppIntent 执行结束后,会导致小组件重新加载时间线,这就会带来从操作到 UI 结果展示之间有一小段延迟,Apple 也提供了一个方式避免这种问题,可以使用 .invalidatableContent() 修饰符来修饰某个视图,这样在点击按钮之后到 UI 更新之前,更新内容都是无效的。

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

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
恋猫de小郭7 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
万少11 小时前
第五款 HarmonyOS 上架作品 奇趣故事匣 来了
前端·harmonyos·客户端
点金石游戏出海13 小时前
每周资讯 | Krafton斥资750亿日元收购日本动画公司ADK;《崩坏:星穹铁道》新版本首日登顶iOS畅销榜
游戏·ios·业界资讯·apple·崩坏星穹铁道
旷世奇才李先生14 小时前
Swift 安装使用教程
开发语言·ios·swift
90后的晨仔15 小时前
Xcode16报错: SDK does not contain 'libarclite' at the path '/Applicati
ios
finger2448015 小时前
谈一谈iOS线程管理
ios·objective-c
Digitally16 小时前
如何将大型视频文件从 iPhone 传输到 PC
ios·iphone
梅名智16 小时前
IOS 蓝牙连接
macos·ios·cocoa
美狐美颜sdk1 天前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk
恋猫de小郭1 天前
Meta 宣布加入 Kotlin 基金会,将为 Kotlin 和 Android 生态提供全新支持
android·开发语言·ios·kotlin