如何将图像剪辑到惰性网格内的正方形?(SwiftUI)

DPM*_*itu 4 ios swiftui

这不是这个问题的重复。

您将在下方看到一个包含 3 列的矩形网格。我正在尝试使用图像实现相同的效果。图像应该被剪裁,否则不会出现拉伸或扭曲。

这是我如何实现矩形网格...

// In my view struct...

private let threeColumnGrid = [
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
]

// In my body...

LazyVGrid(columns: threeColumnGrid, alignment: .center) {
    ForEach(model.imageNames, id: \.self) { imageName in
        Rectangle()
            .foregroundColor(.red)
            .aspectRatio(1, contentMode: .fit)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我想要使用矩形的布局...

矩形网格图像

这是我的目标...

照片应用截图

更新:

如果我这样做...

Image(item)
    .resizable()
    .aspectRatio(1, contentMode: .fit)
Run Code Online (Sandbox Code Playgroud)

如果图像的纵横比不是 1:1,则图像会失真。例如,下面屏幕截图中的圆形图像应该是一个完美的圆形。

失败示例 1

cho*_*lot 13

我发现 DPMitu 的答案不是使图像居中(它与前缘对齐)。

这对我来说效果更好(也不需要 GeometryReader):

  LazyVGrid(columns: columns, spacing: 30) {
       ForEach(items) { item in
           Image("IMG_0044")
               .resizable()
               .scaledToFill()
               .frame(minWidth: 0, maxWidth: .infinity)
               .aspectRatio(1, contentMode: .fill)
               .clipped() //Alternatively you can use cornerRadius for the same effect
               //.cornerRadius(10)
       }
  }
    
Run Code Online (Sandbox Code Playgroud)

我在这里找到了它https://www.appcoda.com/learnswiftui/swiftui-gridlayout.html大约在页面的一半处

  • 要对肖像图像实现相同的效果,请将 .frame() 行更改为 .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)。只要父视图的框架是方形的,它就应该以这种方式处理横向和纵向。 (4认同)
  • 这似乎无法实现肖像图像的方形效果...... (2认同)

DPM*_*itu 8

我找到了解决方案。

定义列数...

// Somewhere in my view struct
private let threeColumnGrid = [
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
]
Run Code Online (Sandbox Code Playgroud)

创建网格...

LazyVGrid(columns: threeColumnGrid, alignment: .center) {
    ForEach(model.imageNames, id: \.self) { item in
        GeometryReader { gr in
            Image(item)
                .resizable()
                .scaledToFill()
                .frame(height: gr.size.width)
        }
        .clipped()
        .aspectRatio(1, contentMode: .fit)
    }
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*lme 8

有些人询问图像是否偏离中心。您可以通过添加行来调整它.position(x: gr.frame(in: .local).midX, y: gr.frame(in: .local).midY)。所以完整的事情是:

列数

// Somewhere in my view struct
private let threeColumnGrid = [
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
    GridItem(.flexible(minimum: 40)),
]
Run Code Online (Sandbox Code Playgroud)

创建网格

LazyVGrid(columns: threeColumnGrid, alignment: .center) {
    ForEach(model.imageNames, id: \.self) { item in
        GeometryReader { gr in
            Image(item)
                .resizable()
                .scaledToFill()
                .frame(height: gr.size.width)
                .position(x: gr.frame(in: .local).midX, y: gr.frame(in: .local).midY)
        }
        .clipped()
        .aspectRatio(1, contentMode: .fit)
    }
}
Run Code Online (Sandbox Code Playgroud)


Mur*_*tam 5

没有GeometryReader正确缩放的图像的解决方案。

struct ContentView: View {

    private let columns = [
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
    ]

    private let imageNames = ["image0", "image1", "image2", "image3", "image4"];

    var body: some View {
        LazyVGrid(columns: columns, content: {
            ForEach(imageNames, id: \.self) { name in
                Color.clear
                    .background(Image(name)
                                    .resizable()
                                    .scaledToFill()
                    )
                    .aspectRatio(1, contentMode: .fill)
                    .clipped()
                    .contentShape(Rectangle()) // <-- this is important to fix gesture recognition
            }
        })
    }
}
Run Code Online (Sandbox Code Playgroud)