Widget

iOS Widget Extension

2021-05-31  本文已影响0人  evan0723

iOS14 Apple 新引入了 Widget Extension 的功能 来代替之前的 Today extension

1.首先我们需要添加一个 target 然后搜索 widget
2.然后系统会为我们生成一个文件 里面的 Struct 实现了 TimelineProvider 协议
struct GreetingTimeLine: TimelineProvider {
    typealias Entry = GreetingEntryModel
    
    /// Required Methods
    
    func placeholder(in context: Context) -> GreetingEntryModel {
        
        Entry(date: Date(), moments: [ .placeholder ])
    }
    
    func getSnapshot(in context: Context, completion: @escaping (GreetingEntryModel) -> Void) {
        
        let entry = Entry(date: Date(), moments: [ .placeholder ])
        completion(entry)
    }
    
    func getTimeline(in context: Context, completion: @escaping (Timeline<GreetingEntryModel>) -> Void) {
        
        var entries: [Entry] = []
        let currentDate = Date()
        
        /// widget will be refresh every minute
        
        let refreshTime = Calendar.current.date(byAdding: .minute, value: 1, to: currentDate)!
        
        for hoursOffset in 0..<24 {
            
            guard let entryDate = Calendar.current.date(byAdding: .hour, value: hoursOffset, to: currentDate) else {
                return
            }
            let entry = Entry(date: entryDate, moments: [ .placeholder ])
            entries.append(entry)
        }
        
        Server.getMoment { result in
            var moments: [Moment] = []
            if case .success(let value) = result{
                moments = value
            } else {
                moments = [ .placeholder ]
            }
            let entry = Entry(date: currentDate, moments: moments)
            let timeline = Timeline(entries: [entry], policy: .after(refreshTime))
            completion(timeline)
        }
    }
3. Widget 的主函数 包含 Widget 的配置
@main
struct Greeting: Widget {
    let kind: String = "Greeting"

    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind, provider: GreetingTimeLine()) { entry in
            GreetingEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget") // 组件的名称
        .description("This is an example widget.") // 关于组件的介绍
        .supportedFamilies([ .systemMedium ]) // 支持的样式 有大中小三种
    }
}

效果就下面的这个样子


SwiftUI的代码

struct MomentView: View {
    let entry: GreetingEntryModel
    
    var body: some View {
        ZStack(alignment: .leading) {
            Image("")
                .resizable()
            VStack(alignment: .leading, spacing: 8) {
                ForEach(entry.moments) { moment in
                    HStack(spacing: 16) {
                        Image(uiImage: moment.avatarImage!)
                            .resizable()
                            .frame(width: 40, height: 40)
                            .cornerRadius(20)
                        
                        VStack(alignment: .leading, spacing: 4) {
                            Text("\(moment.userInfoName)·\(moment.enterprisePost)·公司名称")
                                .font(.system(size: 15))
                                .foregroundColor(.white)
                            Text("description")
                                .font(.system(size: 13))
                                .foregroundColor(Color.white.opacity(0.7))
                        }
                        
                    }
                }
            }
        }
        .padding()
        .foregroundColor(.white)
        .background(LinearGradient(gradient: Gradient(colors: [ .blue, .purple ]), startPoint: .leading, endPoint: /*@START_MENU_TOKEN@*/.trailing/*@END_MENU_TOKEN@*/))
        .widgetURL(URL(string: "abcdefg"))
    }
}

最后的效果


还有就是UI部分必须用SwiftUI来实现,一个简单的 Widget Extension 就完成了。

参考文章:

上一篇下一篇

猜你喜欢

热点阅读