I tried to add a double value to a subclass of UIButton in Swift. I tried all kind of inits and get and set options, but I couldn’t get it to work.
So I started with this:
class CVSTButton : UIButton {
var cvstPosition: Double
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
}
Then I tried:
class CVSTButton : UIButton {
var cvstPosition: Double {
get {
return self.cvstPosition
}
set {
self.cvstPosition = newValue
}
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
}
What’s is wrong here?
With Swift 3, according to your needs, you may choose one of the seven following code snippets to solve your problem.
UIButton
subclass with a custom initializerThis 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
}
}
UIButton
subclass with a convenience initializerThis 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
}
}
UIButton
subclass with init(frame: CGRect)
initializerWith 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
}
}
UIButton
subclass with init?(coder aDecoder: NSCoder)
initializerWith 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
}
}
UIButton
subclass with init(frame: CGRect)
and init?(coder aDecoder: NSCoder)
initializersWith 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
}
}
UIButton
subclass with a default property value for your propertyAs 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
}
}
UIButton
subclass with your property having an optional typeIf 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
}
}
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)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With