单击TableViewCell中collectionView的collectionViewCell中的按钮时显示新的ViewController

时间:2016-05-15 05:13:31

标签: swift uitableview uicollectionview uicollectionviewcell

当点击collectionViewCell中的按钮时,我尝试显示ViewController。

我有一个动态tableView,一个tableViewCells中的动态collectionView。

在每个集合ViewCells中,都有一个按钮,它应该是segue的触发器,以显示另一个View Controller

我尝试使用以下代码,但应用程序崩溃:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Receiver (<Okm.bienController: 0x7fc8b0cfb1a0>) has no segue with identifier 'extend''

我的storyBoard中的segue标识符是'extend'。

 class photoCell: UITableViewCell, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {
    ...

    func extendFunc(sender : UIButton) {

       bienController().performSegueWithIdentifier("extend", sender: sender.tag)
    }
}


class bienController : UIViewController, UITableViewDelegate, UITableViewDataSource {

...

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "extend" {
            let backItem = UIBarButtonItem()
            backItem.title = ""
            navigationItem.backBarButtonItem = backItem

            let extendView = segue.destinationViewController as! extendController
            extendView.image = image[sender]

        }
    }
}

enter image description here

然后,我尝试了这个:

 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
            self.segue()
          // self.performSegueWithIdentifier("image", sender: nil)

    }

    func clickExtend(sender:Int){
        print(sender) //print the correct tag!
       self.segue()
    }

    func segue(){
         self.performSegueWithIdentifier("image", sender: nil)
    }

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

        if segue.identifier == "image" {
            let backItem = UIBarButtonItem()
            backItem.title = ""
            navigationItem.backBarButtonItem = backItem
           // print(sender)

           let extendView = segue.destinationViewController as! extendController
           extendView.image = UIImage(named: "maison")

        }
    }
}

我将函数clickExtend()与我的collectionCell的按钮相关联。 当segue来自didSelectRowAtIndexPath时,它工作,但是当我点击按钮时,它会崩溃并出现同样的错误:'由于未捕获的异常而终止应用'NSInvalidArgumentException',原因:'Receiver()没有带有标识符'image'的segue' “

(我更改了'image'的segue标识符)

然后我尝试直接显示视图控制器而不用Segue执行。

class photoCategoryCell: UITableViewCell, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {

... 
    func extendFunc(sender : UIButton) {
        print(sender.tag)
        bienController().boo(sender.tag)
    }
}

并且:

class bienController : UIViewController, UITableViewDelegate, UITableViewDataSource {

...

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
              self.boo(indexPath.row)

    }

func boo(sender:Int){
        let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let vc:UIViewController = storyboard.instantiateViewControllerWithIdentifier("extend") as! extendController
        let backItem = UIBarButtonItem()
        backItem.title = ""
        navigationItem.backBarButtonItem = backItem

        self.showViewController(vc as UIViewController, sender: nil)
    }
}

当我点击tableViewCell时,它会显示View Controller,但是当我点击collectionViewCell中的“extend”按钮时,没有任何事情发生..

请,我需要帮助!!

谢谢!!

完整代码

import UIKit

class photoCategoryCell: UITableViewCell, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView : UICollectionView!

    var hid = [true, true, true, true, true, true] //supp

    var imageList = [UIImage]()

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

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

        return 10
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath: indexPath) as! photoCollectionViewCell

        cell.photoView.image = self.imageList[indexPath.row]
        cell.photoView.contentMode = .ScaleAspectFill
        cell.extend.hidden = true
        cell.blurView.hidden = true

        cell.extend.tag = indexPath.row
        cell.extend.addTarget(self, action: #selector(photoCategoryCell.extendFunc(_:)), forControlEvents: .TouchUpInside)
        return cell
    }

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        if let cell : photoCollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath) as! photoCollectionViewCell!
        {
            if cell.blurView.hidden == true {
            cell.blurView.hidden = false
            cell.extend.hidden = false
        } else {
            cell.blurView.hidden = true
            cell.extend.hidden = true
        }
        }
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        let cellWidth = (UIScreen.mainScreen().bounds.width) / 2
        return CGSize(width: cellWidth, height: cellWidth)

    }

    func extendFunc(sender : UIButton) {
        print(sender.tag)
        bienController().boo(sender.tag)
    }
}

import UIKit

class bienController : UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView : UITableView!
    @IBOutlet weak var tableViewTwo : UITableView!
    @IBOutlet weak var tableHeight : NSLayoutConstraint!
    @IBOutlet weak var viewBlack : UIView!
    let onglet = ["One", "Two", "Three", "Four", "Five"]


    var imageNb : Int = 3


    override func viewDidLoad() {
        super.viewDidLoad()
//        let gradient: CAGradientLayer = CAGradientLayer()
//        gradient.frame = self.viewBlack!.bounds
//        gradient.colors = [UIColor.clearColor().CGColor, UIColor(red: 225/255, green: 225/255, blue: 225/255, alpha: 0.5).CGColor]
//      
//        self.viewBlack.layer.insertSublayer(gradient, atIndex: 0)

        self.tableView?.tableFooterView = UIView(frame: CGRectZero)
        self.tableViewTwo?.tableFooterView = UIView(frame: CGRectZero)
        self.tableHeight?.constant = 38*5 
        self.tableViewTwo?.scrollEnabled = false

    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(true)
        UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.Default
        if let navigationBar = navigationController?.navigationBar {
            navigationBar.barTintColor = UIColor.whiteColor()
            navigationBar.translucent = false
            if let font = UIFont(name: "HelveticaNeue-Light", size: 20.0) {
                let navBarAttributesDictionary : [String : AnyObject]? = [
                    NSForegroundColorAttributeName: UIColor(red: 235/255, green: 67/255, blue: 27/255, alpha: 1.0),
                    NSFontAttributeName: font
                ]
                navigationBar.titleTextAttributes = navBarAttributesDictionary
                UIBarButtonItem.appearance().setTitleTextAttributes(navBarAttributesDictionary, forState: .Normal)
            }
        }


        let editButton = UIBarButtonItem(title: "Modifier", style: .Plain, target: self, action: #selector(bienController.modifier))

        self.navigationItem.rightBarButtonItem = editButton

    }

    func modifier(){

      //do something  
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.tableView {

            return 3

        } else {

            return 5
        }
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        if tableView == self.tableView {

            if indexPath.row == 0 {

                var cell = tableView.dequeueReusableCellWithIdentifier("oneCell") as! listCommandeCellTwo!

                if cell == nil {

                    cell = listCommandeCellTwo(style: UITableViewCellStyle.Default, reuseIdentifier: "oneCell")
                }

                cell.descriptionLabel.text = "description"
                cell.titre.text = "titre"

                return cell

            } else if indexPath.row == 1 && self.imageNb < 3 {

                var cell = tableView.dequeueReusableCellWithIdentifier("bienImgCell") as! bienImgCell!

                if cell == nil {

                    cell = bienImgCell(style: UITableViewCellStyle.Default, reuseIdentifier: "bienImgCell")
                }

                cell.imageOne.image = UIImage(named: "maison")
                cell.imageTwo.image = UIImage(named: "maison")
                cell.imageOne.contentMode = .ScaleAspectFill
                cell.imageTwo.contentMode = .ScaleAspectFill


                return cell

            } else if indexPath.row == 1 && self.imageNb >= 3 {

                var cell = tableView.dequeueReusableCellWithIdentifier("photoCategoryCell") as! photoCategoryCell!

                if cell == nil {

                    cell = photoCategoryCell(style: UITableViewCellStyle.Default, reuseIdentifier: "photoCategoryCell")
                }

                cell.imageList.removeAll(keepCapacity: false)
                for i in 0...10 {
                cell.imageList.append(UIImage(named: "maison")!)
                }


                cell.collectionView.delegate = cell
                cell.collectionView.dataSource = cell

                return cell

            } else {
                var cell = tableView.dequeueReusableCellWithIdentifier("bienCellOne") as! bienCellOne!

                if cell == nil {

                    cell = bienCellOne(style: UITableViewCellStyle.Default, reuseIdentifier: "bienCellOne")
                }


                cell.commentaire.delegate = cell
                cell.commentaire.editable = false
                cell.commentaire.setContentOffset(CGPointZero, animated: false)

                cell.commentaire.text = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda."

                return cell
            }
        } else {


            var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! bienCellTwo!

            if cell == nil {

                cell = bienCellTwo(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
            }


            cell.titre.text = self.onglet[indexPath.row]
            cell.imageCategory.image = UIImage(named: "validate")
            cell.imageCategory.contentMode = .ScaleAspectFit

            if indexPath.row == 0 {
                cell.backgroundColor = UIColor(red: 235/255, green: 67/255, blue: 27/255, alpha: 1.0)
                cell.tintColor = UIColor.whiteColor()
                cell.titre.textColor = UIColor.whiteColor()
                let checkImage = UIImage(named: "chevron")
                let checkmark = UIImageView(image: checkImage)
                cell.accessoryView = checkmark
                cell.addBottomBorderWithColor(UIColor(red: 235/255, green: 67/255, blue: 27/255, alpha: 1.0), width: 1.0)
            } else {
                cell.addBottomBorderWithColor(UIColor(red: 225/255, green: 225/255, blue: 225/255, alpha: 1.0), width: 1.0)
                cell.backgroundColor = UIColor.whiteColor()
                cell.titre.textColor = UIColor(red: 235/255, green: 67/255, blue: 27/255, alpha: 1.0)
                let checkImage = UIImage(named: "chevron-orange")
                let checkmark = UIImageView(image: checkImage)
                cell.accessoryView = checkmark

            }
            return cell
        }

    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //if tableView == self.tableViewTwo {

            print(indexPath.row)
            self.boo(indexPath.row)
           // self.segue()
          // self.performSegueWithIdentifier("image", sender: nil)
        //}
    }

    func boo(sender:Int){
        print(sender)
        let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let vc:UIViewController = storyboard.instantiateViewControllerWithIdentifier("extend") as! extendController
        let backItem = UIBarButtonItem()
        backItem.title = ""
        navigationItem.backBarButtonItem = backItem

        self.showViewController(vc as UIViewController, sender: nil)

       //self.segue()
    }

    func segue(){
       //  self.performSegueWithIdentifier("image", sender: nil)
    }

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

        if segue.identifier == "image" {
            let backItem = UIBarButtonItem()
            backItem.title = ""
            navigationItem.backBarButtonItem = backItem

           let extendView = segue.destinationViewController as! extendController
           extendView.image = UIImage(named: "maison")

        }
    }
}

1 个答案:

答案 0 :(得分:2)

在第一种情况下,问题是这一行:

bienController().performSegueWithIdentifier("extend", sender: sender.tag)

使用标准bienController方法创建init类的新实例。因此,它不了解故事板,因此无法找到segue。

第二种情况更难确定(你不能显示如何从collectionViewCell中的按钮调用clickExtend方法),但我怀疑它有同样的问题。

在最后一种情况下,您将再次创建bienController的新实例。因为您现在使用showViewController,所以缺少segue没有问题 - 所以没有错误 - 但是新实例不在屏幕上,所以showViewController什么都不做(至少,它没有&#39; t在屏幕上显示任何内容。)

您需要您的集合视图单元格引用bienViewController现有实例。我需要查看更多设置以准确显示如何执行此操作,但同时您应该检查this question和答案。

在这种情况下,您需要photoCategoryCell能够在现有 bienController视图控制器上调用方法。在photoCategoryCell中,定义一个协议,指示它希望调用的方法:

protocol PhotoCategoryCellDelegateProtocol {
    func didTapExtendInPhotoCollectionViewCellWithIndex(index: Int, inPhotoCategoryCell: photoCategoryCell)
}

然后使用以下类型向delegate添加photoCategoryCell属性:

var delegate : PhotoCategoryCellDelegateProtocol?

extendFunc方法中,将bienController().boo(sender.tag)替换为呼叫:

self.delegate?.didTapExtendInPhotoCollectionViewCellWithIndex(sender.tag, inPhotoCategoryCell: self)

bienController类中,实现这个新功能:

func didTapExtendInPhotoCollectionViewCellWithIndex(index: Int, inPhotoCategoryCell: photoCategoryCell) {
    self.boo(index) // or use performSegue if you prefer
}

修改bienController的类定义,以表明它采用此协议:

class bienController : UIViewController, UITableViewDelegate, UITableViewDataSource, PhotoCategoryCellDelegateProtocol { ...

cellForRowAtIndexPath中,请务必将delegate上的photoCategoryCell属性设置为自我:

        ...
        } else if indexPath.row == 1 && self.imageNb >= 3 {

            var cell = tableView.dequeueReusableCellWithIdentifier("photoCategoryCell") as! photoCategoryCell!

            if cell == nil {

                cell = photoCategoryCell(style: UITableViewCellStyle.Default, reuseIdentifier: "photoCategoryCell")
            }

            cell.imageList.removeAll(keepCapacity: false)
            for i in 0...10 {
            cell.imageList.append(UIImage(named: "maison")!)
            }
            // set the cell's delegate...
            cell.delegate = self
            cell.collectionView.delegate = cell
            cell.collectionView.dataSource = cell

            return cell
        } else ...

请注意,我已经定义了协议方法来传递集合视图单元索引表视图单元格:所以如果你有多个具有集合视图的表视图行,你可以确定正确的电视行。

作为最后的风格注释,类名的开头练习以大写字母开头;我现在会养成这种习惯,所以将bienController修改为BienController等等。