使用主题获得响应后将数据从 parent VC 传递到 child VC

Passing data from parent VC to child VC after getting response using subjects

我有一个 VC(A),它有一个容器视图并根据 segementControl 值更改 VC(B-C) 它,我发送一个请求并获得一个A ViewController 内的响应,我想确保 B 和 C 视图控制器都观察到来自 A 的响应并设置数据

我是 rxswift 的新手,所以请多多包涵

在 A VC

中启动两个 child VCS
private lazy var profileVC: ProfileVC = {
    // Load Storyboard
    let storyboard = UIStoryboard(name: "Profile", bundle: Bundle.main)

    // Instantiate View Controller
    var viewController = storyboard.instantiateViewController(withIdentifier: "ProfileVC") as! ProfileVC

    // Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

private lazy var socialMediaVC: SocialMediaVCViewController = {
    // Load Storyboard
    let storyboard = UIStoryboard(name: "Profile", bundle: Bundle.main)

    // Instantiate View Controller
    var viewController = storyboard.instantiateViewController(withIdentifier: "SocialMediaVC") as! SocialMediaVCViewController

    // Add View Controller as Child View Controller
    self.add(asChildViewController: viewController)

    return viewController
}()

在 A 中添加和删除函数 ViewController

func add(asChildViewController viewController: UIViewController) {
    // Add Child View as Subview
    containerView.addSubview(viewController.view)

    // Configure Child View
    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}



private func remove(asChildViewController viewController: UIViewController) {
    // Notify Child View Controller
    viewController.willMove(toParent: nil)

    // Remove Child View From Superview
    viewController.view.removeFromSuperview()

    // Notify Child View Controller
    viewController.removeFromParent()
}

segemntController 更改

 @IBAction func segmentedControlClicked(_ sender: UISegmentedControl) {
        segmentedControl.changeUnderlinePosition()
        if segmentedControl.selectedSegmentIndex == 0 {
            remove(asChildViewController: socialMediaVC)
            add(asChildViewController: profileVC)
        } else {
            remove(asChildViewController: profileVC)
            add(asChildViewController: socialMediaVC)
        }
    }

发送请求并在 ViewModel 中获取响应:

    startedUp.accept(true)
    startedUp.filter({ [=17=]})
        .flatMap{ [weak self] _ -> Observable<Event<Result<ProfileResponse>>> in
            self?.loadInProgress.accept(true)
            return network.showProfile(startupId: 1).materialize()}
        .subscribe(onNext: { [weak self] event in
            self?.loadInProgress.accept(false)
            switch event {
            case .next(let result):
                switch result{
                case .Success(let response):
                    self?.startedUp.accept(false)
                    self?.sectionSubject.onNext(0)
                    self?.output.editProfileData = (self?.setProfileData(response:response))!
                    self?.tableViewcellsSubject.onNext((self?.createArray(response: response))!)
                    self?.userscellsSubject.onNext((self?.createUserArray(response: response.users!))!)
                case .Failure(let error):
                    self?.errorsSubject.onNext(error)
                }
            case .error( _):
                print("error")
            default:
                break
            }
        })
        .disposed(by: disposeBag)

假设您的 AViewModel 有您 children 感兴趣的数据流:

protocol AViewModel {
    let importantDataStream: Observable<SomeData> { get }
}

并且您的 ParentVC 对他的视图模型的引用为:

var viewModel: AViewModel

然后你可以声明协议:

protocol ImportantDataListener {
    func subscribe(to stream: Observable<SomeData>)
}

并且B和C都会遵守这个协议。

然后我们像这样更改 add(asChildViewController ...) 函数的声明:

func add(asChildViewController viewController: UIViewController & ImportantDataListener) {
    // Add Child View as Subview
    containerView.addSubview(viewController.view)

    // Configure Child View
    viewController.view.frame = view.bounds
    viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Passing stream
    viewController.subscribe(to: viewModel.importantDataStream)
}