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)
}
}
-
func placeholder(in context: Context) -> GreetingEntryModel
该函数是设置组件默认数据源下 UI样式的 -
func getSnapshot(in context: Context, completion: @escaping (GreetingEntryModel) -> Void)
该函数是预览模式下的默认UI样式 -
func getTimeline(in context: Context, completion: @escaping (Timeline<GreetingEntryModel>) -> Void)
核心函数,我们通过该函数实现数据的网络请求,及数据的刷新时间间隔
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
就完成了。
网友评论