Лучше практиковать выполнение SeguWithIdentifier или presentViewController - PullRequest
0 голосов
/ 01 июня 2019

Если я использую раскадровки, лучше практиковать создание перехода и использовать executeSegueWithIdentifier или просто использовать presentViewController для перемещения пользователя из одного View Controller в следующий.

Для этого примера давайте предположим, что мыиспользуя Swift 5 и у меня есть 2 контроллера представления: TableView of Contacts на MainViewController и детали этого Contact на DetailViewController.

В своем коде я использую presentViewController, но, поскольку я новичок в разработке для iOS, яЯ не уверен, что это лучший подход.

Ответы [ 2 ]

2 голосов
/ 02 июня 2019

Для иллюстрации предположим, что ситуация в раскадровке следующая:

ViewController1
    |----> modal segue "toVC2" emanating from ViewController1
        |----> ViewController2, identifier "VC2"

Тогда в коде ViewController1 нет абсолютно никакой функциональной или эффективной разницы между этими двумя вещами:

  • Звоните performSegue с идентификатором "toVC2"
  • Позвоните instantiateViewController на раскадровку с идентификатором "VC2" и позвоните present

Сказав это, я приведу аргументы в пользу того, что каждый способ "лучше", чем другой.

Почему результат может быть лучше

Последовательность в моем примере выглядит не намного лучше, потому что мы все еще должны использовать код для вызова performSegue. Однако предположим, что переход исходит не от контроллера вида, а от кнопки в виде контроллера вида. Это действие segue, и теперь оно будет выполняться автоматически , когда пользователь нажимает на нашу кнопку, с кодом , необходимым для его выполнения. Вам даже не нужно знать идентификатор. (Строковые идентификаторы - отличный способ ошибиться.)

Почему instantiate и present могут быть лучше

В сегментах segues есть что-то очень ужасное, будь то последовательность действий или сценарий, запускаемый вручную с помощью performSegue, а именно, когда (как это часто случается) вы хотите передать данные с первого контроллера представления на второй. Если вы используете segue, вы должны выполнить передачу данных в реализации prepare(for:sender:). Это очень грязно, потому что вы должны проверить идентификатор сегмента и привести целевой класс к правильному классу. Более того, если есть более одного перехода, prepare становится грязным узким местом. И если мы также назвали performSegue, мы работаем в двух разных местах - метод, в котором мы назвали performSegue, и отдельная реализация prepare.

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

Кроме того, это может показаться очевидным, но хорошо сказать, что present заключается в том, что это прямо говорит нам в коде, что переход равен . Если вы просто используете идентификатор сегмента, тот факт, что это модальный переход, скрыт в раскадровке.

Что я предпочитаю?

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

Так я говорю, что раскадровки не годятся?

Нет. Раскадровки имеют свойство отображать структуру сцены вашего приложения, особенно если вы используете сегменты. Однако, если вы не собираетесь использовать переход к контроллеру представления, то я не вижу смысла сохранять этот контроллер представления в раскадровке. Механизм одноимённого кончика становится чище и чище. Более того, я рассматриваю механизм prepare(for:sender:) как почти фатальный недостаток во всей архитектуре раскадровки; огромное количество ошибок, показанных в переполнении стека, является следствием этого недостатка.

[ EDIT Обратите внимание, что многие из моих возражений против сегментов отпадут в iOS 13, где контроллер представления источника сможет использовать код для вызова инициализатора контроллера представления назначения.]

0 голосов
/ 01 июня 2019

Они оба делают одно и то же, но я обычно использую Present, поэтому, когда я хочу, например, изменить поведение, заставить кнопку открыть другой VC, я просто меняю идентификатор, мне не нужно удалять переход исоздать новый.Также многие сегменты сделают вашу раскадровку похожей на спагетти

...