swift 如何将按钮添加到iOS 14 Widget

3hvapo4f  于 2023-09-29  发布在  Swift
关注(0)|答案(3)|浏览(127)

我试图添加按钮到一个小部件具有家庭类型“.systemLarge”。我想在不打开应用程序的情况下执行一些代码。
有人知道怎么做吗?
例如,快捷方式应用程序小部件包含一些按钮,您可以点击这些按钮来执行快捷方式,而无需打开应用程序。

gkn4icbw

gkn4icbw1#

Widget是只读的。Shortcuts应用程序是一个例外。
https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension
小部件提供只读信息,不支持交互式元素,如滚动元素或开关。WidgetKit在呈现小部件的内容时省略交互式元素。

7y4bm7vi

7y4bm7vi2#

您可以在中型和大型小部件上添加链接控件,以获得类似按钮的行为。
这将不允许您创建交互式小部件,通过单击小部件内的元素来更改其内容。但是当你的应用通过widget被激活时,你将能够根据widgetUrl来判断哪个“链接”被点击了。
请参阅此处的“* 响应用户交互 *”一章:https://developer.apple.com/documentation/widgetkit/creating-a-widget-extension

irlmq6kh

irlmq6kh3#

iOS 17现已提供此功能!

Details here
从iOS 17、iPadOS 17或macOS 14开始,微件和Live Activities可以包含按钮和切换,以提供特定的应用功能,而无需启动应用
例如,Reminders小部件允许人们通过切换将任务标记为已完成。在锁定的设备上,按钮和切换处于非活动状态,除非用户对其设备进行身份验证并解锁,否则系统不会执行操作。

将功能添加为intent

  • 创建结构
  • Widget采用AppIntent协议
  • 对于Live Activity,采用LiveActivityIntent协议
  • 对于输入参数,通过@Parameter属性 Package 器定义(这必须符合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()函数是异步的,并标记为throws。
  • 当您从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
       }
    }
}

iOS 17之前版本解决方案

有一些局限性,但可以做到
1.你不能只是执行代码,你只能深度链接到你的应用程序,然后处理点击。

  1. systemSmall小部件被视为一个可点击区域(对多个触摸目标没有粒度控制)
  2. systemMediumsystemLarge可以有更多的触摸目标,并使用Link通过特定操作深度链接到您的应用。
    要查看如何完成此操作的示例,可以参考this post

相关问题