Ответ 1
Раскадровка не распознавала какие-либо дополнительные пользовательские интерфейсы, которые я добавил к ней. Во время работы все ссылки были ноль. Поэтому я очистил папку с производными данными, а затем эти соединения снова работали.
Использование Swift 1.1 и Xcode 6.2.
У меня есть UIStoryboard, содержащий специальный, UIViewController
подкласс класса. У меня есть соединение @IBOutlet
типа UIView
от этого контроллера к подклассу UIView
на раскадровке. У меня также есть аналогичные выходы для подсмотров этой точки зрения. См. Рисунок A.
Но во время выполнения эти свойства равны нулю (рисунок B). Несмотря на то, что я уверен, что подключил выходы в Interface Builder.
Мысли
awakeFromNib:
не вызван по какой-либо причинеЧто я пробовал:
@IBOutlet
и типов элементов раскадровки точно (вместо UIView
)
Рисунок A *
Рисунок B
* Неясным кодом в Figure A
является:
@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!
Спасибо.
Раскадровка не распознавала какие-либо дополнительные пользовательские интерфейсы, которые я добавил к ней. Во время работы все ссылки были ноль. Поэтому я очистил папку с производными данными, а затем эти соединения снова работали.
Обычно это происходит потому, что ваш контроллер представления еще не загрузил свою иерархию представления. Контроллер представления загружает свою иерархию представления только тогда, когда что-то отправляет ему сообщение view
. Система делает это, когда пришло время фактически отобразить иерархию представлений на экране, что происходит после того, как такие вещи, как prepareForSegue:sender:
и viewWillAppear:
вернулись.
Так как ваш VC еще не загрузил свою иерархию представления, ваши выходы все еще равны нулю.
Вы можете заставить VC загрузить свою иерархию представлений, сказав _ = self.view
.
Вы пробовали работать с продуктом > Clean. Решил для меня очень похожую проблему.
Вы создавали экземпляр своего контроллера просмотра из раскадровки или NIB, или вы создавали его непосредственно через инициализатор?
Если вы создали экземпляр своего класса непосредственно с инициализатором, выходы не будут подключены. Интерфейс Builder создает индивидуальные экземпляры ваших классов и кодирует эти экземпляры в NIB и Storyboards для повторного декодирования, он не определяет сами классы. Если это была ваша проблема, вам просто нужно изменить код, в котором вы создаете свой контроллер, вместо этого используйте методы на UIStoryboard или UINib.
Это происходило со мной с моей ячейкой просмотра пользовательских коллекций. Оказывается, мне пришлось заменить свой метод registerClassforReuseIdentifier на registerNib. Это исправило это для меня.
В моем случае это произошло потому, что я переопределял метод loadView
в моем подклассе ViewController, но забыл добавить [super loadView]
-(void)loadView {
// blank
}
Когда вы переопределяете метод loadView
, ваша ответственность заключается в том, чтобы инициализировать свои подпрограммы. Поскольку вы переопределяете его, представления от конструктора интерфейса не получают возможности конвертировать в объекты cocoa, и, следовательно, выходы остаются нулевыми.
Если вы реализуете loadView в подклассе контроллера вида, тогда становится ответственностью загружать элементы пользовательского интерфейса из раскадровки /xib в код.
Или просто вызовите
[super loadView];
Так что суперкласс получит возможность загрузить раскадровку /xib в код.
Вы можете вызвать controller.view
, чтобы принудительно загрузить представление для инициализации IBOutlets, тогда вы сможете назначить значения.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "identifier") {
let controller = segue.destinationViewController as! YourController
let _ = controller.view //force to load the view to initialize the IBOutlets
controller.your_IBOutlet_property = xxx
...
controller.delegate = self
}
}
Это произошло для меня, потому что я случайно создавал экземпляр моего контроллера просмотра, а не создавал его через раскадровку. Если вы создаете экземпляр напрямую через MyViewController()
, то выходы не будут подключены.
Для меня это произошло, когда я случайно объявил свой класс контроллера вида
class XYZViewController: UINavigationController {
}
(т.е. как a UINavigationController
не a UIViewController
).
Xcode не подхватывает эту ошибку, класс, кажется, строит отлично, и переопределяет функции, такие как viewDidLoad
, viewWillAppear
и т.д. все работают правильно. Но ни один из IBOutlet
не подключается.
Изменение объявления на
class XYZViewController: UIViewController {
}
исправлено полностью.
Недавно я столкнулся с этой проблемой! Вот моя мысль. Проблема не в том, что вы раскадрой или какая-либо проблема с каналом. Речь идет о том, как вы инициируете свой ViewController. Особенно, когда вы используете Swift. (Когда вы создаете файл класса, в редакторе ничего не получается)
Просто используя init()
из суперкласса, вы не можете инициировать что-либо, что вы работали с доской. Итак, вам нужно изменить инициализацию ViewController. замещать
let XXViewController = XXViewController()
от
let XXViewController = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier("XXViewController") as! XXViewController
Это говорит программе, чтобы перейти к раскадровке найти XXViewController и инициирует все IBOutlet
в вашем раскадровке.
Надеемся на эту помощь ~ GL
Если вы создадите экземпляр view controller
программно. затем
попробуйте создать его, как показано ниже
let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC
вместо напрямую
let initialVC = InitialVC()
Это сработало для меня.
Для Swift 3.
func configureView() {
let _ = self.view
}
Сначала необходимо загрузить иерархию представлений, чтобы создать экземпляры в раскадровке. Для этого вы можете вручную вызвать методы loadView или loadViewIfNeeded.
В моем случае приложение неожиданно начало зависать.
Отладка показала, что все розетки все еще были nil
во время viewDidLoad()
.
Мое приложение по-прежнему использует перья (не раскадровки) для большинства контроллеров представления. Все было на месте, все розетки подключены правильно. Я дважды проверил.
Обычно мы создаем наши контроллеры вида как
let newVC = MYCustomViewController()
... который по какой-то причине кажется работающим до тех пор, пока .xib назван так же, как класс контроллера представления (хотя не уверен, как это работает. Мы не вызываем init(nibName:bundle:)
с нулевыми аргументами или переопределяем init()
сделать это на self
, как обычно предлагается...).
Поэтому я попытался явно позвонить
let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main)
... приветствуется только с ошибкой исключения во время выполнения:
*** Завершение работы приложения из-за невыполненного исключения "NSInternalInconsistencyException", причина: "Не удалось загрузить NIB в комплекте:" NSBundle & lt;/Users/nicolasmiari/Library/Разработчик /CoreSimulator/Devices/3DA3CF21-108D-498F-9649-C4FC9E3C1A8D данные/Контейнеры/Пачка/Применение /C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.app & GT; (загружен) 'с именем' MYCustomViewController ''
И тогда я увидел это:
Флажок "Целевое членство" в файле .xib не был установлен.
Это могло произойти при разрешении одного из частых конфликтов слияния, связанных с файлом проекта Xcode.
Apple определенно должна придумать формат файла проекта, который был бы более дружественным к SCM.
100% рабочее решение для создания ViewControllers из XIB без StoryBoards
7.1.
// creating instance
let controller = CustomViewController()
7.2.
// connecting view/xib with controller instance
let bundle = Bundle(for: type(of: controller))
bundle.loadNibNamed("CustomViewControllerView", owner: controller, options: nil)
7.3.
// get/set outlets
controller.labelOutlet.text = "title"
controller.imageOutlet.image = UIImage(named: "image1")
Проверьте соединение IBOutlet, если оно связано с владельцем файла или представлением. Там могут быть ошибки.
Другой случай:
Ваши выходы не будут установлены до тех пор, пока представление диспетчера представлений фактически не будет создано, что в вашем случае, вероятно, произойдет вскоре после initWithNibName: bundle: -at, в каком пункте они все равно будут nil. Любая настройка, которую вы делаете, которая включает эти выходы, должна происходить в вашем методе контроллера viewviewDoadLoad.
Для меня у меня была такая же ошибка на локализованной раскадровке, элемент был добавлен в какой-то локаль, а не в другой, поэтому у меня была нулевая ссылка для этого элемента при переключении на отсутствующий локаль элемента, мне пришлось удалить (избыточное ) для этой раскадровки с помощью fooobar.com/questions/91864/....
Для меня это сбой, потому что containerView
был нулем.
Вот мой код с Crash.
@IBOutlet private var containerView: UIView! // Connected to Storyboard
override open func loadView() {
containerView.addSubview(anotherView)
}
Недостающая вещь вызывала super.loadView()
. Поэтому добавление его для меня решило проблему.
Фиксированный код:
@IBOutlet private var containerView: UIView!
override open func loadView() {
super.loadView()
containerView.addSubview(anotherView)
}
У меня была аналогичная проблема, когда я ранее добавлял register (_: forCellReuseIdentifier:) для пользовательской ячейки после того, как я уже определил идентификатор в раскадровке. Имел этот код в функции viewDidLoad(). Как только я удалил его, он работал нормально.
Еще один случай, с которым я столкнулся. Я изменил имя моего класса для UIViewController, но я забыл изменить имя файла .xib, где был построен интерфейс.
Как только я поймал это и сделал имена файлов, отражают имя класса, все было хорошо!
Я надеюсь, что это поможет кому-то.
Есть еще один...
Если у вас есть пользовательский класс для UITableViewCell, но не забудьте указать Custom в стиле ячейки.
Вы можете проверить, загружен ли вид.
if isViewLoaded && view.window != nil {
//self.annotationOptionsView.
}
.h
и .m
для просмотра файлов контроллера.Я вижу, что вы используете ViewController
!? в ViewController
класс должен использовать -viewDidLoad
, не -awakeFromNib
, -awakeFromNib
использовать для UIView
class
Несчастливо Я подклассифицировал свой контроллер представления AVPlayerViewController
вместо UIViewController
. Переигрывая его с UIViewController
, все возвращается в нормальное состояние. Это должно помочь.
Нет очистки сборки (нормальный и полный), удаление папок с производными данными и выход из Xcode для меня.
У меня была такая же проблема после копирования класса (связанного с xib), чтобы повторно использовать его с другим классом viewcontroller (связанным с раскадрой). Я забыл удалить
override var nibName
и
override var nibBundle
методы.
После их удаления мои выходы начали работать.
Проверьте, нет ли у вас пропавших или отключенных розеток.
Если у вас есть два main.storyboards
и вы вносите изменения в неправильное, это может произойти. Это может произойти каждый раз, когда вы подключаете розетку от непредусмотренного storyboard
.
Допустим, у вас есть вид контейнера, который показывает какие-то часы. Итак, у вас есть
Класс Clock: UIViewController
Вы фактически используете его в нескольких местах в приложении.
На главном экране, на экране сведений, на экране редактирования.
У вас сложное современное приложение, похожее на Snapchat.
Clock
может быть загружен несколько раз в одно и то же время где-то на одном экране. (Может быть, это скрыто в некоторых случаях.)Вы начинаете работать над одним экземпляром Clock
на одной из ваших многочисленных раскадровок.
На этой раскадровке вы добавляете ярлык NewLabel.
Естественно вы добавляете розетку в код. Все должно работать. Все остальные магазины работают отлично.
Вы определенно связали розетку.
Но приложение вылетает с NewLabel равным нулю.
XCode четко говорит вам "вы забыли подключить розетку".
Авария на самом деле не из того места, где вы работаете, а из другой раскадровки, где на этой раскадровке нет элемента "NewLabel" !!!
Разочарование.