【问题标题】:Issue with left bottom and right bottom cornerradius to Uiview inside UICollectioviewCellUICollectioviewCell 内的 Uiview 的左下角和右下角半径问题
【发布时间】:2019-04-24 06:34:46
【问题描述】:

我遇到了 UICollectionView Cell 的一个问题。我试图用下面的代码只给UIView 2 个边角半径。我面临以下问题。任何建议都会不胜感激。谢谢你

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell : FeaturedCell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeaturedCell", for: indexPath) as! FeaturedCell
        let objModel = arrSearch[indexPath.row]
        cell.lblproducttitle.text = "\(objModel.Name!) \n$\(objModel.price!)"
        cell.imgproduct.sd_setImage(with: URL(string: objModel.imgUrl), placeholderImage: UIImage(named: "logo"), options: .refreshCached, completed: nil)

        let mask = CAShapeLayer()
        mask.bounds = cell.productnamevw.frame
        mask.position = cell.productnamevw.center
        mask.backgroundColor = cell.productnamevw.backgroundColor?.cgColor

        let path = UIBezierPath(roundedRect: cell.productnamevw.bounds, byRoundingCorners: [.bottomLeft , .bottomRight], cornerRadii: CGSize(width: 10, height: 10))
        mask.path = path.cgPath
        cell.productnamevw.layer.mask = mask
        cell.productnamevw.layer.masksToBounds = true
        return cell

    }

【问题讨论】:

  • @HimanshuMoradiya 上 2 个角是如何圆角的?添加您的视图层次结构及其顺序。
  • 尝试使用cell.contentView 而不仅仅是cell
  • 你的 iOS 版本是多少?
  • @Himanshu Moradiya 您不需要为您的子视图制作角半径(即灰色)。您只需将容器视图的“clipbounds”设置为 true。仅当容器的角与子视图的角相同时才执行此操作。
  • 这可能与我描述的in this answer 和in this answer 相同的问题:当您创建遮罩路径时,视图(在本例中为cell.productnamevw)尚未设置为其最终大小,所以cell.productnamevw.bounds 的大小错误。但是,我没有将此问题标记为重复问题,因为在我写完这些答案后,iOS 11 将maskedCorners 属性添加到CALayer。设置maskedCorners(正如这里的几个答案所建议的那样)是一个更简单的解决方案。

标签: ios swift uikit uicollectionviewcell uibezierpath


【解决方案1】:

您可能想尝试以下代码来处理不同的 iOS 版本

  1. 添加UIView的扩展,您可以根据需要进行修改。
extension UIView {
  func roundCorners(corners: UIRectCorner, radius: CGFloat) {
        if #available(iOS 11.0, *) {
            let cornerMasks = [
                corners.contains(.topLeft) ? CACornerMask.layerMinXMinYCorner : nil,
                corners.contains(.topRight) ? CACornerMask.layerMaxXMinYCorner : nil,
                corners.contains(.bottomLeft) ? CACornerMask.layerMinXMaxYCorner : nil,
                corners.contains(.bottomRight) ? CACornerMask.layerMaxXMaxYCorner : nil,
                corners.contains(.allCorners) ? [CACornerMask.layerMinXMinYCorner, CACornerMask.layerMaxXMinYCorner, CACornerMask.layerMinXMaxYCorner, CACornerMask.layerMaxXMaxYCorner] : nil
                ].compactMap({ $0 })

            var maskedCorners: CACornerMask = []
            cornerMasks.forEach { (mask) in maskedCorners.insert(mask) }

            self.clipsToBounds = true
            self.layer.cornerRadius = radius
            self.layer.maskedCorners = maskedCorners
        } else {
            let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            self.layer.mask = mask
        }
    }
}
  1. 这样使用函数:
cell.productnamevw.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)

还有一件事,对于您的情况,我建议您在单元格本身中设置单元格

class FeaturedCell: UICollectionViewCell {

    @IBOutlet private weak var productnamevw: UIView!

    override func awakeFromNib() {
        super.awakeFromNib()

        self.productnamevw.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        self.productnamevw.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)

    }
}

【讨论】:

  • 这不起作用,因为在调用awakeFromNib 时视图尚未设置为其最终大小。需要在productnamevw的layoutSubviews方法中计算掩码路径。
  • 你的答案是正确的,但是当我第一次加载它的显示一半结果时,当我向下滚动并回到顶部时,它运行良好
  • @HimanshuMoradiya 是的,正如 robmayoff 所说,当 awakeFromNib 时,视图尚未设置为最终大小。我更新了代码,希望对您有所帮助:)
【解决方案2】:

请注意,这只适用于 iOS 11.0+

yourview.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]

【讨论】:

    【解决方案3】:

    对于 Swift 4+ 和 iOS 11.0 之后的版本,这将起作用:

        - For top left corner = [.layerMinXMinYCorner]
    
        - For top right corner = [.layerMaxXMinYCorner]
    
        - For bottom left corner = [.layerMinXMaxYCorner]
    
        - For bottom right corner = [.layerMaxXMaxYCorner]
    

    据此,您的代码应如下所示:

        cell.productnamevw.layer.cornerRadius = 10   //or whatever you want to give
        cell.productnamevw.layer.maskedCorners = [. layerMinXMaxYCorner, . layerMaxXMaxYCorner]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-08
      • 2020-10-27
      • 2014-10-26
      • 2013-12-22
      • 2023-03-25
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多