使用主题获得响应后,将数据从父VC传递到子VC

时间:2019-03-19 09:41:06

标签: ios swift rx-swift

我有一个具有容器视图的VC(A),并根据segementControl值更改了VC(BC),我在A ViewController中发送请求并获得响应,我想确保B和C视图控制器观察A的响应并设置数据

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

在VC中同时启动两个子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
}()

在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({ $0})
        .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)

1 个答案:

答案 0 :(得分:1)

假设您的AViewModel拥有您的孩子感兴趣的数据流:

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)
}