Is there any way to avoid those repetitive lines ?
Write a function that sets the properties how you want, and call it for each button in your view.
is it gonna be like this ?
func cornerRadiusFunc(_ button: UIButton!, _ radius: Int, _ bound: Boolean) {
button.layer.cornerRadius = radius
button.clipsToBounds = bound
}
I would personally do it with an extension and a default value for the clipped to bounds:
extension UIButton {
func roundCorners(withRadius r: CGFloat, clippedToBounds: Bool = true) {
layer.cornerRadius = r
clipsToBounds = clippedToBounds
}
}
In general, if the parameters to be set are the same for a bunch of objects...
for button in [button1, button2, ...] {
button.backgroundColor = .white
button.clipsToBounds = true
button.layer.cornerRadius = 10
}
I only need to write that extension in one class, and I can implement that in the whole project. Am I right ?
How about use the technique of Lens on UIButton?
The following is code snap, detail lens support framework can see PaversUI-Lens
The original code is from Kickstarter-iOS-OpenSourceProject.
func >>> <A, B, C> (lhs: (A) -> B, rhs: (B) -> C) -> (A) -> C
func |> <A, B> (x: A, f: (A) -> B) -> B
func .~ <Whole, Part> (lens: Lens<Whole, Part>, part: Part) -> ((Whole) -> Whole)
let buttonStyle: (UIButton) -> UIButton =
UIButton.lens.layer.cornerRadius .~ 10
>>> UIButton.lens.clipsToBounds .~ true
_ = backButton |> buttonStyle
_ = playButton |> buttonStyle
Afterward, you can keep that style somewhere and apply it to which button you want, just like CSS to the HTML element.
Why not set these values in Interface Builder?
[button1, button2].forEach{
$0.cornerRadius = 10
$0.clipsToBounds = true
}
If the values differ, I often go with an array of tuples of [(button1, "Hit me", 10), (button2, "Leave", 0)]
or several arrays which I zip
together before doing the assignments.
Yes, you can write that for the UIButton class then you can call it like so:
override func viewDidLoad() {
super,viewDidLoad()
backButton.roundCorners(withRadius: 10)
playButton.roundCorners(withRadius: 10)
}
Note this will only work for UIButton
's. If you want this for any UI component you can extend UIView
. It's as simple as replacing UIButton
in the extension with UIView
extension UIView {
func roundCorners(withRadius r: CGFloat, clippedToBounds: Bool = true) {
layer.cornerRadius = r
clipsToBounds = clippedToBounds
}
}
You can also create an outlet collection by selecting and dragging the buttons from storyboard to your Swift file.
@IBOutlet var buttons: [UIButton]!
override func viewDidLoad() {
super.viewDidLoad()
buttons.forEach {
$0.layer.cornerRadius = 10
$0.clipsToBounds = true
}
}