Быстрая навигация от третьего ViewController к первому ViewController

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
    let vc = storyboard?.instantiateViewController(identifier: 
    "PersonViewController") as? PersonViewController               
    
    vc?.names = persons[indexPath.row].emer!
    vc?.lastnames = persons[indexPath.row].mbiemer!
    vc?.delegate = self
    PersonViewController.indexes = indexPath.row 
    self.navigationController?.pushViewController(vc!, animated: true)

}`

У меня бывают такие ситуации:

Первый ViewController — это collectionView, второй — это viewcontroller, которому разрешено добавлять нового человека, когда я нажимаю кнопку, и он отлично работает. Я использовал делегатов и Core Data для локальной памяти.

Также у второго ViewController есть еще одна кнопка для редактирования человека. Когда я нажимаю кнопку, появляется новый viewController с расширением UIAdaptivePresentationControllerDelegate. Этот контроллер представления состоит из 2 кнопок и 2 текстовых полей. Поэтому, когда я хочу нажать кнопку «Сохранить», я хочу перейти к первому контроллеру представления (списку представлений коллекции), а когда нажать «Отмена», вернуться ко второму контроллеру представления.

Контроллеры представления создаются с помощью метода pushViewController.

изображение

Пожалуйста, помогите, что мне использовать?

затем в PersonViewController я вызываю это редактирование внутренней кнопки.

@objc func editCell(){
    let vc = storyboard?.instantiateViewController(identifier: 
    "ModalPresentationViewController") as? 
     ModalPresentationViewController

     navigationController?.pushViewController(vc!, animated: true)
    
}

Теперь код в las ViewController, который является ModalViewController

@objc func savePerson(){
    if editNameTextfield.text == "" || editlastNameTextfield.text == ""{
        self.errorLbl.alpha = 1
    }
    else{
        let vc = ViewController()
        guard let textName = editNameTextfield.text else{
            return
        }
        guard let textLastName = editlastNameTextfield.text else{
            return
        }

        let index = PersonViewController.indexes
        DispatchQueue.main.async {[self] in
            if editDelegate != nil{
                self.editDelegate!.editPerson(editedName: textName, editedLastname: textLastName, index: index)
            }
        }
//            What should I call here??
       
    }
}

person Donald Cela    schedule 08.11.2020    source источник
comment
теперь он отредактирован. Я просто хочу руководство, что использовать, чтобы решить эту проблему   -  person Donald Cela    schedule 08.11.2020
comment
Вы обрабатываете навигацию с помощью кода или используете переходы в раскадровке?   -  person DonMag    schedule 08.11.2020
comment
Так в чем проблема? popToViewController позволяет вам вернуться к любому контроллеру представления, который вы хотите. developer.apple.com/documentation/uikit/uinavigationcontroller/   -  person matt    schedule 08.11.2020
comment
Нет, я не использую переходы. В ViewController просто вставьте контроллер навигации и используйте идентификатор раскадровки для отправки в другой ViewController. Также все представления в 3 ViewControllers создаются кодом не в Main.storyboard.   -  person Donald Cela    schedule 08.11.2020
comment
Не удается сохранить данные с помощью popToViewController. Мне удалось сохранить данные только с помощью popViewController, но этот метод возвращает меня к предыдущему экрану, а не к первому.   -  person Donald Cela    schedule 08.11.2020
comment
Вы пробовали popToRootViewController? Кстати, если вы не используете Segues, это означает, что у вас должно быть достаточно кода, который вы могли бы опубликовать, вместо нарисованного от руки объяснения. Было бы очень полезно фактически дублировать любую проблему, с которой вы столкнулись. Разберитесь — похоже, у вас есть 4 VC... A, B, C и навигационный контроллер. Добавьте минимальную логику/представления к каждому для дублирования. Разместите это.   -  person dfd    schedule 08.11.2020
comment
Я вставил код!   -  person Donald Cela    schedule 08.11.2020


Ответы (1)


Вы можете использовать что-то вроде:

func popTo(_ type: AnyClass) {
    guard let controllers = navigationController?.viewControllers else {return}
    
    for controller in controllers {
        if controller.classForCoder == type {
            navigationController?.popToViewController(controller, animated: true)
            break
        }
    }
}

И вызовите функцию в зависимости от условия как:

popTo(A.classForCoder())

EDIT: Приведенное выше решение работает только в том случае, если ViewControllers B и C представлены через навигационный контроллер и находятся в одном и том же навигационном стеке.

Поскольку вы представляете ViewController C модально, ответ ниже должен работать:

Внесите эти изменения в свой ViewController B, который представляет C:

class B: UIViewController, PresenterDelegate {
// some functions

    func popToPrevious() {
        navigationController.popViewController(animated: false)
    }

    @objc func editCell(){
        let vc = storyboard?.instantiateViewController(identifier: 
        "ModalPresentationViewController") as? 
         ModalPresentationViewController
        vc.presenterDelegate = self

        present(vc, animated: true, completion: nil)

    }
}

И в вашем ViewController C:

class C {
    var presenterDelegate: PresenterDelegate? = nil

    //

    @objc func savePerson(){
        //
        //
        dismiss(animated: true, completion: {
            self.presenterDelegate?.popToPrevious()
        })
    }
}

Также добавьте протокол PresenterDelegate в новый файл или ниже ViewControllers B или C.

protocol PresenterDelegate {
    func popToPrevious()
}
person Buğra Cansın Göz    schedule 09.11.2020
comment
Спасибо за ваш ответ, это хорошая идея, но я все еще не могу добраться до A ViewController. Я пробовал много подобных решений. Проблема в том, что я забыл упомянуть, что эту функцию я вызываю внутри завершения закрытия, потому что C-ViewController является существующим модальным окном. Так что каждое решение возвращает меня к B-View Controller. Я пробовал также с popToRootViewController, но все равно ничего - person Donald Cela; 09.11.2020
comment
Это именно то, в чем заключается моя проблема с stackoverflow.com/questions/44669698/, но у меня все еще не работает - person Donald Cela; 09.11.2020
comment
Привет, Дональд, поскольку вы указали PushVC между B и C на своей диаграмме, это решение было основано на предположении, что A, B, C находятся в одном и том же навигационном стеке. Я отредактирую свой ответ. - person Buğra Cansın Göz; 09.11.2020
comment
да, моя ошибка от B до C -> настоящее не нажать - person Donald Cela; 09.11.2020
comment
Внес изменения, дайте знать :) - person Buğra Cansın Göz; 09.11.2020
comment
Решено! Это было гениально! Большое спасибо! - person Donald Cela; 09.11.2020
comment
За исключением случаев, когда вызов отклоняет анимацию, лучше, чтобы она была ложной: p - person Donald Cela; 09.11.2020
comment
Да, я вообще не обращал внимания на анимацию :) Буду признателен, если вы примете мой ответ, чтобы сообщество тоже могло извлечь из этого пользу. - person Buğra Cansın Göz; 09.11.2020
comment
Извините, первый раз задаю вопрос, у меня получилось - person Donald Cela; 09.11.2020