我有几个segues呈现模态视图控制器。
class ProfileViewController: UIViewController {
func configure(profile: Profile) {
// Some ProfileViewController specific config
}
}
class SettingsViewController: UIViewController {
func configure(settings: Settings) {
// Some SettingsViewController specific config
}
}
所以这里有一些非常标准的代码,我们都写过很多次......
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination {
case let nav as UINavigationController:
switch nav.topViewController {
case let pvc as ProfileViewController:
pvc.configure(profile: profile)
case let svc as SettingsViewController:
svc.configure(settings: settings)
default:
break
}
default:
break
}
}
我也是这样试过的......
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination {
case let nav as UINavigationController
where nav.topViewController is ProfileViewController:
(nav.topViewController as! ProfileViewController).configure(profile: profile)
case let nav as UINavigationController
where nav.topViewController is SettingsViewController:
(nav.topViewController as! SettingsViewController).configure(settings: settings)
default:
break
}
}
但我想做的是两者结合......
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.destination {
case let nav as UINavigationController
where let pvc = nav.topViewController as ProfileViewController:
pvc.configure(profile: profile)
case let nav as UINavigationController
where let svc = nav.topViewController as SettingsViewController:
svc.configure(settings: settings)
default:
break
}
}
但显然不会编译。有人遇到过更好的模式吗?
更新
扩展@ Serj的答案......
extension UIStoryboardSegue {
var destinationNavTopViewController: UIViewController? {
return (destination as? UINavigationController)?.topViewController
}
}
然后
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch (segue.destination, destinationNavTopViewController) {
case let (_, pvc as ProfileViewController):
pvc.configure(profile: profile)
case let (_, svc as SettingsViewController):
svc.configure(settings: settings)
case let (ovc as OtherViewController, _):
ovc.configure…
default:
break
}
}
答案 0 :(得分:2)
在问这个问题时,我们可以考虑两种情况:
switch
语句现在针对特定用例,您似乎只想在有导航控制器时切换segue.destination
。您可以使用if let
或guard let
轻松实现此目标,如下所示:
guard let navigationController = segue.destination as? UINavigationController else { return }
guard let topController = navigationController.topViewController else { return }
switch topController {
case let profileViewController as ProfileViewController:
print("Do something for profile view controller")
default:
break
}
现在第二种情况更为通用,关于如何在switch语句中提供这两个变量。答案是元组。例如,我将提供Apple文档中的示例,然后为您的特定用例提供示例。
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x, y):
print("somewhere else at (\(x), \(y))")
}
现在有关如何使用您的用例实现上述内容的示例,请注意它可以改进一个丑陋的示例,但要明白:
switch (segue.destination, (segue.destination as? UINavigationController)?.topViewController) {
case (let nav as UINavigationController, let viewController as ProfileViewController):
return
// Maybe the destination wasn't a nav maybe it was the sign in view controller and you don't care about the second variable
case (let signInController as SignInViewController, let _):
return
default:
return
}
这是切换语句能够轻松切换元组的强大功能。我希望我的例子能回答你的问题。我尝试用所有含糊之处覆盖问题的所有部分。