UICollectionView Cell宽度间距计算错误 每行4个布局异常及圆角失效问题
问题修复方案
一、CollectionView每行显示数量异常修复
注意:你代码中extension的类名拼写错误:ShopViewControll少了末尾的er,正确应为ShopViewController,拼写错误会导致代理方法不生效
你当前的sizeForItemAt方法使用collectionView.bounds.width / 3计算宽度,和你预期每行4个的需求不符,同时没有扣除cell间距、分区边距的宽度,导致布局错乱,修复步骤如下:
- 补充FlowLayout相关代理方法,明确设置布局间距:
// 设置分区上下左右边距,可根据需求调整数值 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) } // 设置行与行之间的间距 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 10 } // 设置同一行内cell之间的间距 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return 10 }
- 修正
sizeForItemAt的宽度计算逻辑:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // 左边距+右边距 let totalInset = 10 + 10 // 一行4个cell,共有3个行内间距 let totalSpacing = 10 * 3 // 扣除边距和间距后,剩余宽度平均分给4个cell let itemWidth = (collectionView.bounds.width - totalInset - totalSpacing) / 4 return CGSize(width: itemWidth, height: 150) }
如果需要适配横竖屏切换,可在宽度计算时使用collectionView.frame.width,同时在屏幕旋转时调用collectionView.reloadData()刷新布局
二、图片圆角不生效修复
圆角不生效有两个原因:一是awakeFromNib调用时cell还未完成布局,拿到的proImage.frame是XIB默认值,不是实际运行的尺寸;二是没有开启图层裁剪,修复步骤如下:
修改ShopCollectionViewCell的代码:
var productData: Products2? = nil{ didSet{ if let product = productData{ // 不需要单独放DispatchQueue.main,cell赋值默认在主线程执行 self.proImage.image = UIImage(named:product.pImage) self.lblName.text = product.name } } } override func awakeFromNib() { super.awakeFromNib() // 提前开启图层裁剪,圆角设置放到layoutSubviews中 proImage.layer.masksToBounds = true } override func layoutSubviews() { super.layoutSubviews() // 此时imageView的frame已经计算完成,拿到的高度是实际运行尺寸 proImage.layer.cornerRadius = proImage.frame.size.height / 2 }
内容的提问来源于stack exchange,提问作者Faheem
相关产品推荐
相关产品推荐

