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

Я пытаюсь отправить данные через tabBarController.

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

Gif сбоя (ошибка в том, что диаграмма View равна нулю): http://i.imgur.com/VPa0RmK.gifv

Гиф успеха: http://i.imgur.com/LqxYBjV.gifv

Есть ли способ сделать это вручную?

Я новичок в программировании iOS, поэтому я думаю, что проблема в этом. Если что-то еще приводит к сбою моего кода, я бы хотел знать!

3
Wouter van Acht 27 Ноя 2016 в 16:30

2 ответа

Лучший ответ

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

Решения:

  1. Вы можете записать данные в свойство второго viewController, а затем переместить эти данные в розетку, переопределив viewWillAppear.

  2. Другая возможность - проверить, является ли выход nil, прежде чем писать на него. Если это так, вызовите loadView на втором viewController, чтобы сообщить ему, что нужно настроить свои выходы, и тогда вы сможете писать им. Обратите внимание: если вы вызовете loadView вручную, метод viewDidLoad не будет запущен, поэтому, если вы выполняете какие-либо дополнительные настройки, вам также нужно будет сделать это из loadView .

  3. Возможно, даже проще, чем вызов loadView вручную, - это вызвать viewDidLoad второгоViewController, обратившись к свойству view. Это может быть очень просто:

    if let svc = self.tabBarController?.viewControllers?[1] as? SecondViewController {
        // check if outlet is nil
        if svc.myLabel == nil {
            // trigger viewDidLoad to set up the outlets
            _ = svc.view
        }
        svc.myLabel = "Success!"
    }
    
  4. Тем не менее, прямой доступ к представлениям другого viewController (т. Е. Выходам) - это плохой дизайн и нарушение парадигмы MVC (Model-View-Controller). Вы действительно должны поместить свои данные в место, доступное для всех вкладок, а затем обновить каждый viewController в viewWillAppear, когда вкладка выбрана. См. Этот ответ: Совместное использование данных в TabBarController как один из способов сделать это.

3
Community 23 Май 2017 в 11:59

Вот как это должно работать. Каждая вкладка создается только тогда, когда она должна отображаться. Это та же идея для TableViews и CollectionViews.

Самый простой способ исправить это для вас - это переопределить метод viewWillAppear (или viewDidAppear) вашего HistoryViewController и обновить пользовательский интерфейс оттуда.

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

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

0
Sonastra 27 Ноя 2016 в 14:10