Представление контроллера равно Nill при переходе делегата

В настоящее время я пытаюсь представить контроллер представления, используя UIPresentationController. Моя проблема в том, что когда мой пользовательский делегат перехода вызывает

func presentationControllerForPresentedViewController(presented: UIViewController, presentingViewController presenting: UIViewController!, sourceViewController source: UIViewController) -> UIPresentationController? 

Мой представляющий контроллер nil вызывает исключение. Я представляю его из контроллера представления, встроенного в контроллер навигации, встроенный в контроллер панели вкладок. Я попытался представить его и с этих контроллеров по той же проблеме. Это также работает правильно, когда нет пользовательского модального представления, но моя цель — настроить его. Я вызываю его, когда выбрана кнопка, и код приведен ниже. mapTransitionDelegate — это мой настраиваемый переходный делегат, который я сохраняю в свойстве класса. Кроме того, EnlargedMapViewController() инициализируется для пользовательского модального представления, поэтому вызывается мой переходный делегат.

var enlargedMapController = EnlargedMapViewController();
enlargedMapController.transitioningDelegate = mapTransitionDelegate;
presentViewController(enlargedMapController, animated: true, completion: nil);

Я хотел бы узнать, почему эта проблема возникает для будущих знаний. На данный момент мой подкласс UIPresentationController даже не инициализируется из-за этого исключения.


person user2532485    schedule 01.08.2015    source источник
comment
EnlargedMapViewController создан в Interface Builder? Если да, то это обычная ловушка. Используйте IBOutlet, а не создавайте экземпляр программно.   -  person vadian    schedule 01.08.2015
comment
EnlargedMapViewController() создается полностью в коде. Однако мое приложение в основном полагается на раскадровки, за исключением этого контроллера представления.   -  person user2532485    schedule 01.08.2015


Ответы (1)


Назначенный инициализатор для UIViewController (и, в свою очередь, его подклассов) — init(nibName:bundle:). Однако в документации конкретно сказано:

Это назначенный инициализатор для этого класса. При использовании раскадровки для определения вашего контроллера представления и связанных с ним представлений вы никогда не инициализируете свой класс контроллера представления напрямую. Вместо этого контроллеры представлений создаются раскадровкой либо автоматически при запуске перехода, либо программно, когда ваше приложение вызывает метод instanceiateViewControllerWithIdentifier: объекта раскадровки. При создании экземпляра контроллера представления из раскадровки iOS инициализирует новый контроллер представления, вызывая его метод initWithCoder: вместо этого метода и задает для свойства nibName файл пера, хранящийся внутри раскадровки.

Вызов EnlargedMapViewController() не является правильным путем, потому что он обходит все необходимые механизмы для Cocoa, чтобы найти части. Вы должны создать его экземпляр из пера, используя его назначенный инициализатор или, по крайней мере, сопоставив его имя файла пера с его именем класса (то есть, EnlargedMapViewController.xib), поэтому ваш вызов EnlargedMapViewController(nibName: nil, bundle: nil) (передача nil) заставит Cocoa искать соответствующий перо по имени.

Но на самом деле, если вы используете раскадровки везде, почему бы и здесь не использовать? Просто установите идентификатор для его сцены и используйте instantiateViewControllerWithIdentifier: и наслаждайтесь сэкономленным временем и раздражением.

person Joshua Nozzi    schedule 04.11.2015