简体   繁体   中英

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

I have a VC(A) that has a container view and changes the VC(BC) it based on the segementControl value, Im sending a request and getting a response inside the A ViewController and i want to make sure both B and C view controllers observe the response from A and set the data

Im new to rxswift so bear with me please

initiating both child VCS inside A VC

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

adding and removing functions inside 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 change

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

sending request and getting response inside A 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)

Let's say your AViewModel has stream of data your children interested in:

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

And your ParentVC has reference on his view model as:

var viewModel: AViewModel

Then you could declare protocol:

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

And both B and C will conform to this protocol.

Then we change declaration of add(asChildViewController ...) function like that:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM