使用主题获得响应后将数据从 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)
}
我有一个 VC(A),它有一个容器视图并根据 segementControl 值更改 VC(B-C) 它,我发送一个请求并获得一个A ViewController 内的响应,我想确保 B 和 C 视图控制器都观察到来自 A 的响应并设置数据
我是 rxswift 的新手,所以请多多包涵
在 A VC
中启动两个 child VCSprivate 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)
}