如何根据可选的 Binding<Image> 在此 SwiftUI @ViewBuilder 中初始化 Bool?
How do I initialize a Bool in this SwiftUI @ViewBuilder based on an optional Binding<Image>?
我的目标是使用三元运算符为图像添加阴影,但如果视图使用默认图像,不会添加阴影。
这是我的代码:
import SwiftUI
struct ImageDisplay: View {
@State private var defaultImage: Image = Image(systemName: "person.crop.circle.fill")
private var defaultText: String = "Add picture"
private var hasShadow: Bool = true
private var text: String?
private var image: Binding<Image>?
public init(_ text: String, image: Binding<Image>) {
self.init(
text: .some(text),
image: image
)
}
public init(image: Binding<Image>) {
self.init(
text: nil,
image: image
)
}
public init() {
self.init(
text: nil,
image: nil
)
}
private init(text: String?, image: Binding<Image>?) {
self.text = text
self.image = image
}
private struct InternalImageDisplay: View {
var text: String
var hasShadow: Bool /// NOT CERTAIN WHERE THIS BELONGS, OR IF IT GOES HERE ...
@Binding var image: Image
@ViewBuilder
var body: some View {
VStack {
image
.imageDisplayStyle()
.shadow(radius: hasShadow ? 4.0 : 0.0) /// HERE IS WHERE I'LL USE IT...
Button(action: {
//TODO: - Code to present image picker.
}, label: {
Text(text)
})
}
}
}
var body: some View {
InternalImageDisplay(
text: text ?? defaultText,
hasShadow: false, /// THIS IS NOT WORKING IN ANY IMPLEMENTATION ...
image: image ?? $defaultImage
)
}
}
我也有 Image
的扩展:
import SwiftUI
extension Image {
func imageDisplayStyle() -> some View {
return self
.resizable()
.scaledToFill()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.aspectRatio(contentMode: .fit)
.clipShape(Circle())
.foregroundColor(.gray)
}
}
我正在尝试让看起来像这样的代码能够很好地工作并且它很棒,除了阴影布尔:
struct ContentView: View {
@State private var image = Image("img1")
@State private var defaultImage: Bool = true
var body: some View {
VStack (spacing: 48) {
// no binding
ImageDisplay()
// binding
ImageDisplay("Select image", image: $image)
ImageDisplay(image: $image)
}
.frame(width: 190)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
在您的初始化程序中,您可以根据是否传入图像参数来设置hasShadow
。
然后,您可以将其传递给您的 InternalImageDisplay
。
出于测试目的,我让阴影更明显一些:
struct ImageDisplay: View {
@State private var defaultImage: Image = Image(systemName: "person.crop.circle.fill")
private var defaultText: String = "Add picture"
private var hasShadow: Bool = true
private var text: String?
private var image: Binding<Image>?
public init(_ text: String, image: Binding<Image>) {
self.init(
text: text,
image: image,
hasShadow: true //<-- Here
)
}
public init(image: Binding<Image>) {
self.init(
text: nil,
image: image,
hasShadow: true //<-- Here
)
}
public init() {
self.init(
text: nil,
image: nil,
hasShadow: false //<-- Here
)
}
private init(text: String?, image: Binding<Image>?, hasShadow : Bool) { //<-- Here
self.text = text
self.image = image
self.hasShadow = hasShadow //<-- Here
}
private struct InternalImageDisplay: View {
var text: String
var hasShadow: Bool //<-- This gets passed in as a prop
@Binding var image: Image
@ViewBuilder
var body: some View {
VStack {
image
.imageDisplayStyle()
.shadow(color: Color.green, radius: hasShadow ? 10.0 : 0) //<-- Here (now it's green for testing)
Button(action: {
//TODO: - Code to present image picker.
}, label: {
Text(text)
})
}
}
}
var body: some View {
InternalImageDisplay(
text: text ?? defaultText,
hasShadow: hasShadow, //<-- Here
image: image ?? $defaultImage
)
}
}
我的目标是使用三元运算符为图像添加阴影,但如果视图使用默认图像,不会添加阴影。
这是我的代码:
import SwiftUI
struct ImageDisplay: View {
@State private var defaultImage: Image = Image(systemName: "person.crop.circle.fill")
private var defaultText: String = "Add picture"
private var hasShadow: Bool = true
private var text: String?
private var image: Binding<Image>?
public init(_ text: String, image: Binding<Image>) {
self.init(
text: .some(text),
image: image
)
}
public init(image: Binding<Image>) {
self.init(
text: nil,
image: image
)
}
public init() {
self.init(
text: nil,
image: nil
)
}
private init(text: String?, image: Binding<Image>?) {
self.text = text
self.image = image
}
private struct InternalImageDisplay: View {
var text: String
var hasShadow: Bool /// NOT CERTAIN WHERE THIS BELONGS, OR IF IT GOES HERE ...
@Binding var image: Image
@ViewBuilder
var body: some View {
VStack {
image
.imageDisplayStyle()
.shadow(radius: hasShadow ? 4.0 : 0.0) /// HERE IS WHERE I'LL USE IT...
Button(action: {
//TODO: - Code to present image picker.
}, label: {
Text(text)
})
}
}
}
var body: some View {
InternalImageDisplay(
text: text ?? defaultText,
hasShadow: false, /// THIS IS NOT WORKING IN ANY IMPLEMENTATION ...
image: image ?? $defaultImage
)
}
}
我也有 Image
的扩展:
import SwiftUI
extension Image {
func imageDisplayStyle() -> some View {
return self
.resizable()
.scaledToFill()
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.aspectRatio(contentMode: .fit)
.clipShape(Circle())
.foregroundColor(.gray)
}
}
我正在尝试让看起来像这样的代码能够很好地工作并且它很棒,除了阴影布尔:
struct ContentView: View {
@State private var image = Image("img1")
@State private var defaultImage: Bool = true
var body: some View {
VStack (spacing: 48) {
// no binding
ImageDisplay()
// binding
ImageDisplay("Select image", image: $image)
ImageDisplay(image: $image)
}
.frame(width: 190)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
在您的初始化程序中,您可以根据是否传入图像参数来设置hasShadow
。
然后,您可以将其传递给您的 InternalImageDisplay
。
出于测试目的,我让阴影更明显一些:
struct ImageDisplay: View {
@State private var defaultImage: Image = Image(systemName: "person.crop.circle.fill")
private var defaultText: String = "Add picture"
private var hasShadow: Bool = true
private var text: String?
private var image: Binding<Image>?
public init(_ text: String, image: Binding<Image>) {
self.init(
text: text,
image: image,
hasShadow: true //<-- Here
)
}
public init(image: Binding<Image>) {
self.init(
text: nil,
image: image,
hasShadow: true //<-- Here
)
}
public init() {
self.init(
text: nil,
image: nil,
hasShadow: false //<-- Here
)
}
private init(text: String?, image: Binding<Image>?, hasShadow : Bool) { //<-- Here
self.text = text
self.image = image
self.hasShadow = hasShadow //<-- Here
}
private struct InternalImageDisplay: View {
var text: String
var hasShadow: Bool //<-- This gets passed in as a prop
@Binding var image: Image
@ViewBuilder
var body: some View {
VStack {
image
.imageDisplayStyle()
.shadow(color: Color.green, radius: hasShadow ? 10.0 : 0) //<-- Here (now it's green for testing)
Button(action: {
//TODO: - Code to present image picker.
}, label: {
Text(text)
})
}
}
}
var body: some View {
InternalImageDisplay(
text: text ?? defaultText,
hasShadow: hasShadow, //<-- Here
image: image ?? $defaultImage
)
}
}