此应用程序中的代理未设置

时间:2016-11-04 00:49:09

标签: ios swift delegates

我有一个带有两个视图控制器的应用程序... ViewController和CollectionViewController。我在viewController中有过滤函数,它们对加载到此视图控制器中的图像执行颜色过滤。 CollectionViewController包含一个集合视图,它充当带有单元格的水平滚动菜单,按下时,它们应该调用ViewController中的过滤器函数。故事板上有一个ID为“FilterSegue”的show segue

我让它与通知中心合作但我想尝试让它与协议和委托一起工作以了解这些方法。我收到了一些建议,但尽管进行了多次尝试,但仍无法让代表参加。 这是代码:

的ViewController:

import UIKit

class ViewController: UIViewController, FilterDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {


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

        if segue.identifier == "FilterSegue" {

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

        }
    }


    func onRedFilter() {

        // some code

    }

    func onGreenFilter() {

        // some code

    }


    func onBlueFilter() {

        // some code

    }

    func onUnfiltered() {

        // some code

    }

}

CollectionViewController:

import UIKit

//Protocols for filter functions called by the filter menu collection view custom cells.
protocol FilterDelegate: class {
    func onRedFilter()
    func onGreenFilter()
    func onBlueFilter()
    func onUnfiltered()
}

class CollectionViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {

    let reuseIdentifier = "FilterCell"

    var filterDelegate: FilterDelegate? = nil


    @IBOutlet var collectionView: UICollectionView!

    // Filter labels for custom filter menu cells.
    var tableData:[String] = ["Red Filter",
                              "Green Filter",
                              "Blue Filter",
                              "Unfilter",
                              "New Filter 1",
                              "New Filter 2"]

    // Filter images for custom filter menu cells.
    var tableImages: [String] = ["waterfallred.png",
                                 "waterfallgreen.png",
                                 "waterfallblue.png",
                                 "waterfall.png",
                                 "waterfall.png",
                                 "waterfall.png"]

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.


        // Set up collectionView for the filters.

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

        layout.itemSize = CGSize(width: 120, height: 80)

        collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)

        collectionView!.registerClass(colvwCell.self, forCellWithReuseIdentifier: reuseIdentifier)

        collectionView!.backgroundColor = UIColor.whiteColor()

        self.view.addSubview(collectionView!)

    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    // Set uo required methods for collection view.
    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {

        return 1

    }


    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        return tableData.count

    }


    // Method for custom collection view cell texts and images.
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        let cell: colvwCell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! colvwCell

        cell.backgroundColor = UIColor.grayColor()

        cell.lblCell.text = tableData[indexPath.row]
        cell.imgCell.image = UIImage(named: tableImages[indexPath.row])

        return cell

    }


    // Method for calling functions upon pressing custom filter menu collection view cells. In this case, the filter functions in the main view controller are called using notifications.

    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.")

        }

    }

}

guard语句返回“未设置过滤器委托!”在集合视图菜单上的任何凹陷单元格上。

2 个答案:

答案 0 :(得分:0)

而不是

protocol FilterDelegate: class {
func onRedFilter()
----
}

试试这个

protocol FilterDelegate {
    func onRedFilter()
    ----
    }

答案 1 :(得分:0)

我找到了答案......

我意识到segue没有被设置,因为它试图用segue实例化另一个集合视图控制器。我完全删除了prepareForSegue和故事板中的segue。 我在主视图控制器上有一个名为onFilter2的按钮,用于在按下的容器中实例化集合视图(调用函数showFilterMenu以显示过滤器菜单),然后在第二次按下时隐藏它(hideFilterMenu)。 showFilterMenu函数是实例化colectionviewcontroller的地方。所以,我在这个函数中设置了委托。它需要一行代码。

这是在正确调用委托时按下过滤器按钮时执行的功能。

  // New onFilter button action that shows/hides the filter collection view scroll bar on main view controller.
    @IBAction func onFilter2(sender: UIButton) {

        if filterButtonOn == true {

            if (sender.selected) {

                hideFilterMenu()
                editButton.selected = false
                sender.selected = false

            } else {

                showFilterMenu()
                sender.selected = true
                hideSliderMenu()
                editButton.selected = false


                //Reset color sliders to initial values.
                redHorizontalSlider?.setValue(0, animated: false)
                greenHorizontalSlider?.setValue(0.0, animated: false)
                blueHorizontalSlider?.setValue(0.0, animated: false)

                // Set initial values for color indicators.
                redSliderIndicator.text = "0.00"
                greenSliderIndicator.text = "0.00"
                blueSliderIndicator.text = "0.00"

            }

        }

    }


    // Shows the filter menu scrolling bar in container view upon request.
    func showFilterMenu() {

        let newViewController = self.storyboard?.instantiateViewControllerWithIdentifier("FilterCollectionView") as! CollectionViewController

        newViewController.view.translatesAutoresizingMaskIntoConstraints = false
        self.toggleOnViewController(newViewController)
        self.currentViewController = newViewController

        // Set the delegate for the filter functions called by the cells in the collectionViewController filter menu.

    // Set the delegate for the filter functions called by the cells in the collectionViewController filter menu.

//Here is the line of code that fixes the problem...
        newViewController.filterDelegate = self

    filterMenuShowOn = true

    }


    // Hides filter menu scrolling bar from container view upon request.
    func hideFilterMenu() {

        currentViewController!.view.alpha = 1

        UIView.animateWithDuration(0.5, animations: {
            self.currentViewController!.view.alpha = 0
            },
                    completion: { finished in
                            self.currentViewController!.view.removeFromSuperview()
                            self.currentViewController!.removeFromParentViewController()
        })

    }

我要感谢Matt让我思考发生了什么。