如何初始化 UIButton 子类



我试图在 Swift 中为 UIButton 的子类添加一个双精度值。我尝试了各种初始化和获取和设置选项,但我无法让它工作。

所以我从这个开始:

class CVSTButton : UIButton {
    var cvstPosition: Double
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        super.init(coder: aDecoder)
    }
}

然后我尝试了:

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)
   }
}

这里出了什么问题?

在 Swift 3 中,根据您的需要,您可以选择以下七个代码片段之一来解决您的问题。


1. 使用自定义初始值设定项创建UIButton子类

此解决方案允许您创建具有适当属性值的 UIButton 子类的实例。使用此解决方案,您只能以编程方式创建 UIButton 子类的实例。

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")
    }
}

用法:

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. 使用方便的初始值设定项创建UIButton子类

此解决方案允许您创建具有适当属性值的 UIButton 子类的实例。使用此解决方案,您只能以编程方式创建 UIButton 子类的实例。

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")
    }
}

用法:

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. 使用初始值设定项创建UIButton init(frame: CGRect)子类

使用此解决方案,您只能以编程方式创建UIButton子类的实例。

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")
    }
}

用法:

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. 使用初始值设定项创建UIButton init?(coder aDecoder: NSCoder)子类

使用此解决方案,可以从情节提要创建UIButton子类的实例。

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
    }
}

用法:

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var button: CustomButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        print(button.myValue) // prints 0
    }
}

5. 使用 init(frame: CGRect)init?(coder aDecoder: NSCoder) 初始值设定项创建 UIButton 子类

使用此解决方案,可以通过编程方式或从情节提要创建 UIButton 子类的实例。

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. 使用属性的默认属性值创建 UIButton 子类

作为上述解决方案的替代方法,可以在初始值设定项之外为属性分配初始值。

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. 使用具有可选类型的属性创建 UIButton 子类

如果在创建按钮时不想/无法为属性设置默认值,则必须将属性类型设置为可选。

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
    }
}
你需要

两件事——(1)cvstPosition需要一个初始值,无论是在声明中还是在init中,在你调用super.init()之前。(2)输入了对fatalError的调用,因此您不要忘记实现初始值设定项 - 它基本上是一个故意崩溃。删除!

在声明中设置初始值,不需要init

class CVSTButton : UIButton {
    var cvstPosition: Double = 0
}

或者在初始值设定项中设置初始值:

class CVSTButton : UIButton {
    var cvstPosition: Double
    required init(coder aDecoder: NSCoder) {
        cvstPosition = 0
        super.init(coder: aDecoder)
    }
}

Swift>= 2.2:

由于此版本对UIButton 进行子类化,因此您的按钮具有.custom类型。

雨燕 2:

convenience init(type buttonType: UIButtonType) {
    super.init(frame: CGRectZero)
    // this button be automatically .Custom
}

迅速:

override class func buttonWithType(buttonType: UIButtonType) -> AnyObject {
    let button = super.buttonWithType(buttonType) as! UIButton
    // your default code
    return button
}

注意:我在 Xcode 8.3.3 中使用 Swift 3

这是我在需要向UIButton添加自定义属性和方法时一直在使用的一种简单易用的解决方法:

class CVSTButton: UIButton {
    var cvstPosition: Double
    static func button(withCVSTPosition cvstPosition: Double) -> CVSTButton {
        let button = CVSTButton(type: .detailDisclosure) // You may adjust the initializer used to suit your needs.
        button.cvstPosition = cvstPosition // Then you can simply set the the properties (which are passed as arguments to the factor/class method)
        return button
    }
}

要使用它:

let cvstButton = CVSTButton.button(withCVSTPosition: 2.0)

最新更新