Storyboard instantiateViewControllerWithIdentifier не устанавливает IBOutlets - программирование
Подтвердить что ты не робот

Storyboard instantiateViewControllerWithIdentifier не устанавливает IBOutlets

Я использую раскадровку instantiateViewControllerWithIdentifier:, и я замечаю, что все IBOutlets, которые я подключил, все еще ноль. Тем не менее, IBActions у меня есть проводная работа. Вид и контроллер связаны (например, controller.view не равен нулю), и если я покажу, что это отображает то, что я ожидаю.

Что мне не хватает?

Здесь моя настройка:

  • У меня есть контроллер просмотра, определенный в моей раскадровке. Я дал ему идентификатор, который является тем же самым идентификатором, который я использую при вызове instantiateViewControllerWithIdentifier:
  • Я установил владельца представления, нажав на контроллер просмотра (только при первом ответчике), и в разделе "Идентификационный инспектор" для параметра "Пользовательский класс" укажите то же имя, что и класс, к которому я хочу подключить представление.
  • Затем я открываю редактор помощника, и управление перетаскивает элементы интерфейса для создания IBOutlets и IBActions.
4b9b3361

Ответ 1

Кажется, что представление корректно инициализировано только после первого обращения. Проблема исчезает при вызове

[self presentViewController:vc animated:NO completion:nil];

или более просто

[vc view];

Ответ 2

[Используйте меня как плохой пример]

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


У меня была одна и та же проблема, однако пользовательский компонент, который я создал, не загружается через presentViewController (загрузка в оверлее к предыдущему виду)

Вы можете просто вызвать

myViewController.loadView()//Swift

[myViewController loadView]//Obj-C

Ответ 3

Настройка рамки для созданного экземпляра ViewController, похоже, устанавливает IBOutlets.

Пример:

DemoViewController *demoVC = [[self storyboard] instantiateViewControllerWithIdentifier:@"demoVC"];
demoVC.frame = self.view.frame; //or CGRectMake(0, 0, 1015, 604);

Это приведет к инициализации IBOutlets DemoViewController, таких как Label, TextField, Button, Table и т.д.

Надеюсь, что это поможет.

Ответ 4

Розетки установлены с помощью кодирования ключевых значений, вы можете поместить это в свой подкласс контроллера представления:

- (void)setValue:(id)value forKeyPath:(NSString *)keyPath {
    [super setValue:value forKeyPath:keyPath];
}

- (void)setValue:(id)value forKey:(NSString *)key {
    [super setValue:value forKeyPath:key];
}

И поставьте точку останова на два вызова супер.

В отладчике я попробую:

  • Сравнивая "я" с контроллером представления, вы считаете, что применяете выходы. Возможно, у вашей раскадровки есть второй контроллер просмотра, которого вы не ожидаете. Когда вы сказали, что создали своего владельца, я подумал, что это странная терминология. Вы перетащили один из объектов куба, чтобы представить свой контроллер представления в дополнение к уже существующему представлению?

  • Сравните [self valueForKey: key] или [self valueForKeyPath: keyPath] или просто [self outletName] с переданным значением после вызова до супер. Возможно, у вас есть сеттер, который не делает то, что вы намереваетесь. Я видел такую ​​ошибку, как это происходит пару раз, когда у людей есть выход для объекта с именем типа firstName, а затем действие с селектором "setFirstName:". Это смущает кодирование ключевых значений, и вы получаете setFirstName: получение вызова во время загрузки nib с целью установления выхода, но установщик для выхода реализован как метод действия, поэтому выход никогда не устанавливается.

Ответ 5

Если объект, на который вы ссылаетесь, является объектом верхнего уровня в сцене, например ArrayController, ссылка должна быть сильной (не слабой!), поскольку она не сохраняется иерархией представления. Слабая ссылка может вызвать проблему, как то, что вы описываете.

Посмотрите дополнительную информацию: Должны ли IBOutlets быть сильными или слабыми при ARC?

Ответ 6

Люди дали решение о том, как загрузить просмотр (некоторые из которых вы никогда не должны использовать (loadView()), поэтому здесь можно проверить, загружено ли ваше представление

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

var name: String? {
    didSet {
        updateNameLabel()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    updateNameLabel()
}

func updateRoomLabel() {
    guard isViewLoaded() else {
        return
    }
    [...]
}

Итак, теперь, когда вы показываете, что розетки обновляются, но также каждый раз, когда вы обновляете свойство