UICollectionViewDelegateFlowLayout设置cell尺寸后内部UIImageView圆角显示为椭圆
问题原因
你在cellForItemAt中设置圆角时,UIImageView的最终布局还没有完成,此时拿到的frame.height是XIB/Storyboard中的初始值而非实际渲染尺寸,计算得到的圆角值不符合预期,所以首次加载显示为椭圆。当你从其他页面返回时,Cell已经完成布局,此时frame值准确,圆角就正常了。重新加载CollectionView时cellForItemAt仍然会在Cell布局完成前触发,所以无法解决问题。
解决方案
推荐在自定义Cell类ColCell中重写layoutSubviews方法统一设置圆角,此时所有子视图的frame已经计算完成,拿到的值是准确的:
class ColCell: UICollectionViewCell { @IBOutlet weak var imgMain: UIImageView! @IBOutlet weak var lblTitle: UILabel! override func layoutSubviews() { super.layoutSubviews() // 强制布局更新,确保frame值准确 self.layoutIfNeeded() // 统一设置圆角,无需在cellForItemAt中分别处理 imgMain.layer.cornerRadius = imgMain.bounds.height / 2 imgMain.layer.masksToBounds = true } }
之后修改你原有的cellForItemAt代码,删除原本在else分支中设置圆角的代码即可:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColCell", for: indexPath) as! ColCell cell.imgMain.image = UIImage(named: "temp.png") if (self.totalCard.count-1) == indexPath.item { cell.lblTitle.text = "Add link" cell.imgMain.image = UIImage(named: "addCard.png") }else{ cell.lblTitle.text = mediaTmp.cardName let url = URL(string: mediaTmp.cardImage) cell.imgMain.kf.setImage(with: url) } return cell }
注意:请确保
imgMain的约束设置了宽高1:1,且位置、尺寸约束完整,避免ImageView本身为矩形导致圆角效果不符合预期。
临时替代方案
如果你不想修改自定义Cell的代码,也可以在设置圆角前强制触发布局更新,在原有的圆角设置代码前加一行cell.layoutIfNeeded()即可,但该方式在Cell布局有动态变化的场景下稳定性不如重写layoutSubviews。
内容的提问来源于stack exchange,提问作者Usman
相关产品推荐
相关产品推荐

