Image+GeometryReader를 사용하여 AspectFill+clipToBounds 재현

8161 단어 SwiftSwiftUI
htps : // 메이 m. 코 m / @ ぇ ん b
이 기사를 참고로 구현했습니다.
GeometryReader(content: { geometry in
    Image(uiImage: image)
        .resizable()
        .scaledToFill()
        .frame(width: geometry.size.width, height: geometry.size.height)
})
    .aspectRatio(1, contentMode: .fit)

위의 기사와의 차이점은 GeometryReader의 Image 속성에 .frame 에서 GeometryReader의 크기를 전달합니다. 이미지에 프레임을 전달하면 GeometryReader의 표시 영역에 scaledToFill의 크기가 조정됩니다. 따라서 종횡비를 고정하면서 중앙 맞춤으로 임의의 종횡비로 클립할 수 있게 됩니다.

이 방법의 장점으로, 자식 요소로 크기가 결정되는 것이 아니라 크기는 부모 요소 측에서 제공된 표시 가능 영역에 맞추어 리사이즈하므로 LazyVGrid 등에서 사용할 때 등에 크기를 고정화할 필요가 없어집니다. .

샘플 코드



gist
struct ProductGridCell: View {
    let name: String
    let price: Int
    let image: UIImage
    var body: some View {
        VStack(alignment: .leading, spacing: 3) {
            GeometryReader(content: { geometry in
                Image(uiImage: image)
                    .resizable()
                    .scaledToFill()
                    .frame(width: geometry.size.width, height: geometry.size.height)
            })
            .aspectRatio(1, contentMode: .fit)
            .clipShape(RoundedRectangle(cornerRadius: 4))
            Text(name)
                .foregroundColor(.primary)
                .font(.caption)
            Text(\(price)")
                .font(.caption2)
                .foregroundColor(.secondary)
        }
    }
}

struct ProductGridCell_Previews: PreviewProvider {
    static var previews: some View {
        ScrollView {
            LazyVGrid(columns: [GridItem(), GridItem(), GridItem()], content: {
                ForEach(0..<20) { _ in
                    ProductGridCell(name: "どら焼き", price: 300, image: UIImage(imageLiteralResourceName: "product"))
                }
            })
                .padding()
        }
    }
}


좋은 웹페이지 즐겨찾기