我有一个
Image
视图,在屏幕中间显示宽高比为 .fit
的图像(其他元素将显示在图像上方和下方)。然后,对它们应用缩放效果。这对于大多数尺寸较宽的图像效果很好,但其中一张图像在此处看到在 iPhone 16 模拟器上运行时显示屏幕边缘存在间隙,从而导致难看的缩放效果。我的猜测是,我必须检测要显示的图像是否适合屏幕宽度,如果不适合,则在显示之前调整其大小。这是解决问题的唯一方法吗?请指教。
struct FancyViewer: View {
private let imageName = "dragon"
private let animDuration = 5.0
@State private var imageScale: CGFloat = 1.0
var body: some View {
GeometryReader { proxy in
VStack {
Spacer()
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: proxy.size.width, height: proxy.size.width * 1.5)
.scaleEffect(imageScale)
.animation(.linear(duration: animDuration), value: imageScale)
.clipped()
Spacer()
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background {
Image(imageName)
.resizable()
.scaledToFill()
.foregroundStyle(.thinMaterial)
.overlay {
Color.clear
.background(.ultraThinMaterial)
}
.ignoresSafeArea()
}
.onAppear {
imageScale = CGFloat.random(in: 1.0...1.3)
}
}
}
aspectRatio
将尝试调整图像大小以适合您设置的 frame
。如果图像太高而无法适应框架的高度,两侧就会有间隙。
如果您仅使用一个大得离谱的数字作为框架的高度,则只有高得离谱(非常低的宽:高比)图像才能超过该高度并在侧面产生间隙。
此外,要在可用空间内裁剪图像,您应该将图像作为填充可用空间的某些视图的覆盖(例如
Color.clear
),然后裁剪该视图。 clipped
上的 Image
不会执行任何操作,因为 Image
始终适合您给它的框架内。
Spacer()
Color.clear
.overlay {
Image(imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 100000000)
.scaleEffect(imageScale)
.animation(.linear(duration: animDuration), value: imageScale)
}
.clipped()
Spacer()