Swift:如何在UITableViewController中使用“didSelectItemAtIndexPath”(包含UICollectionView)?

我有一个UITableViewController,在TableViewCell中,它是一个UICollectionView。 我想在用户点击单元格时将CollectionViewCell中的数据传递给DetailViewController。 我将一个segue从CollectionViewCell拖到DetailViewController,并在TableViewCell(包含CollectionView)中使用了“didSelectItemAtIndexPath”,它可以工作。

class TableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate { var posts1: [Posts] = [Posts]() var posts2: [Posts] = [Posts]() var categories: [Category] = [Category]() var selectedPost1: Posts? @IBOutlet weak var theCollectionView: UICollectionView! func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return posts1.count } func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let collectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! CollectionViewCell let imageUrlString: String = posts1[indexPath.row].postThumbnailUrlString let imageUrl: NSURL = NSURL(string: imageUrlString)! //Give Images A round cornor let filter = AspectScaledToFillSizeWithRoundedCornersFilter( size: collectionViewCell.postImageView.frame.size, radius: 20.0 ) collectionViewCell.postImageView.af_setImageWithURL(imageUrl, filter: filter) collectionViewCell.postTitleLabel.text = posts1[indexPath.row].postTite return collectionViewCell } func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { print("selected") self.selectedPost1 = self.posts1[indexPath.row] } 

它可以打印“已选择”,这意味着数据已经存储在“self.selectedPost1”中。 但是我不能在这个类中使用“prepareForSegue”,因为它只能在ViewController中使用。 有人告诉我在我的“HomeTableViewController”中实现“UICollectionViewDelegate”,并在HomeTableViewController中调用函数“didSelectedItemAtIndexPath”,如下所示:

 import UIKit class HomePageTableViewController: UITableViewController,UICollectionViewDelegate { let sections: NSArray = ["latest news", "good news"] var posts1: [Posts] = [Posts]() var selectedIndexPath: NSIndexPath? override func viewDidLoad() { super.viewDidLoad() } override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { if section  Int { return sections.count } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { if indexPath.row == 0 && indexPath.section == 0 { let tableViewCell = tableView.dequeueReusableCellWithIdentifier("TableViewCell") as! TableViewCell tableViewCell.getCategories() // tableViewCell.scrollToNextCell() // tableViewCell.startTimer() return tableViewCell } func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { self.performSegueWithIdentifier("goToDetail", sender: TableViewCell()) print("selected") } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if let tableViewCell1 = sender as? TableViewCell, let postDetailPage = segue.destinationViewController as? DetailViewController{ let selectedPosts = tableViewCell1.selectedPost1 postDetailPage.selectedPost?.selectedPost1 = selectedPosts } 

但是,“didSelectedItemAtIndexPath”无法调用,没有打印。 我不知道为什么?

这是我的DetailViewController:

 import UIKit class DetailViewController: UIViewController { @IBOutlet weak var postImageView: UIImageView! var posts: [Posts] = [Posts]() var selectedPost: TableViewCell? override func viewDidLoad() { super.viewDidLoad() if let post = selectedPost?.selectedPost1{ let thumbnailUrlString = post.postThumbnailUrlString let imageUrl: NSURL = NSURL(string: thumbnailUrlString)! print(thumbnailUrlString) postImageView.af_setImageWithURL(imageUrl) } } 

我还需要在viewDidLoad或viewDidAppear中实现吗?

几天来我一直在努力解决这个问题? 需要一些关于如何从UICollectionViewCell(在UITableViewCell内部)到新的UIViewController进行Segue的建议。 非常感谢。

你的方式是正确的,但你正在创建一个错误。 UICollectionViewDelegateTableViewCell实现UICollectionViewDelegate方法didSelectItemAtIndexPath并从HomePageTableViewController删除它。

现在声明一个协议,然后在TableViewCell中创建它的实例并在HomePageTableViewController实现协议,之后在didSelectItemAtIndexPath使用该委托实例来调用这样的方法。

 protocol PostDelegate { func selectedPost(post: Posts) } 

现在在TableViewCell创建它的实例,并在didSelectItemAtIndexPath调用此委托方法。

 class TableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate { var posts1: [Posts] = [Posts]() var posts2: [Posts] = [Posts]() var categories: [Category] = [Category]() var selectedPost1: Posts? var postDelegate: PostDelegate? func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { postDelegate?. selectedPost(self.posts1[indexPath.row]) } } 

现在在HomePageTableViewController实现这个PostDelegate协议

 class HomePageTableViewController: UITableViewController,UICollectionViewDelegate { //Your code func selectedPost(post: Posts) { //You will get your post object here, do what you want now } } 

注意:cellForRowAtIndexPath里面不要忘记用你的HomePageTableViewController设置postDelgate的委托

 tableViewCell.postDelegate = self 

编辑:

 func selectedPost(post: Posts) { //You will get your post object here, do what you want now self.performSegueWithIdentifier("goToDetail", sender: post) } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { let post = sender as! Posts let postDetailPage = segue.destinationViewController as? DetailViewController postDetailPage.passPost = post } 

所以,你还没有实现

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

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell 

第二个实现中的方法。 另外,尝试在集合视图单元格上放置一个不可见的按钮,并将标记指定为该集合视图单元格的索引路径,如下所示:

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { .... myButton.tag = indexpath.item } 

在此之后,您可以实现从collectionviewcell类到homepagetableviewcontroller类的委托回调,也可以直接按代码推送详细视图控制器。

至于详细视图控制器中的图像设置。 您可以在viewdidLoad()或viewDidAppear()中执行此操作。 没关系。