How can I init a UIButton subclass?
Solution 1:
With Swift 3, according to your needs, you may choose one of the seven following code snippets to solve your problem.
1. Create your UIButton
subclass with a custom initializer
This solution allows you to create instances of your UIButton
subclass with the appropriate value for your property. With this solution, you can only create instances of your UIButton subclass programmatically.
import UIKit
class CustomButton: UIButton {
var myValue: Int
required init(value: Int = 0) {
// set myValue before super.init is called
self.myValue = value
super.init(frame: .zero)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Usage:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = CustomButton(value: 0)
// let button = CustomButton() // also works
button.setTitle("Hello", for: .normal)
// auto layout
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
print(button.myValue) // prints 0
}
}
2. Create your UIButton
subclass with a convenience initializer
This solution allows you to create instances of your UIButton
subclass with the appropriate value for your property. With this solution, you can only create instances of your UIButton
subclass programmatically.
import UIKit
class CustomButton: UIButton {
var myValue: Int
convenience init(squareOf value: Int) {
self.init(value: value * value)
}
required init(value: Int = 0) {
// set myValue before super.init is called
self.myValue = value
super.init(frame: .zero)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Usage:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = CustomButton(squareOf: 10)
// let button = CustomButton(value: 100) // also works
button.setTitle("Hello", for: .normal)
// auto layout
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
print(button.myValue) // prints 100
}
}
3. Create your UIButton
subclass with init(frame: CGRect)
initializer
With this solution, you can only create instances of your UIButton
subclass programmatically.
import UIKit
class CustomButton: UIButton {
var myValue: Int
override init(frame: CGRect) {
// set myValue before super.init is called
self.myValue = 0
super.init(frame: frame)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Usage:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = CustomButton(frame: .zero)
//let button = CustomButton() // also works
button.setTitle("Hello", for: .normal)
// auto layout
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
print(button.myValue) // prints 0
}
}
4. Create your UIButton
subclass with init?(coder aDecoder: NSCoder)
initializer
With this solution, you can create instances of your UIButton
subclass from Storyboard.
import UIKit
class CustomButton: UIButton {
var myValue: Int
required init?(coder aDecoder: NSCoder) {
// set myValue before super.init is called
self.myValue = 0
super.init(coder: aDecoder)
// set other operations after super.init, if required
backgroundColor = .red
}
}
Usage:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: CustomButton!
override func viewDidLoad() {
super.viewDidLoad()
print(button.myValue) // prints 0
}
}
5. Create your UIButton
subclass with init(frame: CGRect)
and init?(coder aDecoder: NSCoder)
initializers
With this solution, you can create instances of your UIButton
subclass programmatically or from Storyboard.
import UIKit
class CustomButton: UIButton {
var myValue: Int
override init(frame: CGRect) {
// set myValue before super.init is called
self.myValue = 0
super.init(frame: frame)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
// set myValue before super.init is called
self.myValue = 0
super.init(coder: aDecoder)
// set other operations after super.init if required
backgroundColor = .red
}
}
6. Create your UIButton
subclass with a default property value for your property
As an alternative to the previous solutions, you can assign an initial value to your property outside of the initializers.
import UIKit
class CustomButton: UIButton {
var myValue: Int = 0
override init(frame: CGRect) {
super.init(frame: frame)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// set other operations after super.init if required
backgroundColor = .red
}
}
7. Create your UIButton
subclass with your property having an optional type
If you don't want to / can't set a default value to your property when your button is created, you must set your property type as an optional.
import UIKit
class CustomButton: UIButton {
var myValue: Int? = nil
override init(frame: CGRect) {
super.init(frame: frame)
// set other operations after super.init, if required
backgroundColor = .red
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// set other operations after super.init if required
backgroundColor = .red
}
}
Solution 2:
You need two things there -- (1) cvstPosition
needs an initial value, either in the declaration or in the init
before you call super.init()
. (2) That call to fatalError
is put in so you don't forget to implement the initializer -- it’s basically an on-purpose crash. Delete!
Setting the initial value in the declaration, there isn’t any need for an init
:
class CVSTButton : UIButton {
var cvstPosition: Double = 0
}
Or setting the initial value in the initializer:
class CVSTButton : UIButton {
var cvstPosition: Double
required init(coder aDecoder: NSCoder) {
cvstPosition = 0
super.init(coder: aDecoder)
}
}
Solution 3:
Swift >= 2.2:
Since this version subclassing the UIButton
, makes your button to have .custom
type.
Swift 2:
convenience init(type buttonType: UIButtonType) {
super.init(frame: CGRectZero)
// this button be automatically .Custom
}
Swift:
override class func buttonWithType(buttonType: UIButtonType) -> AnyObject {
let button = super.buttonWithType(buttonType) as! UIButton
// your default code
return button
}