@FlooDwm

Передать данные между контроллерами программно?

Есть HomeViewController и NextViewController как передать переменную из первого во второй без использования storyboard и segue ( и как обратно из второго в первый), переменная передана должна быть до загрузки viewDidLoad()
Переход осуществляется так
func handleSearch(){
        navigationController?.pushViewController(AlfavitController(), animated: true)
    }

User Default, Data Core не предлагать.
Если возможно то с примером, а не просто ответ типо (пользуй делегаты, читай про синглтон)
ЗА РАНЕЕ СПАСИБО БОЛЬШОЕ ВСЕМ КТО ПОМОЖЕТ!!!
  • Вопрос задан
  • 6092 просмотра
Решения вопроса 4
@iFamily
Expert in Server-Side-Swift and iOS development
Если пользуешься storyboard, тогда передать данные можно через prepareForSegue

Допустим у тебя есть NextViewController с переменной name: String
class NextViewController: UIViewController {
    var name: String!
}

и тебе нужно в него передать имя, тогда в prepareForSegue есть два способа детектить переход на NextViewController:

1. Если у нас имеется только один переход на NextViewController или их много с разных кнопок, но данные всегда одинаковые
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let dest = segue.destination as? NextViewController {
        dest.name = "Jessica"
    }
}


2. Если у нас имеются разные переходы на NextViewController и набор передаваемых данных различается
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let dest = segue.destination as? NextViewController {
        if segue.identifier == "action1" {
            dest.name = "Jessica"
        } else if segue.identifier == "action2" {
            dest.name = "Jessica"
            dest.sex = "female"
        }
    }
}


В случае если программно создаете переход, то еще проще все. Снова два варианта как достучаться до NextViewController:

1. Он находится на storyboard
let dest = storyboard?.instantiateViewController(withIdentifier: "NextViewController") as! NextViewController


2. Или он не на storyboard...
let dest = NextViewController(nibName:"NextViewController", bundle: nil)


Дальше прикрепляем данные

dest.name = "Jessica"

И два варианта как открыть NextViewController:

1. При наличии navigationController'a
navigationController?.pushViewController(dest, animated: true)


2. Просто модальным окном
dest.modalPresentationStyle = .fullScreen
dest.modalTransitionStyle = .coverVertical
present(dest, animated: true, completion: nil)


Чтобы обратно из второго в первый данные передавать, можно использовать delegate или notifications.

Если делегаты
protocol NextViewControllerDelegate {
    func callback(_ someString: String)
}

class NextViewController: UIViewController {
    var name: String!
    var delegate: NextViewControllerDelegate?

    func someMethod() {
        delegate?. callback("delegate callback")
    }
}

//Тут контроллер из которого открываем CustomViewController, нам помимо name нужно теперь еще задать delegate=self

class HomeViewController: UIViewController, NextViewControllerDelegate {
   override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let dest = segue.destination as? NextViewController {
            dest.name = "Jessica"
            dest.delegate = self
        }
    }

    //MARK: NextViewControllerDelegate
    func callback(_ someString: String) {
        print("got callback with string: \(someString)")
    }
}


Если notifications
let kNotifNextViewControllerCallback = NSNotification.Name(rawValue: "kNotifNextViewControllerCallback")

class NextViewController: UIViewController {
    var name: String!

    func someMethod() {
        NotificationCenter.default.post(name: kNotifNextViewControllerCallback, object: "notification text")
    }
}

//Тут HomeViewController из которого открываем CustomViewController, мы в нем будем слушать kNotifNextViewControllerCallback в метод gotNotification

class HomeViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NotificationCenter.default.addObserver(self, selector: #selector(gotNotification(notification:)), name: kNotifNextViewControllerCallback, object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let dest = segue.destination as? NextViewController {
            dest.name = "Jessica"
        }
    }

    //MARK: Notification observer
    func gotNotification(notification: Notification) {
        print("got notification with object: \(notification.object)")
    }
}
Ответ написан
Комментировать
ManWithBear
@ManWithBear
Swift Adept, Prague
Magic:
func handleSearch() {
    navigationController?.pushViewController(AlfavitController(with: Magic), animated: true)
}


UPD. Очень смешной прикол

UPD2.
1. Берем вью контроллер, у которого есть какая-то зависимость (читать как "переменная, которую ему нужно передать")
2. Создаем ему инициализатор с параметром в виде этой зависимости
3. Создаем контроллер с помощью этого инитиализатора
4. Пушим его
5. ???
6. PROFIT
Ответ написан
@FlooDwm Автор вопроса
Нашел 1 решение использование структуры со статик переменной
struct Manager {
static var id = String()
}
ЕСТЬ ЛИ ЕЩЕ РЕШЕНИЯ???
Ответ написан
Комментировать
briahas
@briahas
ObjC, Swift, Python
Так как viewDidLoad вызывается когда ты запрашиваешь какуюто вьюху с контроллера (даже если его еще ни разу не показывали) то:
  1. У контроллера прописываешь пропертиlet myValue : someType?
  2. Инстантиейтишь контроллер
    let myVC = myStoryboard.instantiateViewController(withIdentifier: "myVC") as! myVC

  3. Сетапиш контроллеру пропертюmyVC.myValue = someValue
  4. Пушиш контроллер
  5. ....Профит
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы