我正在尝试向具有系列类型“.systemLarge”的小部件添加按钮。我想在不打开应用程序的情况下执行一些代码。
有人知道该怎么做吗?
例如,快捷方式应用程序小部件包含您可以点击以执行快捷方式而无需打开应用程序的按钮。
小部件是只读的。快捷方式应用程序是一个例外。
https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
小部件呈现只读信息,不支持滚动元素或开关等交互元素。 WidgetKit 在渲染小部件内容时省略交互元素。
您可以在中型和大型小部件上添加链接控件以获得类似按钮的行为。
这不允许您创建交互式小部件,该小部件通过单击小部件内的元素来更改其内容。 但是,当您的应用程序通过小部件激活时,您将能够根据提供的 widgetUrl 判断点击了哪个“链接”。
请参阅此处的响应用户交互章节: https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
从 iOS 17、iPadOS 17 或 macOS 14 开始,小部件和实时活动可以包含按钮和开关,以在不启动应用程序的情况下提供特定的应用程序功能
例如,“提醒”小部件允许人们通过切换将任务标记为已完成。在锁定的设备上,按钮和切换按钮处于非活动状态,系统不会执行操作,除非用户验证并解锁其设备。
AppIntent
协议LiveActivityIntent
协议@Parameter
属性包装器定义(这必须符合 AppEntity
)perform()
功能中,添加您要在单击时执行的操作示例:
@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, *)
struct SuperCharge: AppIntent {
static var title: LocalizedStringResource = "Emoji Ranger SuperCharger"
static var description = IntentDescription("All heroes get instant 100% health.")
func perform() async throws -> some IntentResult {
EmojiRanger.superchargeHeros()
return .result()
}
}
注释
perform()
函数是异步的并标记为抛出。struct EmojiRangerWidgetEntryView: View {
var entry: SimpleEntry
@Environment(\.widgetFamily) var family
@ViewBuilder
var body: some View {
switch family {
// Code for other widget sizes.
case .systemLarge:
if #available(iOS 17.0, *) {
HStack(alignment: .top) {
Button(intent: SuperCharge()) {
Image(systemName: "bolt.fill")
}
}
.tint(.white)
.padding()
}
// ...rest of view
}
}
}
有一些限制,但可以做到
systemSmall
小部件被视为一个可点击区域(无法对多个触摸目标进行精细控制)systemMedium
和 systemLarge
可以有更多触摸目标,并使用 Link
通过特定操作深层链接到您的应用程序。要查看如何完成此操作的示例,您可以参考这篇文章。