Я использую Swift 3 в Xcode 8.3.3.
У меня есть 2 контроллера представления, A
и B
, которые наследуются от обычного UIViewController
, например:
class A: UIViewController {}
class B: UIViewController {}
Эти 2 контроллера представления могут быть представлены базовым контроллером представления в UINavigationController
.
У меня есть другой контроллер представления, Test
, который в конечном итоге будет представлен либо A
, либоB
, что означает где-то в конце иерархии, например:
Base
-> A
или B
-> Other
-> Other
-> Test
Test
будет представлять данные по-разному, в зависимости от того, откуда они были получены.
У меня есть расширение на UIViewController
, которое обеспечивает способ проверки этого, и оно прекрасно работает, когда я жестко кодируюэто для A
и B
:
extension UIViewController {
var isFromA: Bool {
if let nc = parent as? UINavigationController {
return nc.viewControllers.filter({ ($0 as? A) != nil }).count > 0
} else {
if let _ = parent as? A {
return true
} else if parent != nil {
return parent!.isFromA
} else {
return false
}
}
}
var isFromB: Bool {
if let nc = parent as? UINavigationController {
return nc.viewControllers.filter({ ($0 as? B) != nil }).count > 0
} else {
if let _ = parent as? B {
return true
} else if parent != nil {
return parent!.isFromB
} else {
return false
}
}
}
}
В коде жизненного цикла Test
я могу использовать его так:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if isFromA {
// do something
} else if isFromB {
// do something else
}
}
Итак, я собираюсьдобавление нового контроллера представления, C
, который также может в конечном итоге представить Test
.Я не хочу просто копировать и вставлять код снова, когда я создаю isFromC
var.Я хочу сделать вспомогательную функцию, которая принимает экземпляр типа класса для использования в этих as?
проверках.Новый код будет выглядеть примерно так:
extension UIViewController {
var isFromA: Bool {
return isFrom(A)
}
var isFromB: Bool {
return isFrom(B)
}
var isFromC: Bool {
return isFrom(C)
}
fileprivate func isFrom(_ viewControllerClass: UIViewController) -> Bool {
if let nc = parent as? UINavigationController {
return nc.viewControllers.filter({ ($0 as? viewControllerClass) != nil }).count > 0
} else {
if let _ = parent as? viewControllerClass {
return true
} else if parent != nil {
return parent!.isFrom(viewControllerClass)
} else {
return false
}
}
}
}
Это не компилируется, и это не совсем правильно, потому что у меня нет фактического экземпляра A
, B
илиC
чтобы перейти в эту вспомогательную функцию.
Так, каков наилучший способ решить эту проблему?Также обратите внимание, что я открыт для предложений по переработке кода вспомогательной функции, так как я не уверен, охватывает ли он все комбинации навигационных контроллеров и тому подобное.