Wie initiiere ich eine UIButton-Unterklasse?

74

Ich versuche, einer Unterklasse von UIButton in Swift einen doppelten Wert hinzuzufügen. Ich habe alle Arten von Inits ausprobiert und Optionen abgerufen und festgelegt, aber ich kann sie nicht zum Laufen bringen.

Also habe ich damit angefangen

class CVSTButton : UIButton {
    var cvstPosition: Double

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")

        super.init(coder: aDecoder)
    }
}

dann habe ich versucht:

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

Ich verstehe hier nicht, was falsch ist ... bitte helfen Sie ...

Alexander Schutte
quelle

Antworten:

241

Mit Swift 3 können Sie je nach Bedarf eines der sieben folgenden Codefragmente auswählen , um Ihr Problem zu lösen.


1. Erstellen Sie Ihre UIButtonUnterklasse mit einem benutzerdefinierten Initialisierer

Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse mit dem entsprechenden Wert für Ihre Eigenschaft erstellen . Mit dieser Lösung können Sie Instanzen Ihrer UIButton-Unterklasse nur programmgesteuert erstellen.

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

}

Verwendung:

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. Erstellen Sie Ihre UIButtonUnterklasse mit einem praktischen Initialisierer

Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse mit dem entsprechenden Wert für Ihre Eigenschaft erstellen . Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse nur programmgesteuert erstellen .

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

}

Verwendung:

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. Erstellen Sie Ihre UIButtonUnterklasse mit dem init(frame: CGRect)Initialisierer

Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse nur programmgesteuert erstellen .

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

}

Verwendung:

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. Erstellen Sie Ihre UIButtonUnterklasse mit dem init?(coder aDecoder: NSCoder)Initialisierer

Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse aus Storyboard erstellen .

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
    }

}

Verwendung:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var button: CustomButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        print(button.myValue) // prints 0
    }

}

5. Erstellen Sie Ihre UIButtonUnterklasse mit init(frame: CGRect)und init?(coder aDecoder: NSCoder)Initialisierer

Mit dieser Lösung können Sie Instanzen Ihrer UIButtonUnterklasse programmgesteuert oder über Storyboard erstellen .

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. Erstellen Sie Ihre UIButtonUnterklasse mit einem Standardeigenschaftswert für Ihre Eigenschaft

Alternativ zu den vorherigen Lösungen können Sie Ihrer Eigenschaft außerhalb der Initialisierer einen Anfangswert zuweisen.

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. Erstellen Sie Ihre UIButtonUnterklasse mit Ihrer Eigenschaft mit einem optionalen Typ

Wenn Sie beim Erstellen Ihrer Schaltfläche keinen Standardwert für Ihre Eigenschaft festlegen möchten / können, müssen Sie Ihren Eigenschaftstyp optional festlegen.

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
    }

}
Imanou Petit
quelle
34
Ich finde es gut, dass Sie Szenarien angegeben haben, warum Sie jedes Code-Snippet verwenden sollten. Phänomenale Antwort - wünschte, mehr Fragen würden so beantwortet.
Sami
Wie rufe ich Convenience Init () auf, wenn die Taste eine Steckdose ist?
Mamta
Im Nutzungs Teil Schnipsel 3, wobei ein Rahmen als initialiser verwendet wird, wäre es klarer sein , etwas zu verwenden , wie CustomButton(frame: CGRect(x: 100, y: 300, width: 200, height: 50))eher als ein CustomButton(frame: .zero)Auto Layout
paulo62
12

Zwei Dinge, die Sie dort benötigen - (1) cvstPositionbenötigen einen Anfangswert, entweder in der Deklaration oder in der initvor dem Aufruf super.init(). (2) Dieser Aufruf von fatalErrorwird eingegeben, damit Sie nicht vergessen, den Initialisierer zu implementieren - es handelt sich im Grunde genommen um einen absichtlichen Absturz. Löschen!

Wenn Sie den Anfangswert in der Deklaration festlegen, ist Folgendes nicht erforderlich init:

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

Oder setzen Sie den Anfangswert im Initialisierer:

class CVSTButton : UIButton {
    var cvstPosition: Double

    required init(coder aDecoder: NSCoder) {
        cvstPosition = 0

        super.init(coder: aDecoder)
    }
}
Nate Cook
quelle
Ah toll, also muss ich nur deklarieren und der Variablen einen Init-Wert geben!
Alexander Schutte
Sie brauchen ein Fragezeichen nach initin Swift 2.2, alsorequired init?(coder aDecoder: NSCoder) {
Dan Rosenstark
7

Swift> = 2.2:

Erben Sie einfach von UIButton, und Ihre Unterklasse wird zum .CustomStandardtyp.

Swift 2:

convenience init(type buttonType: UIButtonType) {
    super.init(frame: CGRectZero)

    // this button be automatically .Custom
}

Schnell:

override class func buttonWithType(buttonType: UIButtonType) -> AnyObject {
    let button = super.buttonWithType(buttonType) as! UIButton
    // your default code
    return button
}
Dimpiax
quelle
Sie möchten dort 'public' einfügen.
Dh
Natürlich nicht. Lesen Sie, dass öffentlich der Bereich zwischen Projekten ist.
Dimpiax
4

HINWEIS: Ich verwende Swift 3 in XCode 8.3.3

Dies ist eine einfache und einfache Problemumgehung, die ich verwendet habe, wenn ich benutzerdefinierte Eigenschaften und Methoden zu a hinzufügen musste 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

    }

}

Um es zu benutzen:

let cvstButton = CVSTButton.button(withCVSTPosition: 2.0)
Focorner
quelle