programing tip

UIButton 하위 클래스를 초기화하는 방법은 무엇입니까?

itbloger 2020. 11. 29. 10:00
반응형

UIButton 하위 클래스를 초기화하는 방법은 무엇입니까?


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 3을 사용하면 필요에 따라 다음 7 가지 코드 스 니펫 중 하나를 선택 하여 문제를 해결할 수 있습니다.


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)

이 솔루션을 사용하면 UIButtonStoryboard에서 하위 클래스의 인스턴스를 만들 수 있습니다 .

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. Create your UIButton subclass with a default property value for your property

As an alternative to the previous solutions, you can assign an initial value to your property outside of the initializers.

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. Create your UIButton subclass with your property having an optional type

If you don't want to / can't set a default value to your property when your button is created, you must set your property type as an optional.

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
    }

}

Two things you need there -- (1) cvstPosition need an initial value, either in the declaration or in the init before you call super.init(). (2) That call to fatalError is put in so you don't forget to implement the initializer -- it's basically an on-purpose crash. Delete!

Setting initial value in the declaration, no need for an init:

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

Or setting the initial value in the initializer:

class CVSTButton : UIButton {
    var cvstPosition: Double

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

        super.init(coder: aDecoder)
    }
}

Swift >= 2.2:

Just inherit from UIButton, and your subclass becomes with type .Custom default.

Swift 2:

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

    // this button be automatically .Custom
}

Swift:

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

NOTE: I'm using Swift 3 in XCode 8.3.3

This is a simple and easy workaround I've been using when needing to add custom properties and methods to a 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

    }

}

To use it:

let cvstButton = CVSTButton.button(withCVSTPosition: 2.0)

참고URL : https://stackoverflow.com/questions/27079681/how-to-init-a-uibutton-subclass

반응형