如何在 Swift 中获取父 ViewController 的类名?

Posted

技术标签:

【中文标题】如何在 Swift 中获取父 ViewController 的类名?【英文标题】:How to get class name of parent ViewController in Swift? 【发布时间】:2015-01-28 17:30:20 【问题描述】:

有没有办法在当前(子)UIViewController 中获取父 VC 的类名?我的“子”VC(推送)有两个“父”UIViewControllers,所以我想知道哪个是当前父?

【问题讨论】:

【参考方案1】:

这是一种方法:

if let parentVC = self.parentViewController 
    if let parentVC = parentVC as? someViewController 
        // parentVC is someViewController
     else if let parentVC = parentVC as? anotherViewController 
        // parentVC is anotherViewController
    

首先,分配self.parentViewController 并选择性地解包。

其次,使用可选强制转换as?,如果可行,将视图控制器分配给parentVC

也就是说,这是一种代码异味——子视图控制器通常应该不知道它们的父视图控制器是谁。无论您要解决什么问题,您都应该使用 tell, don't ask 和委托来解决它。

【讨论】:

这似乎是一种很好且正确的方法,但由于某种原因,我推送的子 VC 中 parentViewController 的值始终为零。所以我以一种愚蠢的方式做到了:必须在 child-VC 中创建 Int 变量 parentIndicator,并且我从父控制器向它传递一些值(使用委托和 prepareForSegue)。 更新 swift 4 的答案!迅速你应该使用 parentVC 是 someViewController 而不是你的代码!!! 如果我们使用is,那么我们将无法在条件括号内获得类型绑定【参考方案2】:

更新至 SWIFT 5

在您的子视图控制器中,您可以尝试以下操作:

guard let parent = self.presentingViewController else
    // ...some code
    return

//presented by parent view controller 1
if parent.isKind(of: Parent1.self)
    // do something
else
    //presented by parent view controller 2

我建议您将此逻辑放在您的 viewWillAppear 方法中,因为当调用 viewDidLoad 时,无法保证视图控制器层次结构已加载到导航树中,因此,presentingViewController您的子视图控制器的属性可能是 nil

【讨论】:

为什么不使用as?is?此外,如果presentingViewControllernil,这将导致崩溃。 我只是试图展示另一种方法,你是对的,一切都可以在if(self.presentingViewController != nil) 语句中。感谢您的反馈!【参考方案3】:

首先在视图控制器中添加扩展

extension UIView 
    var parentViewController: UIViewController? 
        var parentResponder: UIResponder? = self
        while parentResponder != nil 
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController 
                return viewController
            
        
        return nil
    

现在像这样使用它

let vc = self.parentViewController

if let parentVC = self.parentViewController 
    if let parentVC = parentVC as? someViewController 
        // parentVC is someViewController
     else if let parentVC = parentVC as? anotherViewController 
        // parentVC is anotherViewController
    

【讨论】:

【参考方案4】:

只需使用view.parentViewController 并最终使用它的title 属性。

【讨论】:

OP 要求的是它的类,而不是它的标题。 啊,是的。但是可以使用标题来区分两者;-) 这是非常不可靠的(因为 title 属性对于 UIViewControllers 来说是完全可选的),并且对于这个特定问题的完全错误的答案,因为 title 属性永远不会返回类名(除非您正在明确分配它,这在大多数情况下也毫无意义...) @Priest 只是将其视为区分事物的替代方法,而不是更多。我在接受的答案之前发布了一点,这越来越重要(parentController)。【参考方案5】:

更新到 Swift 4

斯威夫特 4:

if let parentVC = self.parent 
    if parentVC is someViewControllerr 
        // parentVC is someViewController
     else if parentVC is anotherViewController 
        // parentVC is anotherViewController
    

斯威夫特 3:

if let parentVC = self.parentViewController 
    if let parentVC = parentVC as? someViewController 
        // parentVC is someViewController
     else if let parentVC = parentVC as? anotherViewController 
        // parentVC is anotherViewController
    

【讨论】:

【参考方案6】:

尝试从 children 数组中挑选孩子,如下所示

if let parentVC = self.parent 

            if let parentVC = parentVC.children[0] as? someViewController 

【讨论】:

【参考方案7】:

添加此扩展并按类型查找父视图。

extension UIResponder 
    
    func next<T: UIResponder>(_ type: T.Type) -> T? 
        return next as? T ?? next?.next(type)
    
    

如何使用

self.next(UIViewController.self)

【讨论】:

以上是关于如何在 Swift 中获取父 ViewController 的类名?的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式 Swift Segue

Swift - 将数据从父视图控制器传递到子视图控制器

如何与框架项目swift共享父(主机)项目pod?

如何在 swift 中从父视图访问容器视图子视图

UITableView : popViewController 并将行索引保留到父控制器中?

如何在Swift中正确地从父节点中删除SKSpriteNode的子类(要从数组中移除,屏幕上的空格......)?