передача данных между viewControllers в tabController в быстрой последовательности событий - PullRequest
0 голосов
/ 25 мая 2018

У меня есть UITabController Main, в котором есть два UIViewController, A и B. В раскадровке.Каждый контроллер имеет соответствующий класс swift, Main, A, B

Main.swift является подклассом UITabController и делегатом UITabBarControllerDelegate.В своем viewDidLoad он устанавливает свой .delegate = self.

В функции main в tabBarController (_ tabBarController: UITabBarController, didSelect viewController: UIViewController) Я фиксирую выбранную вкладку и предпринимаю действия, чтобы установить какое-либо значение данных, которое я хочу использоватьпередать переменную выбранного viewController Y.

В классах ViewController A и B существует объявление var для переменной Y.

В каждом ViewController A и B, в viewWillAppear, я заполняюлокальные настраиваемые выходы вида из этой переменной Y.

Причина, по которой это не работает, связана с порядком обработки событий.

Я предполагал, что когда я нажимаю вкладку, вкладка MainBabController в MainФункция сначала обрабатывается, а затем обрабатывается выбранный соответствующий viewWillAppear viewController.Это не тот случай.

Очевидно, сначала выполняется выбранный (A или B) viewWillAppear viewController, а затем срабатывает tab MainBarController.Это, конечно, вызывает проблему, потому что я отображаю торговые точки, заполненные буквой Y, а затем я заполняю Y ...

Этот метод для того, чтобы Main заполнял A или B некоторыми данными, предпочтителен, потому что A и B не должны ничего знатьдруг о друге.Но Мэйн обладает глубокими познаниями как в А, так и в Б. Я действительно не хочу передавать одиночные / глобальные данные - я предпочитаю обращаться с ними аккуратно.

Есть ли какие-либо предложения о том, как исправить порядок последовательности событий или предложить другую (правильную методику MVC)?

Моя цель: я хочу передать некоторые данные в иерархию представлений на выбранной вкладке и сделать так, чтобы вызывающий сделал передачу.Иерархия представления получателя не должна обращать внимания на то, как он получил свои данные.

(У меня есть уродливый обходной путь, посредством которого я вызываю повторный запуск viewWillappear, но в основном это вызывает глупый поток: A.viewWillAppear ->Main.tabBarController -> принудительное выполнение другого A.viewWillAppear)

Большое спасибо.

Код (упрощенно - теперь это исправленный рабочий пример)

class MainController: UITabBarController, UITabBarControllerDelegate {

override func viewDidLoad() {
    super.viewDidLoad()
    delegate = self;
}

 override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    print ("tabBarController didSelect")
    let viewController = viewControllers![self.selectedIndex]
    if let vc = viewController as? AViewController {
        vc.Y = "some valuable data"
    }

    else if let vc = viewController as? BViewController {
        vc.Y = "some valuable data"
    }
}
}

class AViewController: UIViewController {


@IBOutlet weak var YTextField: UITextField!
var Y: String = ""

override func viewDidLoad() {
    super.viewDidLoad()
}


override func viewWillAppear(_ animated: Bool) {
    print ("viewWillAppear A")
    super.viewWillAppear(animated)

    YTextField.text = self.Y
}
}

class BViewController: UIViewController {

@IBOutlet weak var YTextField: UITextField!
var Y: String = ""

override func viewDidLoad() {
    super.viewDidLoad()
}


override func viewWillAppear(_ animated: Bool) {
    print ("viewWillAppear B")
    super.viewWillAppear(animated)

    YTextField.text = self.Y
}
}

1 Ответ

0 голосов
/ 25 мая 2018

Вы используете:

// this is called when the tab's ViewController is selected (*after* the tab item is selected (tapped))
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { ... }

, когда хотите использовать:

// this is called *when* the tab item is selected (tapped)
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { ... }

Вот модификация вашего примера:

import UIKit

class MainViewController: UITabBarController, UITabBarControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self;
    }

    override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

        let n = self.selectedIndex

        if let tabControllers = viewControllers {

            if let _ = tabControllers[n] as? AViewController {
                // *current* VC is AViewController
                if let vcB = tabControllers[n + 1] as? BViewController {
                    vcB.Y = "some valuable data from A"
                }
            }

            else if let _ = tabControllers[n] as? BViewController {
                // *current* VC is BViewController
                if let vcA = tabControllers[n - 1] as? AViewController {
                    vcA.Y = "some valuable data from B"
                }
            }

        }

    }

}

class AViewController: UIViewController {

    @IBOutlet weak var YTextField: UITextField!

    var Y:String = ""

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        YTextField.text = Y
    }

}

class BViewController: UIViewController {

    @IBOutlet weak var YTextField: UITextField!

    var Y:String = ""

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        YTextField.text = Y
    }

}

You 'Я хочу сделать дополнительную обработку / проверку, чтобы убедиться, что вы попадаете на нужную вкладку.Вы можете захотеть установить переменную внутри MainViewController на didSelect item, а затем установить переменную внутри «целевого» контроллера представления на didSelect viewController.

...