Search code examples
iosswiftuikituicollectionviewcelluibezierpath

Issue with left bottom and right bottom cornerradius to Uiview inside UICollectioviewCell


I'm getting one issue with UICollectionView Cell. i'm try to give only 2 side corner radius to UIView with below code. i face below issue. Any suggestion could be appreciate. Thank you

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

    }

Issue image

Expectation Image


Solution

  • You may want to try the following code to handle diff iOS version

    1. Add the extension for UIView, you can modify it as your need.
    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. use the function like that:
    cell.productnamevw.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
    

    One more thing, for your case, I would recommend you setup the cell in the cell itself

    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)
    
        }
    }