[iOS14]WidgetKit开发实战4-Link-支付小部件

7,561 阅读3分钟

前言

如何让我们的Widget和用户交互?而不仅仅是一个展示栏?

这个问题想必大家开发的过程中都遇到过吧?目前iOS14-beta1是只支持点击(tap)操作的,也就是说Widget无法使用滚动等手势来完成交互的。

但是这里的点击和我们APP里面的点击还略有不同: 只能通过Link来操作,不能使用点击事件来操作

同时这里的Link还和软件内的Link不同,这里的Link只能用于跳转到自己APP内,如果需要使用DeepLink等就必须要在软件内再次跳转。

如果你没有看过前面的文章建议先阅读前面的文章:

[iOS14]WidgetKit开发实战1-初识iOS小部件

[iOS14]WidgetKit开发实战2-开发一言小部件

[iOS14]WidgetKit开发实战3-小部件用户配置

项目地址:github.com/Littleor/iW…

效果展示

打造支付小部件

如何打造一款支付小部件用来快速唤醒支付宝和微信的扫一扫和付款码?

这里就需要用到Link了,下面让我们从零开始写小部件

1.创建Widget

前面已经详细写了如何创建一个Widget,这里就不再赘述。

我们这里直接使用上一节的可配置的内容小部件来作为底板修改

初始代码

2.修改Provider

这里我们要做的是一款快捷支付小部件,无需更新故把Provider中的timeline改为.never

.never的小部件仍然可以通过WidgetCenter调用API更新

struct PayToolsProvider: IntentTimelineProvider {
    typealias Entry = SimpleEntry
    public func snapshot(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date())
        completion(entry)
    }
    
    public func timeline(for configuration: ConfigurationIntent, with context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        let currentDate = Date()
        let entry = SimpleEntry(date: currentDate)
        let timeline = Timeline(entries: [entry], policy: .never)
        completion(timeline)
    }
}

其中的SimpleEntry为:

struct SimpleEntry: TimelineEntry {
    public let date: Date
    //去除了configure毕竟快捷支付小部件没啥可以配置的
}

3.修改View

View是我们需要注意的重点,无论是Link还是widgetURL都需要通过View来配置 这里我们直接先贴代码。其中的IconWidgetItem为我封装的一个View,完整代码详见iWidget

struct PayToolsMediumView: View {
    var body: some View {
        HStack(spacing: 3.0) {
            IconWidgetItem(icon:"qrcode",bottomIcon: "alipay",size: 70)
            IconWidgetItem(icon: "pay",bottomIcon: "alipay",size: 70,url: "alipay://platformapi/startapp?appId=20000056")
                .padding([.top, .leading, .bottom])
            IconWidgetItem(icon: "qrcode",bottomIcon: "wechat",size: 70, url: "weixin://scanqrcode")
                .padding(.all)
            IconWidgetItem(icon: "pay",bottomIcon: "wechat",size: 70, url: "weixin://")
        }
    }
}

其中IconWidgetItem代码:

struct IconWidgetItem:View {
    var icon:String = "qrcode"
    var bottomIcon:String = "alipay"
    var size: CGFloat = 60
    var url: String  = "alipayqr://platformapi/startapp?saId=10000007"
    var body: some View {
    //这里的Link是关键
        Link(destination: URL(string: url)!) {
            ZStack {
                ZStack {
                    Image(icon)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                }
                .frame(width: size, height: size, alignment: .center)
                .zIndex(1)
                HStack() {
                    Spacer()
                    VStack {
                        Spacer()
                        HStack {
                            Image(bottomIcon)
                                .resizable()
                                .aspectRatio(contentMode: .fit)
                                .opacity(1)
                            
                        }
                        .frame(width: size/3, height: size/3, alignment: .center)
                        .background(Color.white)
                        .cornerRadius(size/6)
                        .shadow(radius: 1)
                    }
                    
                }
                .zIndex(2)
            }.frame(width: size, height: size, alignment: .center)
        }
        
    }
}

IconWidgetItem中的Link是关键点,配置了Link就可以让Widget点击后跳转APP的时候带上URL。

但是这个时候是不能点击打开这个Link的。而是打开了APP。

4.软件内部跳转

因为Widget无法直接打开Link,所以我们只能退而求其次,这里我采用的是使用NavigationView的onOpenURL方法来实现跳转,如果有更好的方法欢迎留言或提交PR!

    NavigationView{
        //...View
    }
  .onOpenURL(perform: { (url) in
            UIApplication.shared.open(url)
        })

如此即可实现Widget的Link通过APP跳转。

后记

iOS14提供的Widgetkit大概内容也就到这里结束了,Widget开发往简单来说需要做的无非是Provider和View和一点配置,配置好Provider和View我相信你也可以做出优雅的小部件!

最后如果你认为这些文章对你有用,欢迎给该Github项目iWidget点个Star。

个人博客: sixming.com

项目地址:github.com/Littleor/iW…