Search code examples
iosswiftrounded-cornerscornerradius

Smooth only top angles and imageview in Swift


I'm trying to round only the top top corners (TopLeft and TopRight) of a view and imageview. With the code below I was able to round up only the left corner (although there is also specified TopRight). Maybe he doesn't see the constraint placed on the storyboard.

How do I fix?

Thank you.

let rectShape = CAShapeLayer()
        rectShape.bounds = self.CopertinaImage1.frame
        rectShape.position = self.CopertinaImage1.center
        rectShape.path = UIBezierPath(roundedRect: self.CopertinaImage1.bounds, byRoundingCorners: [.TopRight, .TopLeft], cornerRadii: CGSize(width: 10, height: 10)).CGPath

        self.CopertinaImage1.layer.backgroundColor = UIColor.greenColor().CGColor
        self.CopertinaImage1.layer.mask = rectShape

The right corner is always the same: enter image description here Edit:

I've tried placing the following code in viewDidLayoutSubviews:

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    let rectShape = CAShapeLayer() 
    rectShape.bounds = self.CopertinaImage1.frame 
    rectShape.position = self.CopertinaImage1.center 
    rectShape.path = UIBezierPath(roundedRect: self.CopertinaImage1.bounds, byRoundingCorners: [.TopRight, .TopLeft], cornerRadii: CGSize(width: 10, height: 10)).CGPath 
    self.CopertinaImage1.layer.backgroundColor = UIColor.greenColor().CGColor 
    self.CopertinaImage1.layer.mask = rectShape
}

But it didn't work.


Solution

  • I've tried the code you've posted. For whatever reason when I enter your constraints and recreate your view hierarch, the auto layout engine does not call viewDidLayoutSubviews after it does it's second pass. I could force it to but calling self.view.layoutIfNeeded() from viewWillAppear. For example:

    override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            let rectShape = CAShapeLayer()
            rectShape.frame = self.imageView.bounds
            rectShape.path = UIBezierPath(roundedRect: self.imageView.bounds, byRoundingCorners: [.TopRight, .TopLeft], cornerRadii: CGSize(width: 10, height: 10)).CGPath
            self.imageView.layer.backgroundColor = UIColor.greenColor().CGColor
            self.imageView.layer.mask = rectShape
    }
    
    override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
            self.view.layoutIfNeeded()
        }
    

    Results in:

    enter image description here

    With both corners rounded.

    I would say a better, more elegant solution that avoids this auto layout glitch is to just set the corner radius of the image view container, as it seems like that what you're doing anyways. For example:

    override func viewDidLoad() {
            super.viewDidLoad()
            self.imageView.clipsToBounds = true
            self.imageContainerView.layer.cornerRadius = 10.0
            self.imageContainerView.layer.masksToBounds = true
        }
    

    You can also do this from viewDidLoad because it doesn't depend on any of your views' frames being set.

    enter image description here