Swift : 사용자 정의 ViewController 이니셜 라이저


87

UIViewControllerSwift의 서브 클래스에 커스텀 이니셜 라이저를 어떻게 추가 합니까?

UIViewController다음과 같은 하위 클래스를 만들었습니다 .

class MyViewController : UIViewController
{
    init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
    {
        self.leftVC = leftVC;
        self.rightVC = rightVC;
        self.gap = gap;

        super.init();

        setupScrollView();
        setupViewControllers();
    }
}

실행할 때 치명적인 오류가 발생합니다.

치명적인 오류 : 'MyApp.MyViewController'클래스에 구현되지 않은 초기화 프로그램 'init (nibName : bundle :)'사용

사용자 지정 이니셜 라이저를 추가 할 때 재정의해야하는 부분도 읽었으므로 init(coder aDecoder:NSCoder)재정의하고 init어떻게되는지 살펴 보겠습니다 .

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

이것을 추가하면 Xcode는 self.leftVC is not initialized at super.init call. 그래서 나는 그것이 해결책이 될 수 없다고 생각합니다. 그렇다면 ViewControllerSwift 의 하위 클래스에 사용자 지정 이니셜 라이저를 올바르게 추가 할 수있는 방법이 궁금합니다 (Objective-C에서는 문제가되지 않는 것 같습니다)?


어떻게 인스턴스화하려고 MyViewController합니까?
Mike Pollard

viewDidLoad ()에서 모든 것을 인스턴스화하지 않으
시겠습니까

@MikePollard with dualViewCtrl = DualViewCtrl (leftVC : l, rightVC : r, gap : 50) ... 이미 initWithNib 이니셜 라이저를 사용해야한다는 것을 알았습니다.
BadmintonCat

3
@tudoricc 종종 주어진 매개 변수를 사용하여 초기화 프로그램에서 안전하게 초기화되는 인스턴스 속성을 원하기 때문입니다. viewDidLoad에서는 그렇게 할 수 없습니다. 그 이후로 필요할 때 속성을 사용할 수 있다는 보장이 없기 때문입니다.
BadmintonCat

미안하지만 내 마음 속에 viewDidLoad ()가 이니셜 라이저로 표시된다는 것입니다. 설명에 대한 고맙습니다
tudoricc

답변:


124

해결했습니다! 이 경우에는 nibName이있는 init 인 지정된 이니셜 라이저를 호출해야합니다.

init(leftVC:UIViewController, rightVC:UIViewController, gap:Int)
{
    self.leftVC = leftVC
    self.rightVC = rightVC
    self.gap = gap

    super.init(nibName: nil, bundle: nil)

    setupScrollView()
    setupViewControllers()
}

31
:) 그 추한 세미 콜론을 제거하기
MobileMon

8
나는 세미콜론을 좋아합니다. 특히 엄청나게 장황한 Cocoa / Cocoa-Touch API 이름과 서명을 사용하여 코드를 덜 모호하게 만듭니다. IMHO를 제거하려는 Swift 디자이너의 잘못된 결정.
BadmintonCat

25
컴파일 된 바이너리를 사용자가 문자를 입력하고 영향을주지 않는 경우에 이럴, 당신은 :)을 입력해서는 안
샘 Soffes에게

33
@SamSoffes 그래서 (추가) 공백을 전혀 사용하지 않습니까? 그리고 모든 기호를 단일 문자로 난독 화합니까?
Victor Jalencas 2015 년

8
이 논의는 실리콘 밸리에 공백 대 탭을 생각 나게
아론

13

보다 일반적인 UIViewController의 경우 Swift 2.0에서 사용할 수 있습니다.

init() {
    super.init(nibName: nil, bundle: nil)
}

11

이 문제를 완전히 해결할 수 있었는지 확실하지 않지만 클래스 인터페이스의 모양과 실제로 코더 기능이 필요한지 여부에 따라 아래를 사용할 수도 있습니다.

convenience required init(coder aDecoder: NSCoder)
{
    //set some defaults for leftVC, rightVC, and gap
    self.init(leftVC, rightVC, gap)
}

init:leftVC:rightVC:gap은 (는) 지정된 이니셜 라이저 이므로 지정된 이니셜 init:coder라이저를 호출하는 편리한 이니셜 라이저로 만들어 구현 요구 사항을 충족 할 수 있습니다 .

이것은 더 나을 수 있습니다

override init(coder aDecoder: NSCoder)
{
    super.init(coder: aDecoder);
}

일부 속성을 초기화해야하는 경우 다시 작성해야하기 때문입니다.


8

스위프트 5

사용자 정의를 작성하려는 경우에 이니셜 UIViewController로 초기화된다storyBoard.instantiateViewController(withIdentifier: "ViewControllerIdentifier")

Optional속성 에 대해서만 사용자 지정 이니셜 라이저를 작성할 수 있습니다 .

class MyFooClass: UIViewController {
    var foo: Foo?

    init(with foo: Foo) {
        self.foo = foo
        super.init(nibName: nil, bundle: nil)
    }

    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.foo = nil
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.