2016-08-19 2 views
2

У меня есть UITableViewController, внутри TableViewCell это UICollectionView. Я хочу передать данные из CollectionViewCell в DetailViewController, когда пользователь постучал по ячейке. Я перетащил segue из CollectionViewCell в DetailViewController и использовал «didSelectItemAtIndexPath» внутри TableViewCell (который содержит CollectionView), и он работает.Swift: Как использовать «didSelectItemAtIndexPath» в UITableViewController (содержит UICollectionView)?

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. кто-то сказал мне, чтобы реализовать «UICollectionViewDelegate» в моем «HomeTableViewController», и вызовите функцию «didSelectedItemAtIndexPath» в HomeTableViewController, как это:

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 < sections.count{ 
     return sections[section] as? String 
    } 

    return nil 

} 

override func numberOfSectionsInTableView(tableView: UITableView) -> 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?

В течение нескольких дней я боролся с этой проблемой? нужны некоторые предложения о том, как сделать Segue из UICollectionViewCell (который находится внутри UITableViewCell) новому UIViewController. большое спасибо.

+0

для CollectionView внутри didSelectRowAtIndexPath, удалите SEGUE и обновить меня, если он напечатает «выбран» – jo3birdtalk

+0

я удалил Segue, и он все еще может печатать «выбран» после того, как я постучал по сотовому –

+0

I предложите обратиться [этот код github] (https://github.com/DipenPanchasara/UITableViewWithHorizontalScroll), который имеет ту же самую реализацию, которая вам нужна. Хотя в вашем коде вам нужно установить делегат 'UICollectionView' внутри' cellForRowAtIndexPath', используя 'cell.objectOfCollectionview'. –

ответ

1

, как вы собираетесь это правильно, но вы создаете один mistake.Try реализовать UICollectionViewDelegate метод didSelectItemAtIndexPath также внутри TableViewCell и удалить его из 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]) 
    } 
} 

Теперь реализовать этот PostDelegate протокол внутри HomePageTableViewController

class HomePageTableViewController: UITableViewController,UICollectionViewDelegate { 


    //Your code 

    func selectedPost(post: Posts) { 
     //You will get your post object here, do what you want now 
    } 
} 

Примечание: Внутри cellForRowAtIndexPath не забыли установить делегат postDelgate с вашими HomePageTableViewController как этот

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 
} 
+0

Извините, что я новичок в Swift, не очень знакомый с созданием нового протокола. так ли это означает, что мне нужно реализовать «протокол PostDelegate» внутри моего TableViewCell? и после этого я поместил этот протокол в свой HomePageTableViewController? Я удалил «didSelectedItemAtIndexPath» из HomePageTableViewController, мне все еще нужен «func prepareForSegue» в этом HomePageTableViewController? » –

+0

Объявить стороннюю сторону« TableViewCell »не внутри, создать экземпляр этого протокола внутри« TableViewCell », как мой ответ. –

+0

Вы можете объявить, что 'protocol' над классом' TableViewCell'. –

0

Таким образом, вы не реализовали методы в вашем втором варианте осуществления в

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

и

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

. Кроме того, попытайтесь поместить невидимую кнопку над видом коллекции ячейки и присвоить метку, чтобы быть indexpath этой CollectionView клетки, как это:

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

После этого вы можете либо реализовать делегат обратного вызова из collectionviewcell класса в homepagetableviewcontroller класса или нажмите контроллер подробного представления непосредственно по коду.

Что касается настройки изображения в контроллере подробного представления. Вы можете сделать это как в viewdidLoad(), так и в viewDidAppear(). Все нормально.

+0

Итак, вы Я должен реализовать «numberOfItemInSection» и «cellForItemAtIndexPath» в HomeTableViewController? Зачем мне это нужно? И сколько мне нужно вернуть? И для ячейки, как ее реализовать? Извините, я новичок в Swift. –

+0

Его не о быстром, но в общем случае для «numOfItemInSection» вызывается «cellForItemAtIndexPath». Итак, если количество элементов в разделе равно 0 (или не указано). Ячейка не сформирована. И, следовательно, «didSelectRowAtIndexPath» не будет иметь никакого эффекта. –

+0

Но в моем HomeTableViewController у меня есть numberOfRowAtIndexPath и cellForRowAtIndexPath. Но если я использую didSelectedRowAtIndexPath, он тоже не работает. Почему это? Спасибо –