這個是產(chǎn)品要求的效果圖
廢話不多說,直接上代碼借浊,通過代碼一步步的對小組件進行更深的了解和體會
//
// ClockTwoWidget.swift
// ClockTwoWidget
//
// Created by Bron on 2020/9/26.
//
import WidgetKit
import SwiftUI
import YYCategories
import SwiftDate
struct TwoProvider: TimelineProvider {
func placeholder(in context: Context) -> TwoSimpleEntry {
// let currentDate = Date().addingTimeInterval(8*60*60)
let model = self.getModel()
return TwoSimpleEntry(date: Date(), model: model)
}
func getSnapshot(in context: Context, completion: @escaping (TwoSimpleEntry) -> ()) {
let model = self.getModel()
let entry = TwoSimpleEntry(date: Date(), model: model)
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [TwoSimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
for secondOffset in 0 ..< 2 {
let currentDate = Date()
let model = self.getModel()
let entryDate = Calendar.current.date(byAdding: .minute, value: secondOffset, to: currentDate)!
let entry = TwoSimpleEntry(date: entryDate,model: model)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
func getModel()->Model{
let currentDate = Date().addingTimeInterval(8*60*60)
let hour = currentDate.toFormat("HH")
let hourTime = Int(hour) ?? 0
let hourTimeStr = hourTime > 12 ? hourTime - 12 : hourTime
let ampmStr = hourTime > 12 ? "PM" : "AM"
let sharedDefaults = UserDefaults(suiteName: "group.com.XXXX.XXXX")
let imgBase64Str = sharedDefaults?.value(forKey: "smallClock2bgImage") as? String ?? ""
let decodeImageData = NSData(base64Encoded: imgBase64Str, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)
let decodeImage = UIImage(data: decodeImageData as! Data) ?? UIImage()
let bgImage = Image.init(uiImage: decodeImage)
let bgColorStr = sharedDefaults?.value(forKey: "smallClock2Color") as? String ?? "#D9DEED"
let week = currentDate.weekday
//middleWidget
let middlebgColorStr = sharedDefaults?.value(forKey: "middleClock2Color") as? String ?? "#D9DEED"
let middleimgBase64Str = sharedDefaults?.value(forKey: "middleClock2bgImage") as? String ?? ""
let middledecodeImageData = NSData(base64Encoded: middleimgBase64Str, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)
let middledecodeImage = UIImage(data: middledecodeImageData as! Data) ?? UIImage()
let middlebgImage = Image.init(uiImage: middledecodeImage)
//large
let largebgColorStr = sharedDefaults?.value(forKey: "largeClock2Color") as? String ?? "#D9DEED"
let largeimgBase64Str = sharedDefaults?.value(forKey: "largeClock2bgImage") as? String ?? ""
let largedecodeImageData = NSData(base64Encoded: largeimgBase64Str, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)
let largedecodeImage = UIImage(data: largedecodeImageData as! Data) ?? UIImage()
let largebgImage = Image.init(uiImage: largedecodeImage)
let model = Model(bgImage: bgImage, amPmStr: ampmStr, weekIndex: week, isImgBg: false ,hourTimeStr: "\(hourTimeStr)",bgImageColorStr: bgColorStr, middlebgImage: middlebgImage, middlebgImageColorStr: middlebgColorStr, currentDate: currentDate,largebgImage: largebgImage,largebgImageColorStr: largebgColorStr)
return model
}
}
struct Model {
let bgImage:Image
let amPmStr: String
let weekIndex: Int
let isImgBg: Bool
let hourTimeStr:String
let bgImageColorStr:String
let middlebgImage:Image
let middlebgImageColorStr:String
let currentDate: Date
let largebgImage:Image
let largebgImageColorStr:String
}
struct ClockTwoWidgetEntryView : View {
@Environment(\.widgetFamily) var yfamily: WidgetFamily
var entry: TwoProvider.Entry
var body: some View {
if yfamily == .systemSmall {
VStack(alignment: .center, spacing: 30.0, content: {
Group {
Text("\(entry.date.toFormat("yyyy-MM-dd"))").frame(width: 95, height: 20, alignment: .center).foregroundColor(.black).font(Font.custom("蘋方-簡 常規(guī)體", size: 13))
}
.background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.5) ?? UIColor.init()))
.cornerRadius(5).offset(CGSize(width: 0.0, height: 30.0))
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: 10, content: {
Text("\(entry.model.currentDate.toFormat("HH"))").font(Font.custom("zcool-gdh", size: 32)).frame(width: 55, height: 70, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.6) ?? UIColor())).cornerRadius(10)
Text(":").font(Font.custom("蘋方-簡 中粗體", size: 32))
Text("\(entry.model.currentDate.toFormat("mm"))").font(Font.custom("zcool-gdh", size: 32)).frame(width: 55, height: 70, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.6) ?? UIColor())).cornerRadius(10)
}).foregroundColor(.black).offset(CGSize(width: 0.0, height: 10.0))
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: 0, content: {
HStack{
Text("一").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 2 ? 1.0 : 0.2) ?? UIColor()))
Text("二").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 3 ? 1.0 : 0.2) ?? UIColor()))
Text("三").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 4 ? 1.0 : 0.2) ?? UIColor()))
Text("四").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 5 ? 1.0 : 0.2) ?? UIColor()))
Text("五").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 6 ? 1.0 : 0.2) ?? UIColor()))
Text("六").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 7 ? 1.0 : 0.2) ?? UIColor()))
Text("日").frame(width: 13, height: 20, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 1 ? 1.0 : 0.2) ?? UIColor()))
}.font(Font.custom("蘋方-簡 常規(guī)體", size: 12)).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.5) ?? UIColor())).cornerRadius(5)
}).frame(minWidth: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, idealWidth: 0, maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, minHeight: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, idealHeight: 0, maxHeight: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
Spacer()
}).background(entry.model.bgImage.resizable()).background(Color(UIColor(hexString: entry.model.bgImageColorStr) ?? UIColor())).widgetURL(URL(string: "Clock-small-2/https://www.baidu.com/small"))
}
if yfamily == .systemMedium {
Link(destination: URL(string: "Clock-meduim-2/https://www.baidu.com/medium/1")!) {
VStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: /*@START_MENU_TOKEN@*/nil/*@END_MENU_TOKEN@*/, content: {
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: nil, content: {
Text("\(entry.model.hourTimeStr)").font(Font.custom("zihun64hao-mengquruantangti", size: 100))
Text(":").font(Font.custom("zihun64hao-mengquruantangti", size: 100))
Text("\(entry.date.toFormat("mm"))").font(Font.custom("zihun64hao-mengquruantangti", size: 100))
}).foregroundColor(.white).offset(x: 0, y: 5)
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: /*@START_MENU_TOKEN@*/nil/*@END_MENU_TOKEN@*/, content: {
Spacer()
})
Text("祝你們幸福是假的拴竹,祝你幸福是真的扫俺。").font(Font.custom("zihun64hao-mengquruantangti", size: 14)).foregroundColor(.white).offset(x: 10, y: -10.0/*@END_MENU_TOKEN@*/)
Text("——網(wǎng)易云《我到外地去看你》").font(Font.custom("zihun64hao-mengquruantangti", size: 14)).foregroundColor(.white).offset(x: 30, y: -10.0/*@END_MENU_TOKEN@*/)
Spacer()
}).background(entry.model.middlebgImage.resizable()).background(Color(UIColor(hexString: entry.model.middlebgImageColorStr) ?? UIColor()))
}
}
if yfamily == .systemLarge {
Link(destination: URL(string: "Clock-large-2/https://www.baidu.com/large/1")!) {
VStack(alignment: .center, spacing: 30.0, content: {
Group {
Text("\(entry.date.toFormat("yyyy-MM-dd"))").frame(width: 300, height: 50, alignment: .center).foregroundColor(.black).font(Font.custom("蘋方-簡 常規(guī)體", size: 20))
}
.background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.5) ?? UIColor.init()))
.cornerRadius(10).offset(CGSize(width: 0.0, height: 20.0))
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: 10, content: {
Text("\(entry.model.currentDate.toFormat("HH"))").font(Font.custom("zcool-gdh", size: 77)).frame(width: 130, height: 175,alignment: .center).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.6) ?? UIColor())).cornerRadius(10)
Text(":").font(Font.custom("蘋方-簡 中粗體", size: 77))
Text("\(entry.model.currentDate.toFormat("mm"))").font(Font.custom("zcool-gdh", size: 77)).frame(width: 130, height: 175, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.6) ?? UIColor())).cornerRadius(10)
}).foregroundColor(.black).offset(CGSize(width: 0.0, height: 10.0))
HStack(alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/, spacing: 0, content: {
HStack{
Text("").frame(width: -1, height: 30, alignment: .center)
Text("一").frame(width: 34, height: 40, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 2 ? 1.0 : 0.2) ?? UIColor()))
Text("二").frame(width: 34, height: 27, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 3 ? 1.0 : 0.2) ?? UIColor()))
Text("三").frame(width: 34, height: 27, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 4 ? 1.0 : 0.2) ?? UIColor()))
Text("四").frame(width: 34, height: 27, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 5 ? 1.0 : 0.2) ?? UIColor()))
Text("五").frame(width: 34, height: 27, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 6 ? 1.0 : 0.2) ?? UIColor()))
Text("六").frame(width: 34, height: 27, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 7 ? 1.0 : 0.2) ?? UIColor()))
Text("日").frame(width: 34, height: 27, alignment: .center).foregroundColor(Color(UIColor(hexString: "#000000")?.withAlphaComponent(entry.model.weekIndex == 1 ? 1.0 : 0.2) ?? UIColor()))
Text("").frame(width: -1, height: 30, alignment: .center)
}.font(Font.custom("蘋方-簡 常規(guī)體", size: 12)).background(Color.init(UIColor(hexString: "#FFFFFF")?.withAlphaComponent(0.5) ?? UIColor())).cornerRadius(5)
}).frame(minWidth: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, idealWidth: 0, maxWidth: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, minHeight: /*@START_MENU_TOKEN@*/0/*@END_MENU_TOKEN@*/, idealHeight: 0, maxHeight: /*@START_MENU_TOKEN@*/.infinity/*@END_MENU_TOKEN@*/, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/).offset(x: 0, y: /*@START_MENU_TOKEN@*/10.0/*@END_MENU_TOKEN@*/)
Spacer()
}).background(entry.model.largebgImage.resizable()).background(Color(UIColor(hexString: entry.model.largebgImageColorStr) ?? UIColor()))
}
}
}
}
@main
struct ClockTwoWidget: Widget {
let kind: String = "ClockTwoWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: TwoProvider()) { entry in
ClockTwoWidgetEntryView(entry: entry)
}
.configurationDisplayName("ClockTwoWidget")
.description("This is an example widget.")
}
}
struct ClockTwoWidget_Previews: PreviewProvider {
static var previews: some View {
ClockTwoWidgetEntryView(entry: TwoSimpleEntry(date: Date().addingTimeInterval(8*60*60),model: Model(bgImage: Image(""), amPmStr: "PM", weekIndex: 2, isImgBg: false ,hourTimeStr: "04",bgImageColorStr: "#D9DEED", middlebgImage: Image(""), middlebgImageColorStr: "#D9DEED", currentDate: Date(),largebgImage: Image(""),largebgImageColorStr: "#D9DEED")))
.previewContext(WidgetPreviewContext(family: .systemSmall))
ClockTwoWidgetEntryView(entry: TwoSimpleEntry(date: Date().addingTimeInterval(8*60*60),model: Model(bgImage: Image(""), amPmStr: "PM", weekIndex: 2, isImgBg: false ,hourTimeStr: "04",bgImageColorStr: "#D9DEED", middlebgImage: Image(""), middlebgImageColorStr: "#D9DEED", currentDate: Date(),largebgImage: Image(""),largebgImageColorStr: "#D9DEED")))
.previewContext(WidgetPreviewContext(family: .systemMedium))
ClockTwoWidgetEntryView(entry: TwoSimpleEntry(date: Date().addingTimeInterval(8*60*60),model: Model(bgImage: Image(""), amPmStr: "PM", weekIndex: 1, isImgBg: false ,hourTimeStr: "04",bgImageColorStr: "#D9DEED", middlebgImage: Image(""), middlebgImageColorStr: "#D9DEED", currentDate: Date(),largebgImage: Image(""),largebgImageColorStr: "#D9DEED")))
.previewContext(WidgetPreviewContext(family: .systemLarge))
}
}