如何初始化 UIButton 子类?

Posted

技术标签:

【中文标题】如何初始化 UIButton 子类?【英文标题】:How can I init a UIButton subclass? 【发布时间】:2014-11-22 16:30:22 【问题描述】:

我尝试在 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)
   

这里有什么问题?

【问题讨论】:

【参考方案1】:

使用 Swift 3,根据你的需要,你可以选择 以下七个代码 sn-ps 之一来解决你的问题。


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。使用 init(frame: CGRect) 初始化器创建您的 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) 
        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。使用 init?(coder aDecoder: NSCoder) 初始化器创建您的 UIButton 子类

使用此解决方案,您可以从 Storyboard 创建 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 子类

使用此解决方案,您可以通过编程方式或从 Storyboard 创建 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
    


【讨论】:

我喜欢你给出了为什么要使用每个代码 sn-p 的场景。惊人的反应 - 希望有更多这样的问题得到回答。 如果按钮是插座,如何调用便捷的init()? 在 sn-p 3 的使用部分,使用框架作为初始化器,使用 CustomButton(frame: CGRect(x: 100, y: 300, width: 200, height: 50)) 之类的东西会更清楚,而不是 CustomButton(frame: .zero) 和自动布局【参考方案2】:

你需要两件事 - (1) cvstPosition 需要一个初始值,在你调用 super.init() 之前,要么在声明中,要么在 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 中init 后面需要一个问号,所以required init?(coder aDecoder: NSCoder) 【参考方案3】:

斯威夫特 >= 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 是项目之间的范围。 Re "...你的子类变成了 .Custom default 类型。":这几乎是不可理解的。你能fix吗? (但没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的。)【参考方案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)

【讨论】:

以上是关于如何初始化 UIButton 子类?的主要内容,如果未能解决你的问题,请参考以下文章

从 nib 加载的 UIButton 的子类未正确初始化

子类UIButton:属性未在super.init调用时初始化

使用alloc后如何初始化UIButton的类型?

如何在 segue 中初始化 UIButton 的 titleLabel 字体?

如何使这个 UIButton 的动作正确运行?

初始化后访问自定义 UIButton 类中的插座