0

Ive been using the code shown below to round selected corners of views, however am now having trouble achieving this on a resizable view as the layer? isn't updated each time the view is resized.

extension UIView {
    func roundCorners(corners:UIRectCorner, radius: CGFloat) {
        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
    }
}

titleLabelView.roundCorners(corners: [.topLeft, .topRight], radius: 10)

There is a similar question here but its quite old and all done in objC.

Is there a way of rounding selected corners in swift for resizable views?

----- EDIT -----

So essentially what i have is a text table that i have set to resize based on the size of the text.

In most cases i can just use:

myTextLabel.layer.cornerRadius = 10

However this does all 4 corners. So if i want to round just the top 2 then i need to use the extension above. Now because i am using scrollViewDidEndDecelerating to set the content for the label (i need to get the indexPath for the cell at the centre of the collectionView so i can set the text label)

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    GeneralFunctions.getIndexOfCell(sender: self) { (index) in
        self.titleLabel.text = self.partArray[index].title
        self.titleLabel.roundCorners(corners: [.topLeft, .topRight], radius: 10)
        self.descriptionLabel.text = self.partArray[index].description
        self.descriptionLabel.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
        self.backgroundLabelView.layer.cornerRadius = 16
        self.backgroundLabelView.layoutIfNeeded()
        self.backgroundLabelView.layoutSubviews()
    }

}

Using viewDidLayoutSubViews doesn't work in this case as there is a lag between accelerating ending and the layout. I have tried using the same code(without the check for the centre index) inside viewDidLayoutSubViews but the result is the same.

enter image description here

And The label does resize correctly when i don't use any of the corner rounding.

enter image description here

Community
  • 1
  • 1
DuckMan
  • 133
  • 1
  • 12
  • Without checking the linked question (and I expect answer), can you explain the exact issue? Conversion from Obj-C to Swift is pretty straightforward. What have you tried? You question is rather vague. –  Feb 14 '17 at 04:45
  • In particular, in the question you referenced, pay particular attention to doing the resize in `viewDidLayoutSubviews` – David Berry Feb 14 '17 at 05:00

1 Answers1

1

I had similar problem, I've solved it by using this function like

DispatchQueue.main.async(execute: {
    self.roundCorners(.allCorners, radius: 6, borderColor: nil, borderWidth: nil)
})

I am using this function a lot for UITableViewCell, and my whole code looks like

private var didLayoutSubview = false {
    didSet {
        DispatchQueue.main.async(execute: {
            self.roundCorners(.allCorners, radius: 6, borderColor: nil, borderWidth: nil)
        })
    }
}

override func layoutSubviews() {
    if !self.didLayoutSubview {
        self.didLayoutSubview = true
    }
    super.layoutSubviews()
}

So basically, calling this function in main thread helped, and I am calling it inside layoutSubivews because I think it is the place.

My function

func roundCorners(_ corners: UIRectCorner, radius: CGFloat, borderColor: UIColor?, borderWidth: CGFloat?) {
    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))

    let mask = CAShapeLayer()
    mask.frame = self.bounds
    mask.path = path.cgPath
    self.layer.mask = mask

    if borderWidth != nil {
        addBorder(mask, borderWidth: borderWidth!, borderColor: borderColor!)
    }
}
JuicyFruit
  • 2,638
  • 2
  • 18
  • 35