【发布时间】:2021-02-07 11:01:47
【问题描述】:
我想做的是让用户选择widget background 是从http 还是gradient background 拍摄的图像。
我目前有以下笔记结构,但我无法让它工作。
所以typeBg必须有一个默认值,如果没有通过它应该取默认值。
image和bgColors的值必须是可选参数。
struct Note: Identifiable, Codable {
let title: String
let message: String
let image: String?
let bgColors: [Color?]//[String?]
let typeBg: String? = "color"
var id = UUID()
}
但我只得到错误,在结构注:
类型'Note'不符合协议'Decodable'
类型'Note'不符合协议'Encodable'
我想做的是:
如果结构的typeBg == 'url',那么我将image 作为一个url。
如果结构的typeBg == 'gradient',那么我将bgColors 作为值,这是一个颜色数组。
内容视图:
SmallWidget(entry: Note(title: "Title", message: "Mex", bgColors: bgColors, typeBg: "gradient"))
小部件:
struct SmallWidget: View {
var entry: Note
@Environment(\.colorScheme) var colorScheme
func bg() -> AnyView { //<- No work
switch entry.typeBg {
case "url":
return AnyView(NetworkImage(url: URL(string: entry.image))
case "gradient":
return AnyView(
LinearGradient(
gradient: Gradient(colors: entry.bgColors),
startPoint: .top,
endPoint: .bottom)
)
default:
return AnyView(Color.blue)
}
var body: some View {
GeometryReader { geo in
VStack(alignment: .center){
Text(entry.title)
.font(.title)
.bold()
.minimumScaleFactor(0.5)
.foregroundColor(.white)
.shadow(
color: Color.black,
radius: 1.0,
x: CGFloat(4),
y: CGFloat(4))
Text(entry.message)
.foregroundColor(Color.gray)
.shadow(
color: Color.black,
radius: 1.0,
x: CGFloat(4),
y: CGFloat(4))
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.edgesIgnoringSafeArea(.all)
}
.background(bg)
//.background(gradient)
//.background(NetworkImage(url: URL(string: entry.image)))
}
}
struct NetworkImage: View {
public let url: URL?
var body: some View {
Group {
if let url = url, let imageData = try? Data(contentsOf: url),
let uiImage = UIImage(data: imageData) {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fill)
}
else {
ProgressView()
}
}
}
}
【问题讨论】:
标签: swift swiftui widget widgetkit