问题描述
我正在尝试编写一个带有 UIImage 的公共初始化程序,但我想同时允许从照片(或以其他方式绘制)或使用 SF 符号制作的普通的、实际的 UIImage,但我很难过为什么SF符号模糊。我错过了什么?
这是我得到的代码:
struct TempuIImageView: View {
var defaultimage: UIImage = UIImage(systemName: "globe")!
var defaultimageString: String = "globe"
var body: some View {
vstack {
Image(uiImage: defaultimage)
.resizable()
.scaledToFill()
.aspectRatio(contentMode: .fit)
Image(systemName: defaultimageString)
.resizable()
.scaledToFill()
.aspectRatio(contentMode: .fit)
}
.padding()
}
}
@State private var displayedImage: UIImage?
...
private var displayImage: some View {
Image(uiImage: displayedImage!)
.resizable()
.frame(maxWidth: .infinity,maxHeight: .infinity,alignment: .center)
.scaledToFill()
.aspectRatio(contentMode: .fit)
.clipShape(Circle())
.shadow(radius: 4)
}
但是displayedImage 可以是UIImage 或SF 符号。
解决方法
当您使用 Image(systemName:)
时,系统会使用矢量图形绘制到屏幕上,从而产生清晰、不模糊的渲染效果。
然而,UIImage
,包括,看起来 UIImage(systemName:)
是一个位图图像,在一个设定的分辨率。如果您将其放大(就像您在第二个代码块中所做的那样),则会变得模糊,因为您没有获得矢量图形的好处。
使用类似以下的模式将允许您有条件地显示 Image(uiImage:)
或 Image(systemName:)
,并且仍然为每个使用相同的修饰符集:
struct ContentView: View {
@State var displayedImage : UIImage?
var imageToDisplay: Image {
if let displayedImage = displayedImage {
return Image(uiImage: displayedImage)
} else {
return Image(systemName: "camera.circle")
}
}
var body: some View {
imageToDisplay
.resizable()
.scaledToFill()
.aspectRatio(contentMode: .fit)
.frame(width: 400,height: 400)
}
}