在SwiftUI中将图像裁剪为正方形

时间:2019-10-08 17:05:31

标签: ios swiftui

我正在尝试将多个单元格彼此相邻放置,其中每个单元格由下面的图像和文本组成。单元格本身应为正方形,并且图像应缩放以填充剩余的空间(剪切图像的一部分)。

首先,我尝试使图像和下面的文本变为正方形。 现在我的问题是,我不知道如何在SwiftUI中正确实现这一目标。使用以下代码时,我可以使其正常工作:

VStack {
    Image(uiImage: recipe.image!)
        .resizable()
        .aspectRatio(contentMode: .fill)
        .frame(width: 200, height: 200, alignment: .center)
        .clipped()
    Text(recipe.name)
}

Image 1 问题是,我必须指定固定的帧大小。我想要的是一种制作单元格的方法,该单元格的纵横比保持1:1,并且可调整大小,因此我可以将它们的动态量放置在彼此相邻的屏幕上。

我也尝试使用

VStack {
    Image(uiImage: recipe.image!)
        .resizable()
        .aspectRatio(1.0, contentMode: .fit)
        .clipped()
    Text(recipe.name)
}

Image 2 这给了我方形图像,可以动态缩放。但是问题在于,图像现在被拉伸以填充正方形,而无法缩放以填充它。

我的下一个想法是将其裁剪为正方形。为此,我首先尝试将其裁剪为圆形(因为显然没有正方形):

VStack {
    Image(uiImage: recipe.image!)
        .resizable()
        .aspectRatio(contentMode: .fit)
        .clipShape(Circle())
    Text(recipe.name)
}

Image 3 但是出于某种奇怪的原因,它并没有真正裁剪图像,而是保留了剩余的空间...

所以我看不到东西吗?还是将图像正方形裁剪为框架修改器的唯一选择?

编辑

为了澄清:我不太在乎文本,也不在乎整个单元格(或者图像是否更简单)为正方形,而不必通过.frame指定其大小,也不必方形原始图像被拉伸以使其适合。

因此,理想的解决方案是VStack是方形的,但是获得方形图像也可以。它应该看起来像图像1,但不必使用.frame修饰符。

2 个答案:

答案 0 :(得分:4)

我认为ZStack可能更适合您的需求,除非文本背后必须透明。在图片上尝试使用这些修饰符。

如果需要保持宽度动态,可以使用Geometry Reader或初始化时传入的参数来研究。 .clipped() modifier使用边界框遮罩视图,因此您需要将其设置为裁剪图像。

        HStack {
            ForEach(0..<3, id: \.self) { index in
                ZStack {
                    GeometryReader { proxy in
                        Image(systemName: "pencil")
                            .resizable()
                            .scaledToFill()
                            .frame(width: proxy.size.width)
                        VStack {
                            Spacer()
                            Text("yes")
                                .frame(width: proxy.size.width)
                                .background(Color.white)
                        }
                    }
                }
                .clipped()
                .aspectRatio(1, contentMode: .fit)
                .border(Color.red)
            }
        }

答案 1 :(得分:2)

它对我有用,但我不知道为什么必须使用cornerRadius ...

import SwiftUI

struct ClippedImage: View {
    let imageName: String
    let width: CGFloat
    let height: CGFloat

    init(_ imageName: String, width: CGFloat, height: CGFloat) {
        self.imageName = imageName
        self.width = width
        self.height = height
    }
    var body: some View {
        ZStack {
            Image(imageName)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: width, height: height)
        }
        .cornerRadius(0) // Necessary for working
        .frame(width: width, height: height)
    }
}

struct ClippedImage_Previews: PreviewProvider {
    static var previews: some View {
        ClippedImage("dishLarge1", width: 100, height: 100)
    }
}

enter image description here