具有相同信息的视图控制器之间的复杂导航系统(和 NavBar)

Complex navigation system (and NavBar) between view controllers with the same information

我需要帮助解决一个我一直想解决的问题。 它是从 parent 获取信息的视图控制器 (children) 之间的导航。如果有通知,parent 会更新。我希望 children 与 parent 一起立即更新。 这将是一个家庭控制器,我可以在其中显示基本信息。 然后是 Home 控制器内的一个按钮,该按钮将采用具有我提到的导航的 View Controller。

附上基本方案,方便大家理解

我想收到一个想法,即使它是以编程方式开始思考逻辑的基本想法。 如何在步骤(第 1 步、第 2 步...)之间制作 TOP NAVIGATION BAR,以及当我单击打开与该步骤对应的 child 的任何步骤时,它也会对我有很大帮助。

User 类型只不过是一个包含字符串、整数和一些数据的字典。 (我可以做通知系统和工作,我只提到可以这样工作)

我还想过,当我按下主控制器按钮时,它会加载 4 个视图控制器(每个步骤一个),这会消耗加载时间,对吗?

任何帮助都会让我摆脱压力 非常感谢!!

// Home controller
    class HomeController: UIViewController {
        
        let showSteps: UIButton = {
            let button = UIButton(type: .system)
            button.addTarget(self, action: #selector(showSteps), for: .touchUpInside)
            return button
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            addSubview(showSteps)
        }
        
        @objc func showSteps() {
            
            let controller = ShowSteps()
            self.present(controller, animated: true, completion: nil)
            
        }
        
    }


    // UIViewController with Navigation Bar
    class ShowSteps: UIViewController {

        private var user: User?
        
        override func viewDidLoad() {
            // update the User variable
            Service.shared.fetchUserData(uid: "XXX") { user in
                self.user = user
            }
            // listen notifications to update the user
            let nc = NotificationCenter.default
            nc.addObserver(self, selector: #selector(updateUser), name: NSNotification.Name(rawValue: "updateUser"), object: nil)
        
            /// 1. HERE I NEED TO ADD A NAVIGATION BAR IN THE TOP OF THE VIEW, THAT APPEAR IN ALL CHILDS
            /// 2. I NEED TO NAVIGATE TO OTHER STEPS WITH A FUNCTION
            
        
        }
        
        @objc func dissmissView(){
            /// 3. how can i remove from view all childs 4 in this case. but can be 6 o 7.... And then dismiss actual ShowSteps
            self.dismiss(animated: true, completion: nil)
        }
        
        @objc func updateUser() {
            // update user if notification called
            Service.shared.fetchUserData(uid: "XXX") { user in
                self.user = user
            }
        }

    }


    // that is a child example
    class VCexample1: UIViewController {
        
        /// 4. how can i see the navigation bar that has the parent? How can i send to other step from here?
        /// 5. how can i get the user variable from ShowSteps?
        /// 6. how can i navigate to other step from here?
        ///
        let BarButton: UIButton = {
            let button = UIButton(type: .system)
            button.addTarget(self, action: #selector(goToOtherStep), for: .touchUpInside)
            return button
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            /// show user data
        }
        

    }


    // that is a other child example
    class VCexample2: UIViewController {
        
        ...

    }
    // that is a other child example
    class VCexample3: UIViewController {
        
        ...

    }
    // that is a other child example
    class VCexample4: UIViewController {
        
        ...

    }

是基本的基本代码。它并不完美。我已经把它与错误放在一起,但很短,以便更好地理解

委托的简单示例:

// User data
struct UserData {
    var name: String
}

// this how child get info from parentVC
protocol childVCDelegate {
    // delegete user func or var (only one may be usefull)
    func getUserData() -> UserData
    func getUserName() -> String
    var userData: UserData {get set}
}

// the parent view controller who keep the user data
class ParentVC: UIViewController, childVCDelegate {
    var userData: UserData = UserData(name: "nacho111")
    
    func getUserData() -> UserData {
        userData
    }

    func getUserName() -> String {
        userData.name
    }
}

// child VC with a label updated with user name from parentVC
class ChildVC: UIViewController {
    var label = UILabel()
    var delegate: childVCDelegate?
    
    // either a copy of user in child view
    var userInChildVC: UserData?
    
    // either access user in Parent VC
    var userInParentVC: UserData? {
        delegate?.userData
    }
    
    // fonction to register in notification center to get userData changes from parentVC
    func userDataChanged() {
        // only one of the 2 options is usefull
        userInChildVC = delegate?.getUserData()
        label.text = userInChildVC?.name
        
        label.text = delegate?.userData.name
        
        label.text = delegate?.getUserName()
    }
}

// the tab bar which create a childVC and connect it to the parent
// via delegate property of ChildVC
class TabBar: UIViewController {

    var childVC: [ChildVC] = []

    // visible child VC
    var visibleChildVC: Int? {
        willSet {
            if let index = visibleChildVC {
                childVC[index].view.isHidden = true
            }
        }
        didSet {
            if let index = visibleChildVC {
                childVC[index].view.isHidden = false
            }
        }
    }
    
    func createChildVC(withParentVC parentVC: ParentVC,
                       visible: Bool = false) {
        let ch1 = ChildVC()
        ch1.delegate = parentVC
        childVC.append(ch1)
        // adding child VC view in view hierarchy : optional
        view.addSubview(ch1.view)
        if visible {
            visibleChildVC = childVC.count - 1
        } else {
            ch1.view.isHidden = true
        }
    }


    func displayChildVC(atIndex index: Int) {
        visibleChildVC = index
    }
}