[英]How do I perform either a push UIViewController or a present of UIAlertController?
After some API calls, I have a check to either navigate to another screen or show an alert on the same screen. 在一些API调用之后,我会检查导航到另一个屏幕或在同一屏幕上显示警报。 Currently, I am doing this by creating an observable that returns a UIViewController type but pushing a UIAlertController causes problem.
目前,我通过创建一个返回UIViewController类型的observable来执行此操作,但是推送UIAlertController会导致问题。
Any suggestions/ideas on how this should be done? 关于如何做到这一点的任何建议/想法?
ViewModel.swift ViewModel.swift
let nextAction = Observable.combineLatest(appVersionOutput, serviceAvailabilityOutput, getLanguagePackOutput,
resultSelector:
{ appVersion, _, _ -> UIViewController in
if appVersion.currentAppVersion == "1.0.0" {
let appServiceAvailability = Availability.shared.getAppStatus()
if appServiceAvailability {
return LoginLandingViewController()
} else {
return ServiceMaintenanceViewController()
}
} else {
return UIAlertController()
}
})
ViewController.swift ViewController.swift
viewModel.output.nextAction
.subscribe(onNext: { [weak self] screen in
self?.navigationController?.pushViewController(screen, animated: true)
}) // PROBLEM FACED: Pushing a UIAlertController
.disposed(by: disposeBag)
You can check the class using classForCoder 您可以使用classForCoder检查类
viewModel.output.nextAction
.subscribe(onNext: { [weak self] screen in
if String(describing: screen.classForCoder) == "UIAlertController" {
//present
self?.present(screen, animated: true, completion: nil)
} else {
//navigate
self?.navigationController?.pushViewController(screen, animated: true)
}
}) // PROBLEM FACED: Pushing a UIAlertController
.disposed(by: disposeBag)
There're a few options. 有几个选择。
The first option is the adoption of your current implementation. 第一种选择是采用您当前的实现。 You could pass an information in addition to ViewController in onNext event of nextAction observable, that will tell how to show the VC.
您可以在nextAction observable的onNext事件中传递除ViewController之外的信息,这将告诉您如何显示VC。
For instance, you can create an associated enum 例如,您可以创建关联的枚举
// you can call it NextAction, Action etc
enum PresentationType {
case
push(UIViewController),
present(UIViewController)
}
and reuse it like this: 并重复使用它:
let nextAction = Observable.combineLatest(appVersionOutput, serviceAvailabilityOutput, getLanguagePackOutput,
resultSelector:
{ appVersion, _, _ -> PresentationType in
if appVersion.currentAppVersion == "1.0.0" {
let appServiceAvailability = Availability.shared.getAppStatus()
if appServiceAvailability {
return .push(LoginLandingViewController())
} else {
return .push(ServiceMaintenanceViewController()) // use .present if should present modally
}
} else {
return .present(UIAlertController())
}
})
// somewhere in viewController
viewModel.output.nextAction
.subscribe(onNext: { [weak self] action in
switch action {
case .push(let vc):
self?.navigationController?.pushViewController(vc, animated: true)
case .present(let vc):
self?.present(vc, animated: true, completion: nil)
})
.disposed(by: disposeBag)
The second (and more flexible and testable in some sense) option would be to create a separate Router class which is responsible for creating and showing next screens (with functions showLogin
, showAlert
etc). 第二个(在某种意义上更灵活和可测试)选项是创建一个单独的Router类,负责创建和显示下一个屏幕(使用
showLogin
, showAlert
等函数)。 The router can be directly injected in ViewModel and you can call the Router to show next screens in, for example, do(onNext) events in your observables. 路由器可以直接注入ViewModel,您可以调用路由器以显示下一个屏幕,例如,您的observable中的do(onNext)事件。
You can look at the is
keyword which allows you to check the object type. 您可以查看
is
关键字,它允许您检查对象类型。 More on is keyword . 更多关于关键字 。 An alternative will be to use
type(of: object)
and compare to UIAlertViewController.self
另一种方法是使用
type(of: object)
并与UIAlertViewController.self
进行比较
Since you have to present a UIAlertViewController
and not push it, use if and else with the above to present if type is UIAlertViewController
and push if otherwise. 因为您必须呈现
UIAlertViewController
而不是推送它,所以如果type是UIAlertViewController
则使用if和else以及上面的内容,否则将推送。 NB: Unnecessary to check for UIViewController since they all are. 注意:不必检查UIViewController,因为它们都是。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.