SwiftUI

iOS14 Widget小组件开发实践3——Widget点击交互

前面实现的Widget只是纯展示的样子,界面搭建也只是用展示的Text实现,当点击桌面Widget的时候,打开的是对应的APP。如果Widget布局的时候用的是按钮、图片、链接等方式,想实现点击对应的跳转APP对应的页面、事件,那么就需要额外处理。

根据官方文档的描述,点击Widget窗口唤起APP进行交互指定跳转支持两种方式:

  • widgetURL:点击区域是Widget的所有区域,适合元素、逻辑简单的小部件
  • Link:通过Link修饰,允许让界面上不同元素产生点击响应

Widget支持三种显示方式,分别是systemSmallsystemMediumsystemLarge,其中:
1、systemSmall只能用widgetURL修饰符实现URL传递接收。

@ViewBuilder
var body: some View {
    VStack(content: {
        Image("h_buyao")
            .resizable()
            .frame(width: 50, height: 50)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.white, lineWidth: 4))
            .shadow(radius: 10)
        Text("二狗子你变了")
    })
    .background(Color.init(red: 144 / 255.0, green: 252 / 255.0, blue: 231 / 255.0))
    .widgetURL(URL(string: "https://www.jianshu.com/u/bc4a806f89c5"))
}
  • 2、systemMediumsystemLarge可以用Link或者 widgetUrl处理
var body: some View {
    Link(destination: URL(string: "https://www.jianshu.com/u/bc4a806f89c5")!) {
        VStack {
            Image("h_buyao")
                .resizable()
                .frame(width: 50, height: 50)
                .clipShape(Circle())
                .overlay(Circle().stroke(Color.white, lineWidth: 4))
                .shadow(radius: 10)
            Text("二狗子你变了")
        }
    }
}

这两种方式的本质都是URL Schemes
在查找资料的时候,看到网上有的地方说在AppDelegate实现OpenUrl进行跳转处理:

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool

然而试了之后发现根本没有响应,其实是需要在SceneDelegate里面实现跳转处理,因为iOS13后,APPUI生命周期交由SceneDelegate管理,这里拿到需要的URL,就能处理产品需求实现了。

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    for context in URLContexts {
        print(context.url) // https://www.jianshu.com/u/bc4a806f89c5
    }
}

参考资料

creating-a-widget-extension
https://swiftrocks.com
iOS13 URL Schemes 跳转与传值问题