web-dev-qa-db-fra.com

Comment initier une sous-classe UIButton?

J'essaie d'ajouter une valeur double à une sous-classe de UIButton dans Swift J'ai essayé toutes sortes d'inits et d'options d'obtention et de définition, mais je ne parviens pas à le faire fonctionner.

alors j'ai commencé avec ça

class CVSTButton : UIButton {
    var cvstPosition: Double

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

        super.init(coder: aDecoder)
    }
}

alors j'ai essayé:

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

Je ne me trompe pas ici .... aidez s'il vous plaît ...

61
Alexander Schutte

Avec Swift 3, selon vos besoins, vous pouvez choisir l’un des sept extraits de code suivants pour résoudre votre problème.


1. Créez votre sous-classe UIButton avec un initialiseur personnalisé

Cette solution vous permet de créer des instances de votre sous-classe UIButton avec la valeur appropriée pour votre propriété. Avec cette solution, vous ne pouvez créer que des instances de votre sous-classe UIButton par programme.

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

}

Usage:

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. Créez votre sous-classe UIButton avec un initialiseur de commodité

Cette solution vous permet de créer des instances de votre sous-classe UIButton avec la valeur appropriée pour votre propriété. Avec cette solution, vous ne pouvez créer que des instances de votre sous-classe UIButton par programme.

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

}

Usage:

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. Créez votre sous-classe UIButton avec init(frame: CGRect) initializer

Avec cette solution, vous ne pouvez créer que des instances de votre sous-classe UIButton par programme.

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

}

Usage:

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. Créez votre sous-classe UIButton avec init?(coder aDecoder: NSCoder) initialiseur

Avec cette solution, vous pouvez créer des instances de votre sous-classe UIButton à partir de 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
    }

}

Usage:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var button: CustomButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        print(button.myValue) // prints 0
    }

}

5. Créez votre sous-classe UIButton avec les initialiseurs init(frame: CGRect) et init?(coder aDecoder: NSCoder)

Avec cette solution, vous pouvez créer des instances de votre sous-classe UIButton par programme ou à partir de 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. Créez votre sous-classe UIButton avec une valeur de propriété par défaut pour votre propriété.

Au lieu des solutions précédentes, vous pouvez attribuer une valeur initiale à votre propriété en dehors des initialiseurs.

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. Créez votre sous-classe UIButton avec votre propriété ayant un type optionnel

Si vous ne voulez pas/ne pouvez pas définir une valeur par défaut pour votre propriété lors de la création de votre bouton, vous devez définir le type de votre propriété comme facultatif.

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
    }

}
204
Imanou Petit

Deux choses dont vous avez besoin ici - (1) cvstPosition a besoin d’une valeur initiale, soit dans la déclaration, soit dans le init avant que vous appeliez super.init(). (2) Cet appel à fatalError est inséré afin de ne pas oublier d’implémenter l’initialiseur - c’est fondamentalement un crash. Supprimer!

Définition de la valeur initiale dans la déclaration, pas besoin d'un init:

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

Ou définir la valeur initiale dans l'initialiseur:

class CVSTButton : UIButton {
    var cvstPosition: Double

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

        super.init(coder: aDecoder)
    }
}
12
Nate Cook

Swift> = 2.2:

Juste hériter de UIButton, et votre sous-classe devient de type .Custom défaut.

Swift 2:

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

    // this button be automatically .Custom
}

Rapide:

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

NOTE: j'utilise Swift 3 dans XCode 8.3.

C'est une solution de contournement simple et facile que j'utilise lorsque j'ai besoin d'ajouter des propriétés et des méthodes personnalisées à un 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

    }

}

Pour l'utiliser:

let cvstButton = CVSTButton.button(withCVSTPosition: 2.0)
3
focorner