I've created a custom UIView with a subview containing several square subviews which are sized using layout constraints. I'd like for each subview to be circular so I'm holding a reference to the view in an array, then iterating through the array of views in the layoutSubviews method and applying a corner radius that is half the view.bounds.height.
The problem is, this only works 70% of the time. Sometimes the view doesn't seem to know its bounds and the views are rendered as square.
I'm probably approaching this all wrong... does anyone have any advice for me? Where is it safe to apply the corner radius so that it always renders as a perfect circle?
Thanks
CodePudding user response:
The most reliable way to manage this is to subclass UIView
and let it handle its own rounding.
For example:
class RoundView: UIView {
override func layoutSubviews() {
super.layoutSubviews()
// this assumes constraints keep
// self at a 1:1 ratio (square)
layer.cornerRadius = bounds.height * 0.5
}
}
This simple controller example:
class RoundDemoVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let colors: [UIColor] = [
.systemRed, .systemGreen, .systemBlue
]
let widths: [CGFloat] = [
200, 140, 140
]
let xPos: [CGFloat] = [
20, 120, 180
]
let g = view.safeAreaLayoutGuide
for i in 0..<colors.count {
let v = RoundView()
v.backgroundColor = colors[i]
view.addSubview(v)
v.translatesAutoresizingMaskIntoConstraints = false
v.widthAnchor.constraint(equalToConstant: widths[i]).isActive = true
// make it square
v.heightAnchor.constraint(equalTo: v.widthAnchor).isActive = true
v.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: xPos[i]).isActive = true
v.centerYAnchor.constraint(equalTo: g.centerYAnchor).isActive = true
}
}
}
Produces this output:
No need to iterate through subviews and setting values based on frame sizes... all you need to do is set the size/position constraints.
CodePudding user response:
Donmag's example is cool.Also, you can do it this way without writing code to layoutsubview. You must add this settings after adding the constraints
of the subviews in for iteration
.
.......
....... // constraint settings
subView.layoutIfNeeded()
subView.layer.cornerRadius = subView.frame.size.height/2
CodePudding user response:
override func layoutSubviews() {
super.layoutSubviews()
// This is the place to apply corner radius
}