Невозможно обновить встроенный дочерний VC из неродительского VC

Обновите Xcode/Swift/iOS.

У меня есть главный VC (называемый StartVC), который содержит дочерний VC (называемый TopBarVC) через встроенный переход. Дочерний VC содержит кнопку, которая при нажатии модально переходит к 3-му VC (называемому CategoryPickerOverlayVC) (представление в этом VC служит раскрывающимся списком для выбора категории).

    @IBAction func CategoryFilterButtonPressed(_ sender: Any) {

    performSegue(withIdentifier: "toCategoryPickerOverlay", sender: self)

}

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

В ведущем VC я использую prepareforsegue для сохранения ссылки на дочерний VC в переменной - "topBarReference" - в момент, когда происходит переход к встраиванию.

 var topBarReference: TopBarVC?


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        
    if segue.identifier == "TopBarPane"{
        topBarReference = segue.destination as? TopBarVC
    }
}

Затем, в 3-м VC, когда я нажимаю на один из вариантов кнопки в раскрывающемся списке, заголовок кнопки отправляется через prepareforsegue для обновления кнопки в дочернем VC (через "topBarReference").

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC

        vc.topBarReference?.filterButtonText = ((sender as! UIButton).titleLabel?.text)!

    }

Затем 3-й виртуальный канал разворачивается обратно к главному виртуальному каналу. Я должен добавить, что когда кнопка в дочернем VC изменена, переменная (filterButtonText) в дочернем VC сначала устанавливается с текстом заголовка, а затем эта переменная затем используется для установки текста заголовка кнопки с помощью метода viewDidAppear дочернего VC.

При использовании отладчика я также отмечаю, что viewDidAppear в Master VC, похоже, не выполняется после раскручивания (я поместил диагностическую печать на консоль в viewDidAppear, и после раскручивания ничего не печатается). Я понимаю, что это объясняет, почему кнопка не обновляется, но я понятия не имею, почему viewDidAppear не запускается.

Я также пытался использовать протокол делегата и instanceiateViewController(withString:) безрезультатно. Все методы приводят к одному и тому же результату: кнопка в дочернем VC не обновляется. Ошибки не отображаются. Все остальное происходит так, как ожидалось.

Любые идеи относительно того, что я делаю неправильно?


person Rossco    schedule 21.01.2017    source источник
comment
если оба они встроены в StartVC, то есть StartVC все еще виден, то представление не будет вызываться. Попробуйте использовать уведомления. Заставьте ваш startVC прослушивать конкретное уведомление и отправлять его, когда вы раскручиваете / выбираете вариант из раскрывающегося списка. Внутри кода обработчика уведомлений обновите заголовок кнопки.   -  person Shawn Frank    schedule 21.01.2017
comment
Третий виртуальный канал — это отдельный виртуальный канал, а не встроенный.   -  person Rossco    schedule 21.01.2017
comment
Я понятия не имею, почему viewDidAppear не запускается, потому что он никогда не исчезал. Я думаю, это то, что @ShawnFrank вам тоже сказал.   -  person matt    schedule 21.01.2017
comment
@Rossco, чтобы попробовать комментарий Шона Фрэнка, вы можете протестировать в методе Master VC viewDidDisappear, если он выполняется при выполнении перехода.   -  person aircraft    schedule 21.01.2017
comment
@Shawn Frank: Спасибо за ответ - я еще не использовал уведомления (хотя я знаю о них), поэтому в какой-то момент поищу это. Я был уверен, что мой исходный код ДОЛЖЕН работать, поэтому искал кого-то, кто указал бы, почему это не так, вместо того, чтобы сразу переходить к изменению механизма обновления текста кнопки.   -  person Rossco    schedule 21.01.2017
comment
@Matt: Шон спрашивал (как я это интерпретировал), были ли и Child, и 3rd VC встроены в Master VC, что не так. Третий VC был отдельным VC, отображаемым поверх всего остального через модальный переход, так почему бы не исчезнуть представление Master VC? Это какой-то аспект модальных переходов, о котором я еще не знаю? Фон 3-го VC был установлен прозрачным - возможно, это означает, что представление Start VC за представлением Child VC не исчезает само по себе, и, следовательно, viewDidAppear из Start VC не срабатывает, когда 3-й VC исчезает через раскрутку перейти?   -  person Rossco    schedule 21.01.2017


Ответы (2)


Вы имеете в виду что-то вроде этого?

введите здесь описание изображения

Если да, то решение, которое я использовал, было очень простым: третий VC использует prepareForSegue для установки свойства встроенного VC, а встроенный VC выбирает это свойство в методе unwind.

В моей реализации три контроллера представления называются ViewController, ChildViewController и ThirdViewController. Это весь код (все остальное настраивается в раскадровке):

class ChildViewController: UIViewController {

    @IBOutlet weak var theButton: UIButton!
    var buttonTitle : String?

    @IBAction func unwind(_:UIStoryboardSegue) {
        self.theButton.setTitle(self.buttonTitle, for: .normal)
    }

}
class ThirdViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        (segue.destination as! ChildViewController).buttonTitle = (sender as! UIButton).currentTitle
    }

}
person matt    schedule 21.01.2017

Итак, я обнаружил, что мой исходный код работает нормально, за исключением одной строки в prepareforsegue дочернего VC. Если я изменю этот prepareforsegue с:

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC
        vc.topBarReference?.CategoryFilterButton.titleLabel?.text = ((sender as! UIButton).titleLabel?.text)!

    }

к этому:

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC
        vc.topBarReference?.CategoryFilterButton.setTitle((sender as! UIButton).titleLabel?.text, for: .normal)

    }

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

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

Поскольку мое маленькое «открытие» приравнивается к наименьшему изменению исходного кода, я отмечу это как ответ.

Спасибо всем, что нашли время ответить!

person Rossco    schedule 21.01.2017