swift - 单击 TableViewCell 中 collectionView 的 uicollectionViewCell 中的按钮时显示新的 View Controller

标签 swift uitableview uicollectionview uicollectionviewcell

我尝试在单击 collectionViewCell 中的按钮时显示 ViewController。

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

在每个 collectionViewCells 中,有一个按钮应该是 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 的按钮链接在一起。 当它来自 didSelectRowAtIndexPath 时,segue 有效,但是当我单击按钮扩展时,它崩溃并出现相同的错误:“由于未捕获的异常‘NSInvalidArgumentException’而终止应用程序,原因:‘Receiver () has no segue with identifier‘image’” '

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

然后我尝试直接显示 View Controller 而不执行 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 中的“扩展”按钮时,没有任何反应..

拜托,我需要帮助!!

谢谢!!

完整代码

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

        }
    }
}

最佳答案

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

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

使用标准 init 方法创建 bienController 类的新实例。因此,它不了解 Storyboard,因此无法找到转场。

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

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

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

在这种情况下,您需要您的 photoCategoryCell 能够在您的现有 bienController View Controller 上调用方法。在 photoCategoryCell 中,定义一个协议(protocol)来指示它期望调用的方法:

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的类定义,表明它采用这个协议(protocol):

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

cellForRowAtIndexPath 中,确保将 photoCategoryCelldelegate 属性设置为 self:

        ...
        } 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 ...

请注意,我已经定义了协议(protocol)方法来传递 Collection View 单元格索引表格 View 单元格:所以如果您有多个带有 Collection View 的表格 View 行,您可以确定正确的电视行。

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

关于swift - 单击 TableViewCell 中 collectionView 的 uicollectionViewCell 中的按钮时显示新的 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37234795/

相关文章:

swift - 需要按 ObjectBulletin.id 对 tableview 进行排序

ios - 快速定位中心 UICollectionViewCell

ios - NSRangeException',原因 : '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 . 。 1] 核心数据和 NSFR 错误

ios - 具有居中 UISlider 和两个图像的自定义 UITableViewCell

ios - 在预填充的 TableView 上显示 NSArray

ios - 通过 NSNotification 从 UICollectionView 中删除单元格

ios - 更新 UICollectionView 补充 View 的方向更改约束

ios - 如何定义适当的约束以使 ScrollView 有效工作

ios - 如何在核心数据中保存明天日期任务以及如何将这些任务放入 Swift 的 TableView 中?

ios - 关于在带有聊天端的 iOS 上开发应用程序的建议