2016-07-12 10 views
5

Tworzę niestandardowy kontroler nawigacyjny. Mam coś takiego:Błąd krytyczny: użycie niezatwierdzonego inicjalizatora w niestandardowym kontrolerze nawigacji

public class CustomNavigationController: UINavigationController { 

    // MARK: - Life Cycle 

    override init(rootViewController: UIViewController) { 
     super.init(rootViewController: rootViewController) 

     delegate = self 
    } 

    required public init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     delegate = self 
    } 
} 

chciałem przetestować to na zewnątrz więc stworzyłem CustomNavigationController takiego:

CustomNavigationController(rootViewController: ViewController()) 

Kiedy uruchomić aplikację uzyskać to:

fatal error: use of unimplemented initializer 'init(nibName:bundle:)' for class 'TestApp.CustomNavigationController' 

Nie widzę problemu, czy ktoś może mi pomóc?

+0

co jest 'delegat = self'? po prostu usunięcie, że mógłbym uruchomić twój kod bez problemu – Aladin

+0

To jest UINavigationControllerDelegate. – user1007522

Odpowiedz

6

UINavigationController implementacja init(rootViewController:) prawdopodobnie wywoła self.init(nibName:bundle:), której nie zaimplementowałeś, więc zgłasza błąd.

Oprócz inicjalizatorów, które już zostały zastąpione, należy zastąpić init(nibName:bundle). init(nibName:bundle:) jest wyznaczonym inicjatorem, a init(rootViewController:) jest inicjatorem wygody.

+1

init (rootViewController :) nie może być inicjatorem wygody. Zgodnie z zasadami delegowania inicjalizatora (wymienionymi w odpowiedzi @ Jack's poniżej), określony inicjator może wywołać tylko do innego wyznaczonego inicjalizatora. Powinien to być błąd kompilatora, jeśli spróbujesz wywołać inicjator wygody superklasy z wyznaczonego inicjalizatora podklasy. – Cognitio

4

Podczas korzystania z kontrolera nawigacji zwyczaj, musimy użyć override init własność NavigationController as-

class CustomNavigationController: UINavigationController { 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 

    } 
    override init(rootViewController: UIViewController) { 
     super.init(rootViewController: rootViewController) 
    } 
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
     super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 
    } 

} 

& w Appdelegate klasy użytkowania -

import UIKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

    var window: UIWindow? 
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 
     self.window = UIWindow(frame: UIScreen.main.bounds) 
     let vc = ViewController(nibName: "ViewController", bundle: nil) 
     let navi = CustomNavigationController(rootViewController: vc) 
     window?.backgroundColor = .white 
     window?.rootViewController = navi 
     window?.makeKeyAndVisible() 
     return true 
    } 
} 

Jak na dokument firmy Apple - Aby uprościć relacje między inicjatorami wyznaczonymi a wygodnymi, Swift stosuje następujące trzy reguły dla wywołań delegacji między inicjacją alizers:

Rule 1 A designated initializer must call a designated initializer from its immediate superclass.

Rule 2 A convenience initializer must call another initializer from the same class.

Rule 3 A convenience initializer must ultimately call a designated initializer.

A simple way to remember this is:-

enter image description here

Powiązane problemy