【问题标题】:Calling a function in a view controller from another view controller从另一个视图控制器调用视图控制器中的函数
【发布时间】:2017-03-12 09:31:21
【问题描述】:

这是建议的委托过程的代码...

在主视图控制器中...

protocol FilterDelegate: class {
    func onRedFilter()
    func onGreenFilter()
    func onBlueFilter()
    func onUnfiltered()
}

class ViewController: UIViewController, FilterDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

----

// Increase red color level on image by one.
    func onRedFilter() {

    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        if segue.identifier == "filterSegue" {

            let dest = segue.destinationViewController as!    CollectionViewController
            dest.filterDelegate = self

        }
    }

在集合视图控制器中...

var filterDelegate: FilterDelegate?

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    print("Cell \(indexPath.row) selected")

    guard let filterDelegate = filterDelegate else {
        print("Filter delegate wasn't set!")
        return
        }

    switch indexPath.row {

        case 0:
            filterDelegate.onRedFilter()
        case 1:
            filterDelegate.onGreenFilter()
        case 2:
            filterDelegate.onBlueFilter()
        case 3:
            filterDelegate.onUnfiltered()
        default:
            print("No available filter.")

    }

现在...代码在保护块处停止并打印错误消息。任何按下单元格时都不会执行切换块。

【问题讨论】:

    标签: swift view controllers


    【解决方案1】:

    您在倒数第二句中的理论是正确的——当您在“子”视图控制器中调用 storyboard.instantiateViewControllerWithIdentifier 时,您实际上是在创建主视图控制器的全新实例。您没有获得对现有主视图控制器的引用,这就是您调用的方法没有任何效果的原因。

    有几种方法可以实现您想要做的事情,包括delegate pattern 或使用闭包。下面是使用委托协议的示意图:

    protocol FilterDelegate: class {
        func onRedFilter()
        func onGreenFilter()
        func onBlueFilter()
        func onUnfiltered()
    }
    
    class MainViewController: UIViewController, FilterDelegate {
    
        // implement these as required
        func onRedFilter() { }
        func onGreenFilter() { }
        func onBlueFilter() { }
        func onUnfiltered() { }
    
        // when we segue to the child view controller, we need to give it a reference
        // to the *existing* main view controller
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if let dest = segue.destination as? ChildViewController {
                dest.filterDelegate = self
            }
        }
    
    }
    
    class ChildViewController: UIViewController {
    
        var filterDelegate: FilterDelegate?
    
        func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    
            // ... 
    
            guard let filterDelegate = filterDelegate else {
                print("Filter delegate wasn't set!")
                return
            }
    
            switch indexPath.row {
                case 0:
                    filterDelegate.onRedFilter()
                case 1:
                    filterDelegate.onGreenFilter()
                case 2:
                    filterDelegate.onBlueFilter()
                case 3:
                    filterDelegate.onUnfiltered()
                default:
                    print("No available filter.")
    
            }
    
        }
    
    }
    

    另一种选择是为MainViewController 上孩子需要调用的每个函数在ChildViewController 上提供闭包,并将它们设置在prepareForSegue 中。使用委托似乎更简洁一些,因为在这种情况下有很多函数。

    【讨论】:

    • 我试过了,不仅单元格没有调用过滤器(甚至没有打印正在工作的 indexPath.row 的嵌入式打印语句),而且现在 collectionviewcontroller 的水平滚动被破坏了。有什么想法吗?
    • 这听起来像是子视图控制器搞砸了,并且 UICollectionViewDataSource 方法不起作用。如果没有看到代码,很难说出发生了什么。我想我会确保它仍然是 UICollectionViewController 的子类(不是 UIViewController),并确保数据源仍然正确连接到情节提要中。
    • 好吧,我设法将其取回,因此滚动集合视图正在工作。你能向我解释一下带守卫的挡板是做什么的以及是否缺少什么吗?现在它打印“未设置过滤器委托!”每个单元格上的语句按下滚动菜单并返回,永远不会进入 switch 语句。
    • 我正在使用您建议的技术编辑上面发布的代码。如您所见,我必须进行一些更正才能使其编译。再次......它没有通过保护块中的错误消息。
    • 这意味着filterDelegate 属性未设置。您是否使用 segue 从主视图控制器显示子视图控制器?如果没有,则需要使用其他方法来设置 filterDelegate。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-17
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多