我们可以使用递归来代替while
循环(请注意,以下代码都没有经过全面测试):
// Swift 2.3
public extension UIViewController {
public var topViewController: UIViewController {
let o = topPresentedViewController
return o.childViewControllers.last?.topViewController ?? o
}
public var topPresentedViewController: UIViewController {
return presentedViewController?.topPresentedViewController ?? self
}
}
关于遍历视图控制器层次结构的更一般的问题,一种可能的方法是有两个专用序列,以便我们可以:
for ancestor in vc.ancestors {
//...
}
或者:
for descendant in vc.descendants {
//...
}
在哪里:
public extension UIViewController {
public var ancestors: UIViewControllerAncestors {
return UIViewControllerAncestors(of: self)
}
public var descendants: UIViewControllerDescendants {
return UIViewControllerDescendants(of: self)
}
}
实现祖先序列:
public struct UIViewControllerAncestors: GeneratorType, SequenceType {
private weak var vc: UIViewController?
public mutating func next() -> UIViewController? {
guard let vc = vc?.parentViewController ?? vc?.presentingViewController else {
return nil
}
self.vc = vc
return vc
}
public init(of vc: UIViewController) {
self.vc = vc
}
}
实现后代序列:
public struct UIViewControllerDescendants: GeneratorType, SequenceType {
private weak var root: UIViewController?
private var index = -1
private var nextDescendant: (() -> UIViewController?)? // TODO: `Descendants?` when Swift allows recursive type definitions
public mutating func next() -> UIViewController? {
if let vc = nextDescendant?() {
return vc
}
guard let root = root else {
return nil
}
while index < root.childViewControllers.endIndex - 1 {
index += 1
let vc = root.childViewControllers[index]
var descendants = vc.descendants
nextDescendant = { return descendants.next() }
return vc
}
guard let vc = root.presentedViewController where root === vc.presentingViewController else {
return nil
}
self.root = nil
var descendants = vc.descendants
nextDescendant = { return descendants.next() }
return vc
}
public init(of vc: UIViewController) {
root = vc
}
}