Reputation: 166
I have a UIButton
in a storyboard that automatically resizes based on the device's current orientation. I have a 1:1
aspect ratio constraint on the button, and the button's corner radius should always be half its width so that it displays as a circle.
I have tried to update the corner radius in viewDidLayoutSubviews
as follows:
override func viewDidLayoutSubviews() {
bigButton.layer.cornerRadius = 0.5 * bigButton.bounds.size.width
}
I would expect this to update the corner radius based on the button's width after it resizes. I think what it's actually doing is updating the corner radius based on the button's previous width, causing it to display incorrectly.
Is there an easy way to get the button's width after it resizes? Or is there a different approach to achieve my desired effect? Thanks for the help!
Upvotes: 2
Views: 4376
Reputation: 1258
You can make a subclass of UIButton
and set the layer.cornerRadius
in layoutSubviews
.
class RoundButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2
}
}
Here is a simple example could be tested in the Playground. You can see the corner radius is reactive every time it changes the size by clicking.
import UIKit
import PlaygroundSupport
class MyViewController: UIViewController {
private var button: RoundButton!
override func loadView() {
let view = UIView()
view.backgroundColor = .white
button = RoundButton()
button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(tapButton), for: .touchUpInside)
button.setTitle("Round", for: .normal)
button.backgroundColor = .red
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
self.view = view
}
@objc private func tapButton(_ sender: Any) {
button.contentEdgeInsets.top += 5
button.contentEdgeInsets.bottom += 5
}
}
class RoundButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = bounds.height / 2
}
}
PlaygroundPage.current.liveView = MyViewController()
Upvotes: 6
Reputation: 166
I was able to achieve the desired effect by setting the corner radius asynchronously:
override func viewDidLayoutSubviews() {
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.bigButton.layer.cornerRadius = 0.5 * self.bigButton.bounds.size.width
}
}
The rotation animation becomes a little clunky, but it should be sufficient for now.
Upvotes: 1