Reputation: 657
I've been trying to control the appearance of all of my buttons in my project. I've created an Extension and put it at the top of one ViewController file to control the appearance of all of the buttons in that View. It works great. Here it is:
import UIKit
// EXTENSION TO CONTROL BUTTON APPEARANCE
extension UIButton {
func styleButton() {
self.layer.cornerRadius = 8
self.layer.borderWidth = 2
self.layer.borderColor = UIColor.red.cgColor
}
}
class DefaultSettingsVC: UIViewController, UITextFieldDelegate {
...
// IN VIEWDIDLOAD :
myButton1.styleButton()
myButton2.styleButton() //etc.
The only thing is I need to put it at the top of every ViewController file. (I hope I'm using the right terminology here.) So instead of that, I thought I would create an entirely new file which is a subclass of UIButton. This is the contents of the entire file:
import UIKit
class ButtonStyle: UIButton {
func styleButton() {
self.layer.cornerRadius = 8
self.layer.borderWidth = 2
self.layer.borderColor = UIColor.red.cgColor
}
}
But now what?! When I try to add it to to the Class line in my ViewController files, I get a "Multiple inheritance from classes" error.
class DefaultSettingsVC: UIViewController, UITextFieldDelegate, ButtonStyle {
Am I completely on the wrong track here? Should I be doing this an entirely different way? Any help would be great. My Swift expertise is only a 2.5 out of 5 so I'm still learning and would appreciate some guidance if you can.
Upvotes: 0
Views: 858
Reputation: 31685
I would suggest to apply the desired style for all buttons in all ViewControllers by:
Create a custom UIViewController
super class for all of the ViewControllers in your application.
Let the super class handles the applying of the desired style for all buttons in its view.
The super class should be similar to:
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupButtonsStyle()
}
func setupButtonsStyle() {
for subview in view.allSubViews.filter({$0 is UIButton}) {
let button = subview as! UIButton
button.layer.cornerRadius = 8
button.layer.borderWidth = 2
button.layer.borderColor = UIColor.red.cgColor
}
}
}
extension UIView {
var allSubViews : [UIView] {
var array = [self.subviews].flatMap {$0}
array.forEach { array.append(contentsOf: $0.allSubViews) }
return array
}
}
Note the the purpose of declaring allSubViews
is to get all views and their subviews in a view.
Make sure that the sub class(es) viewDidLoad()
method contains super.viewDidLoad()
:
class ViewController: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
This approach saves the time of calling the style method for each single button in your application (you don't have to call button.styleButton
manually for each button), all you have to do is to let the desired ViewController to be as a subclass of the super class.
Hope this helped.
Upvotes: 0
Reputation: 618
You shouldn't use sublassing to do this. Extensions are the way to go! If you want to be able to use the extension in different classes, you should try to put it in a separated file. Since you're extending the UIButton
class, you want it to be accessible from everywhere.
See, the ViewController
class :
class MyViewController: UIViewController {
var button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
button.styleButton(cornerRadius: 8, borderWidth: 2, borderColor: UIColor.red.cgColor)
}
}
And your extension file :
extension UIButton {
func styleButton(cornerRadius: CGFloat, borderWidth: CGFloat, borderColor: CGColor) {
self.layer.cornerRadius = cornerRadius
self.layer.borderWidth = borderWidth
self.layer.borderColor = borderColor
}
}
I tweaked it a little bit so now you're able to set the parameters you want in case you need later to style some buttons differently. It is more reusable in my opinion so more useful.
Upvotes: 2