Передача данных из родительского VC в дочерний VC после получения ответа с использованием предметов - PullRequest
1 голос
/ 19 марта 2019

У меня есть VC (A), который имеет вид контейнера и изменяет VC (BC) на основе значения segementControl, я отправляю запрос и получаю ответ внутри A ViewController, и я хочу убедиться, что и B, и Контроллеры представления C наблюдают ответ от A и устанавливают данные

Я новичок в rxswift, так что терпите меня, пожалуйста

инициация обоих дочерних VCS внутри 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
}()

добавление и удаление функций внутри 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)
        }
    }

отправка запроса и получение ответа внутри 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 Ответ

1 голос
/ 22 марта 2019

Скажем, у вашего 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)
}
...