为什么在SwiftUI中调整大小的PDF会产生锐利的边缘? [英] Why do PDFs resized in SwiftUI getting sharp edges?
问题描述
我尝试使用Xcode 11.4和iOS 13.4在启用SwiftUI的应用程序中包含pdf.但是,当我调整pdf大小时,它会出现卷曲的边缘.我提供了两个版本的pdf:一个大pdf(icon.pdf
)和一个小pdf(icon_small.pdf
).当我调整icon.pdf
的大小时,它会得到开始边缘,而icon_small.pdf
时会得到平滑的边缘.这个问题也适用于我尝试过的所有其他PDF.
I try to include a pdf in my SwiftUI enabled app using Xcode 11.4 and iOS 13.4. However, when I resize the pdf, it gets crips edges. I have included two versions of the pdf: One large pdf (icon.pdf
) and one small pdf (icon_small.pdf
). When I resize icon.pdf
it gets start edges, while icon_small.pdf
gets smooth edges. The issue applies to all other pdfs I have tried as well.
这是我的代码:
struct ContentView: View {
var body: some View {
VStack {
Spacer()
Text("icon.pdf:")
Image("icon")
.resizable()
.renderingMode(.template)
.aspectRatio(contentMode: .fit)
.frame(width: 27.0, height: 27.0)
Spacer()
Text("icon_small.pdf:")
Image("icon_small")
Spacer()
}
}
}
icon.pdf
和icon_small.pdf
都具有以下资产设置:
Both icon.pdf
and icon_small.pdf
have the following asset settings:
- 渲染为:模板图像
- 调整大小:保留矢量数据
- 设备:通用
- 秤:单秤
可在此处找到pdf文件:
The pdfs are available here:
- http://simensolbakken.com/public/stackoverflow/icon.pdf
- http://simensolbakken.com/public/stackoverflow/icon_small.pdf
- http://simensolbakken.com/public/stackoverflow/icon.pdf
- http://simensolbakken.com/public/stackoverflow/icon_small.pdf
推荐答案
我使用您提供的图像对两个矢量图像进行了并排比较:
I did a side by side comparison for both vector images using the ones you provided:
- http://simensolbakken.com/public/stackoverflow/icon.pdf
- http://simensolbakken.com/public/stackoverflow/icon_small.pdf
起初,我使用了SwiftUI
的内置Image
,并且如上所述,它们在极端情况下的表现都很差:
At first, I used SwiftUI
's inbuilt Image
and as mentioned, both performed badly at their extreme ends:
- 按比例缩小大图像时会出现锐利的边缘
- 小图像在放大时变得模糊
起初我以为可能是您的pdf矢量,所以我使用了我知道在以前的项目中效果很好的矢量,但是我遇到了同样的问题.
认为这是一个UIImage
问题,我使用了SwiftUI
的Image(uiImage:)
但同样的问题.
At first I thought it might be your pdf vectors so I used ones that I know have worked well in my previous projects, but I got the same issues.
Thinking it to be a UIImage
issue, I used SwiftUI
s Image(uiImage:)
but same problem.
最后一个猜测是图像容器,并且知道UIImageView
可以很好地处理矢量图像,因此使UIViewRepresentable
包裹UIImageView
似乎可以解决此问题.现在看来,这可能是一种解决方法.
Last guess was the image container, and knowing that UIImageView
has handled vector images well, getting UIViewRepresentable
to wrap the UIImageView
seems to solve this issue. And for now it looks like a possible workaround.
struct MyImageView: UIViewRepresentable {
var name: String
var contentMode: UIView.ContentMode = .scaleAspectFit
var tintColor: UIColor = .black
func makeUIView(context: Context) -> UIImageView {
let imageView = UIImageView()
imageView.setContentCompressionResistancePriority(.fittingSizeLevel,
for: .vertical)
return imageView
}
func updateUIView(_ uiView: UIImageView, context: Context) {
uiView.contentMode = contentMode
uiView.tintColor = tintColor
if let image = UIImage(named: name) {
uiView.image = image
}
}
}
这会丢失一些SwiftUI
Image
修饰符(您仍然具有普通的View
修饰符),但是您始终可以像上面所示那样传入某些参数,例如contentMode
和tintColor
.如果需要,添加更多并进行相应处理.
This loses some SwiftUI
Image
modifiers (you still have normal View
modifiers) but you can always pass in some parameters such as contentMode
and tintColor
as shown above. Add more if needed and handle accordingly.
struct ContentView: View {
var body: some View {
VStack {
MyImageView(name: "icon", //REQUIRED
contentMode: .scaleAspectFit, //OPTIONAL
tintColor: .black /*OPTIONAL*/)
.frame(width: 27, height: 27)
MyImageView(name: "icon_small", //REQUIRED
contentMode: .scaleAspectFit, //OPTIONAL
tintColor: .black /*OPTIONAL*/)
.frame(width: 27, height: 27)
}
}
}
现在所有这些都是推测,但看起来SwiftUI
似乎将矢量图像视为PNG
.
Now this is all speculation but it looks as though SwiftUI
treats vector images as a PNG
.
下面的示例是对UIKit
的UIImageView
和SwiftUI
的Image
中呈现的大小矢量图像的简单并排比较.
The following example is a simple side by side comparison of the small and large vector images rendered in UIKit
's UIImageView
and SwiftUI
's Image
.
struct ContentView: View {
let (largeImage, smallImage) = ("icon", "icon_small")
let range = stride(from: 20, to: 320, by: 40).map { CGFloat($0) }
var body: some View {
List(range, id: \.self) { (side) in
ScrollView(.horizontal) {
VStack(alignment: .leading) {
Text(String(format: "%gx%g", side, side))
HStack {
VStack {
Text("UIKit")
MyImageView(name: self.smallImage)
.frame(width: side, height: side)
MyImageView(name: self.largeImage)
.frame(width: side, height: side)
}
VStack {
Text("SwiftUI")
Image(self.smallImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: side)
Image(self.largeImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: side)
}
}
}
}
}
}
}
结果:
- 第一行;左:
UIImageView
中的小图像
- 第一行;右:
SwiftUI
Image
中的小图片
- 底行;左:
UIImageView
中的大图像
- 底行;右:
SwiftUI
Image
中的大图像
- Top row; Left : Small Image in
UIImageView
- Top row; Right : Small Image in
SwiftUI
Image
- Bottom row; Left : Large Image in
UIImageView
- Bottom row; Right : Large Image in
SwiftUI
Image
UIKit
的UIImageView
具有一致的性能,而SwiftUI
的Image
遇到问题.
UIKit
's UIImageView
has consistent performace while SwiftUI
's Image
is having trouble.
这篇关于为什么在SwiftUI中调整大小的PDF会产生锐利的边缘?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!