我尝试在单击 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]
}
}
}
然后,我尝试了这个:
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
中,确保将 photoCategoryCell
的 delegate
属性设置为 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/