如何初始化UIButton子类?


75

我正在尝试在Swift中尝试对UIButton的子类添加双精度值,尝试了所有类型的init并获取并设置了选项,但我无法使其正常工作。

所以我从这个开始

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

我没有在这里出什么问题....请帮助...

Answers:


244

使用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从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
    }

}

用法:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var button: CustomButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        print(button.myValue) // prints 0
    }

}

5.UIButton使用init(frame: CGRect)init?(coder aDecoder: NSCoder)初始化程序创建子类

使用此解决方案,您可以以UIButton编程方式或从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.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
    }

}

35
我喜欢您给出了为什么要使用每个代码段的方案。现象反应-希望这样回答更多问题。
萨米(Sami)

如果按钮是插座,如何调用便捷init()?
马姆塔

在代码片段3的使用部分(其中的框架用作初始化程序)中,使用诸如CustomButton(frame: CGRect(x: 100, y: 300, width: 200, height: 50))而不是CustomButton(frame: .zero)自动布局之类的内容会更清楚
paulo62,20年

12

在那里您需要做两件事-(1)cvstPosition需要一个初始值,无论是在声明中还是在init调用之前super.init()。(2)发出了对to的调用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)
    }
}

太好了,所以我只需要声明并给变量一个init值即可!
亚历山大·

init在Swift 2.2中需要一个问号,所以required init?(coder aDecoder: NSCoder) {
Dan Rosenstark '16

7

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
}

您要在其中插入“ public”。即:优先于公共类功能
u2Fan 2015年

当然不是。读公众是项目之间的范围。
dimpiax

4

注意:我在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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.