Search code examples
iosswiftuiimageviewcollectionview

How to crop part of the image outside of a collectionview cell in swift


I have a simple design app where i have just a round image on the top right corner. I am trying to do something like what they have on the bloom app.

enter image description here

See how the edge of the image is getting cut off at the edge of the cell, I am trying to go for something like that, but I keep getting this.

enter image description here

I had a feeling that the entire cell is just an image so that it how it looks like that, but I don't know if making an entire cell image is what i want to do, since I plan to eventually be able to change the cell's color and the circle image's color at different times, and use different color, so it is not in my interest to use just a large image for the cell, since I might want to use different images too. It also seems to be easier to figure this out, than just create a couple dozen different images, which also increases it's app size.

I have looked at a few different posts, but none of them seems to work for me.

I tried:

  • setting the frame of the image and background to the bounds
  • using all the different content mode
  • using clipsToBound, and masksToBounds and set them to either true and false.

this is what is in my cell:

    contentView.addSubview(cellBackgrounded)
        cellBackgrounded.addSubview(imgView)
//        imgView.frame = cellBackgrounded.bounds  set this to = self.bounds, contentView.frame
//        contentView.frame = self.bounds
//        cellBackgrounded.frame = self.bounds
//        imgView.layer.masksToBounds = false
        imgView.translatesAutoresizingMaskIntoConstraints = false
        imgView.image = UIImage(named: "Oval")?.withRenderingMode(.alwaysTemplate)
        imgView.clipsToBounds = true
        imgView.contentMode = .scaleToFill
        imgView.tintColor = .red
        
        cellBackgrounded.translatesAutoresizingMaskIntoConstraints = false
        cellBackgrounded.backgroundColor = .white
        cellBackgrounded.addSubview(cellName)
        cellName.translatesAutoresizingMaskIntoConstraints = false
        cellName.font = UIFontMetrics.default.scaledFont(for: UIFont.systemFont(ofSize: 50, weight: .bold))
        cellName.textColor = .black
        cellName.numberOfLines = 0
        cellName.textAlignment = .center
        
        darkShadow.frame = self.bounds
        darkShadow.cornerRadius = 15
        darkShadow.backgroundColor = UIColor.offWhite.cgColor
        darkShadow.shadowColor = UIColor.black.withAlphaComponent(0.2).cgColor
        darkShadow.shadowOffset = CGSize(width: 10, height: 10)
        darkShadow.shadowOpacity = 1
        darkShadow.shadowRadius = 15
        self.layer.insertSublayer(darkShadow, at: 0)
        
        NSLayoutConstraint.activate([
            cellBackgrounded.topAnchor.constraint(equalTo: topAnchor),
            cellBackgrounded.leadingAnchor.constraint(equalTo: leadingAnchor),
            cellBackgrounded.trailingAnchor.constraint(equalTo: trailingAnchor),
            cellBackgrounded.bottomAnchor.constraint(equalTo: bottomAnchor),
            imgView.topAnchor.constraint(equalTo: cellBackgrounded.topAnchor, constant: -40),
            imgView.trailingAnchor.constraint(equalTo: cellBackgrounded.trailingAnchor, constant: 40),
            cellName.centerXAnchor.constraint(equalTo: cellBackgrounded.centerXAnchor),
            cellName.centerYAnchor.constraint(equalTo: cellBackgrounded.centerYAnchor),
            cellName.leadingAnchor.constraint(equalTo: cellBackgrounded.leadingAnchor, constant: 10),
            cellName.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            imgView.heightAnchor.constraint(equalTo: cellBackgrounded.heightAnchor, multiplier: 0.7),
            imgView.widthAnchor.constraint(equalTo: cellBackgrounded.widthAnchor, multiplier: 0.7)
        ])

if there is anything else i can help with please ask, Thank you


Solution

  • Use clipToBounds

    According to apple docs :

    When the value of this property is true, Core Animation creates an implicit clipping mask that matches the bounds of the layer and includes any corner radius effects

    You must do clipsToBound to the containerView to solve this problem

    containerView.clipsToBound = true