【问题标题】:How to send values to a parent view controller in Swift如何在 Swift 中向父视图控制器发送值
【发布时间】:2016-05-28 02:45:17
【问题描述】:

我正在为我用 swift 编写的 iOS 应用程序开发设置视图控制器屏幕。我正在使用导航控制器来运行显示标题为“输入法”的单元格的主设置表视图。当前方法列在单元格的右侧。他们可以单击单元格转到下一个视图控制器,在那里他们可以选择他们想要的输入法。

从这里开始,有两个部分。首先是要选择的输入法(触摸屏或操纵杆)。第二部分是特定于该人是左撇子还是右撇子的操纵杆。当他们选择一个框时,我不想让 vc 展开,因为他们也可能在另一部分中选择一个。

我的问题:如何从子控制器更新父控制器中的文本字段。

我在可选解决方案方面遇到的问题:

let parentVC: UIViewController = (self.navigationController?.parentViewController)!
parentVC.inputMethod.text? = cellSelected // This doesn't work because it cannot find the label inputMethod.

viewDidLoad() 会导致延迟,用户在旧方法更改之前会看到它。

当有人单击导航控制器左上角的后退按钮时,我不知道如何运行 segue,因为导航控制器控制着 segue。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    强制转换父视图控制器不是一个好主意,即使您确定代表哪个类也是如此。我会用一个协议来做:

    在子控制器中添加如下协议:

    protocol ChildNameDelegate {
        func dataChanged(str: String)
    }
    
    class ChildClass {
    
        weak var delegate: ChildNameDelegate?
    
        func whereTheChangesAreMade(data: String) {
            delegate?.dataChanged(data)
        }
    }
    

    在父级中:

    class ParentClass: ChildNameDelegate {
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            guard let segueId = segue.identifier else { return }
    
            switch segueId {
            case "childSegue":
                let destVC = segue.destinationViewController as! ChildClass
                destVC.delegate = self
                break
            default:
                break
            }
        }
    
        // Child Delegate
        func dataChanged(str: String) {
            // Do whatever you need with the data
        }
    }
    

    【讨论】:

    • 如果我的子视图已经有一个委托,我想这不会起作用,因为我不能(轻松)设置另一个委托。有没有其他方法可以做到这一点?
    • 您可以完美地遵守多个协议(例如您遵守 tableviewdelegate 和 tableviewdatasource 时)。您必须用另一个名称命名委托(如 'var secondDelegate: SecondChildNameDelegate?')并将两个委托都设置在父级中。
    • 我就是这么想的,只是想确认一下,非常感谢。
    • 我只能通过将协议限制为类来使其在 Swift 4 中工作:protocol ChildNameDelegate: class { 有关更多信息,请参阅此答案:stackoverflow.com/a/24104371/7493938
    【解决方案2】:

    您需要将parentViewController 转换为它具有的任何自定义类。例如,如果父级有 ExampleParentController 类,你可以这样写:

    let parentVC = (self.navigationController?.parentViewController)! as! ExampleParentController
    parentVC.inputMethod.text? = cellSelected
    

    【讨论】:

    • 不幸的是,这为父视图控制器提供了 nil,但我不知道为什么。
    • @AlecO'Connor 这可能是因为父级不是来自navigationController。您可以尝试类似 let parentVC = parent as! ExampleParentController
    【解决方案3】:

    我在这里找到了解决方案:Modifing one variable from another view controller swift http://www.raywenderlich.com/115300/swift-2-tutorial-part-3-tuples-protocols-delegates-and-table-views

    您可以使用委托方法来调整变量,而不是尝试直接访问视图控制器(如果它不为视图控制器返回 nil 会更容易)。 代表的工作就像一个魅力!

    【讨论】:

    • 我仍然想知道为什么它返回 nil,因为如果它只是更新标签,访问父视图控制器会更短更容易。
    猜你喜欢
    • 1970-01-01
    • 2018-08-06
    • 2015-08-06
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多