【问题标题】:How can I init a UIButton subclass?如何初始化 UIButton 子类?
【发布时间】: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)
   }
}

这里有什么问题?

【问题讨论】:

    标签: swift uibutton


    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多