如何避免LazyVGrid单元格中的图片被挤压变形?
SwiftUI网格单元格图片避免挤压的优化方案
我做了一个简单的网格视图,每个单元格内显示一张方形图片,下方附带几行文字。目标是让图片完全填充方形区域,只做裁剪处理,绝对不能出现挤压变形的情况。目前效果接近预期,但图片还是会出现挤压问题:
(注:原问题附带图片显示部分单元格图片被横向挤压变形)
初始实现代码
struct CollectionsView: View { @StateObject var viewModel: CollectionsViewModel = CollectionsViewModel() var body: some View { ScrollView { let columns = [GridItem(spacing: 16), GridItem(spacing: 16)] LazyVGrid(columns: columns) { ForEach(viewModel.collections) { collection in Button { print("进入合集页面") } label: { CollectionsViewCell(collection: collection) } .onAppear { if collection == viewModel.collections.last { Task { try await viewModel.getCollections(nextPage: true) } } } } } .padding(16) } .navigationTitle("合集") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { // 更多按钮点击事件 } label: { Image(systemName: "ellipsis.circle") } } } } } struct CollectionsViewCell: View { let collection: HashableCollection var body: some View { VStack(alignment: .leading) { AsyncImage(url: URL(string: collection.imageUrlString)) { image in image .resizable() .aspectRatio(1, contentMode: .fill) } placeholder: { Rectangle() } .background(.secondary) .clipped() .cornerRadius(11) Text(collection.title) .lineLimit(1) .truncationMode(.tail) Text("\(collection.itemCount) 个项目\(collection.itemCount == 1 ? "" : "s")") .foregroundColor(.secondary) } } }
我尝试过使用Geometry Reader,但它在ScrollView中的表现不佳——有没有更优的实现方法?
自行尝试的解决方案(感觉过于繁琐)
struct CollectionsView: View { @StateObject var viewModel: CollectionsViewModel = CollectionsViewModel() var body: some View { GeometryReader { geometry in ScrollView { let spacing: Double = 16 let columns = [GridItem(spacing: spacing), GridItem(spacing: spacing)] LazyVGrid(columns: columns) { ForEach(viewModel.collections) { collection in Button { print("进入合集页面") } label: { let geometryInfo = GeometryInfo(size: geometry.size, columnCount: Double(columns.count), spacing: spacing) CollectionsViewCell(geometryInfo: geometryInfo, collection: collection) } .onAppear { if collection == viewModel.collections.last { Task { try await viewModel.getCollections(nextPage: true) } } } } } .padding(spacing) } .navigationTitle("合集") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { // 更多按钮点击事件 } label: { Image(systemName: "ellipsis.circle") } } } } } } struct CollectionsViewCell: View { let geometryInfo: GeometryInfo let collection: HashableCollection var body: some View { VStack(alignment: .leading) { AsyncImage(url: URL(string: collection.imageUrlString)) { image in image .resizable() .scaledToFill() } placeholder: { Rectangle() } .frame(width: getImageSize(), height: getImageSize()) .background(.secondary) .clipped() .cornerRadius(11) Text(collection.title) .lineLimit(1) .truncationMode(.tail) Text("\(collection.itemCount) 个项目\(collection.itemCount == 1 ? "" : "s")") .foregroundColor(.secondary) } } func getImageSize() -> Double { (geometryInfo.size.width - ((geometryInfo.columnCount + 1) * geometryInfo.spacing)) / geometryInfo.columnCount } }
有没有更简洁的优化方式?
内容的提问来源于stack exchange,提问作者Halpo
相关产品推荐
相关产品推荐

