IBOutlet равен нулю, но он подключен в раскадровке, Swift



использование Swift 1.1 и Xcode 6.2.



у меня есть UIStoryboard, содержащий сингулярный, пользовательский UIViewController подкласс. На нем, у меня есть @IBOutlet подключение типа UIView от этого контроллера к UIViewподкласс на раскадровке. У меня также есть аналогичные выходы для подвидов этого представления. См. рисунок А.



но во время выполнения эти свойства равны нулю (рисунок B). Хотя я заверил, что подключил розетки в интерфейсе Строитель.



мысли:




  • возможно ли, что из-за того, что я использую подкласс подкласса что-то путает с инициализацией? Я не переопределяю инициализаторы


  • awakeFromNib: не вызывается по какой-то причине

  • может быть, он не подключается к subviews на subviews


вещи, которые я пробовал:




  • соответствующего @IBOutlet и пункта раскадровка набирает ровно (вместо UIView)

  • удаление свойства и розетки и повторно добавил их


Figure A



Рисунок A*



Figure B



Рисунок B



*скрытый код в Figure A - это:



@IBOutlet private var annotationOptionsView: UIView!
@IBOutlet private var arrivingLeavingSwitch: UISegmentedControl!


спасибо.

575   28  

28 ответов:

обычно это происходит потому, что ваш контроллер представления еще не загрузил свою иерархию представлений. Контроллер представления загружает свою иерархию представлений только тогда, когда что-то отправляет ему view сообщение. Система делает это, когда пришло время фактически поместить иерархию представлений на экран, что происходит после таких вещей, как prepareForSegue:sender: и viewWillAppear: вернулись.

поскольку ваш VC еще не загрузил свою иерархию представлений, ваши выходы по-прежнему равны нулю.

вы можете заставить VC загружаться его иерархия представления, говоря _ = self.view.

вы пробовали запустить продукт > очистить. Решил очень похожую проблему для меня.

вы создали экземпляр контроллера вида из раскадровки или пера, или вы создали его непосредственно через инициализатор?

Если вы создали экземпляр класса непосредственно с инициализатор, розетки не подключены. Interface Builder создает настроенные экземпляры ваших классов и кодирует эти экземпляры в NIBs и раскадровки для повторного декодирования, он не определяет сами классы. Если это была ваша проблема, вам просто нужно изменить код, где вы создайте свой контроллер, чтобы вместо этого использовать методы на UIStoryboard или UINib.

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

в моем случае это произошло потому, что я переопределил loadView метод в моем подклассе ViewController, но забыл добавить [super loadView]

-(void)loadView {
// blank
}

при переопределении loadView метод, это ваша ответственность, чтобы инициализировать ваш подпанелей. Поскольку вы переопределяете его, представления из interface builder не получают возможности конвертировать в объекты cocoa и, таким образом, выходы остаются нулевыми.

если вы реализуете loadView в своем подклассе контроллера вида, то это становится вашей ответственностью загрузить элементы пользовательского интерфейса из раскадровки/xib в код.

или просто позвоните

[super loadView];

так что суперкласс получает возможность загрузить раскадровку / xib в код.

Это происходило со мной с моей пользовательской ячейкой представления коллекции. Оказывается, мне пришлось заменить мой метод registerClassforReuseIdentifier на registerNib. Это исправило все для меня.

можно назвать 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 {
}

(т. е. как UINavigationController Не a UIViewController).

Xcode не подхватывает эту ошибку, класс, похоже, отлично строится и переопределяет такие функции, как viewDidLoad,viewWillAppear и т. д. все работают правильно. Но ни один из IBOutlets подключиться.

изменения декларация

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

Для Swift 3.

func configureView() {
    let _  = self.view
}

проверьте соединение IBOutlet, если оно подключено к владельцу файла или представлению. Здесь могут быть ошибки.

другой случай:

ваши розетки не будут установлены до тех пор, пока представление контроллера вида не будет фактически создано, что в вашем случае, вероятно, произойдет вскоре после initWithNibName:bundle:-в этот момент они все равно будут равны нулю. Любая настройка, которую вы делаете, которая включает эти розетки, должна происходить в методе View controller-viewDidLoad.

для меня у меня была такая же ошибка на локализованной раскадровке, элемент был добавлен в какой-то локали, а не в другой, поэтому у меня была нулевая ссылка на этот элемент при переключении на отсутствующий элемент locale, мне пришлось удалить (избыточную) локализацию для этой раскадровки с помощью https://stackoverflow.com/a/42256341/1356559.

вам нужно сначала загрузить иерархию представлений, чтобы создать экземпляры розеток в раскадровке. Для этого можно вручную вызвать методы loadView или loadViewIfNeeded.

для меня это был сбой, потому что containerView отсутствовала.

вот мой код авария.

@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)
}

еще один случай, с которым я только что столкнулся. Я изменил имя моего класса для UIViewController, но я забыл изменить имя .xib файл, в котором был построен интерфейс.

Как только я поймал это и сделал имена файлов отражают имя класса, все было хорошо!

Я надеюсь, что это кому-то поможет.

есть еще один ...

Если у вас есть пользовательский класс для UITableViewCell, но вы забыли указать пользовательский стиль ячейки.

вы можете проверить, загружено ли представление is.

if isViewLoaded && view.window != nil {
 //self.annotationOptionsView.
}
  1. выберите .h и .m просмотр файлов контроллера
  2. удалить ссылку на эти файлы
  3. повторно добавьте файлы в дерево проекта
  4. откройте раскадровку, в конечном итоге заново построить проект

случайно Я подкласс моего контроллера вида с AVPlayerViewController вместо UIViewController. Путем воспроизведения его в UIViewController все в норме. Это должно помочь.

нет очистки сборки (normal&full), удаление папок производных данных и выход из Xcode работал для меня.

у меня была такая же проблема после копирования класса (связанного с xib), чтобы повторно использовать его с другим классом viewcontroller (связанным с раскадровкой). Я забыл удалить

override var nibName

и

override var nibBundle

методы.

после удаления их, мои розетки начали работать.

У меня была аналогичная проблема, когда я ранее добавил register(_:forCellReuseIdentifier:) для пользовательской ячейки после того, как я уже определил идентификатор в раскадровке. Имел этот код в функции viewDidLoad (). Как только я удалил его, он работал нормально.

Я вижу, вы используете ViewController!? в

проверьте, есть ли у вас отсутствующие или отключенные розетки.

enter image description here

Если у вас есть два main.storyboards и вы вносите изменения в неправильный это может произойти. Это может произойти в любое время, когда вы подключаете розетку из деинсталлированного storyboard.

Если вы создаете экземпляр view controller через программно. Затем попробуйте создать его, как показано ниже

let initialVC = self.storyboard?.instantiateViewController(withIdentifier: "InitialVC") as! InitialVC
напрямую
let initialVC = InitialVC()

это работает для меня.

в моем случае приложение внезапно начало рушиться. Отладка показала, что все розетки были еще nil во время viewDidLoad().

мое приложение все еще использует крупка (не раскадровки) для большинства вид контроллеров. Все было на месте, все розетки подключены правильно. Я дважды проверил.

мы обычно создаем наши контроллеры представления как

let newVC = MYCustomViewController()

...который по какой-то причине, кажется, работает так долго, как .xib называется так же, как и вид контроллера класса (не уверен, как это работает, хотя. Мы не вызов init(nibName:bundle:) с нулевыми аргументами, или переопределение init() на self как это обычно...).

поэтому я попытался явно вызвать

 let newVC = MYCustomViewController(nibName: "MYCustomViewController", bundle: .main)

...только для приветствия с ошибкой исключения во время выполнения:

*** прекращение приложения из-за необработанных исключений 'NSInternalInconsistencyException', причина: 'не удалось загрузить СИБ в пачке: 'NSBundle /nicolasmiari/Library/Developer/CoreSimulator/Devices/3DA3CF21-108D-498F-9649-C4FC9E3C1A8D/data/Containers/Bundle/Application/C543DDC1-AE86-4D29-988C-9CCE89E23543/MyApp.приложение> (загружено) 'с именем 'MYCustomViewController"

и затем, я увидел это:

флажок "целевое членство".xib файл был снят.


должно быть, произошло при разрешении одного из частых слияний конфликты, связанные с файлом проекта Xcode.

Яблоко наверняка необходимо придумать формат файла проекта, который более удобен для SCM.

Comments

    Ничего не найдено.