Evan Ngo
Evan Ngo

Reputation: 254

Swift - how to open another viewcontroller with CollectionViewCell inside UITableViewCell

I'm really new in iOS/Swift and i'm in a small project. In this project i have a UITableView inside ViewController. And i have another file custom CollectionViewCell in side UITableViewCell. I want when user click a cell in collectionview it will open another ViewController and it get data from this collectionviewcell. This is my uitableview swift file:

class IndexRow: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var names:[String] = ["Movie 1","Movie 2","Movie 3","Movie 4","Movie 5","Movie 6"]
@IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
    super.awakeFromNib()
    collectionView.registerClass(indexOneMovie.self, forCellWithReuseIdentifier: "onemovie")
    let nib = UINib(nibName: "indexOneMovie",bundle: nil)
    collectionView.registerNib(nib, forCellWithReuseIdentifier: "onemovie")
    self.collectionView.backgroundColor = UIColor.clearColor()
    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    print("Hello")
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return names.count
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = self.collectionView.dequeueReusableCellWithReuseIdentifier("onemovie", forIndexPath: indexPath) as! indexOneMovie
    cell.poster.image = UIImage(named: "poster.jpg")
    cell.name.text = names[indexPath.row]
    return cell
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    print(indexPath.item)
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    let itemsPerRow:CGFloat = 2
    let hardCodedPadding:CGFloat = 0
    let itemWidth = (collectionView.bounds.width / itemsPerRow) - hardCodedPadding
    let itemHeight = collectionView.bounds.height - (hardCodedPadding)
    return CGSize(width: itemWidth, height: itemHeight)
}

How i can do it?

Upvotes: 1

Views: 3397

Answers (2)

Muhammad Ali
Muhammad Ali

Reputation: 2183

You can do it like this :

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    print(indexPath.item)
    let name = names[indexPath.item]
    let distinationViewController = DistinationViewController()
    distinationViewController.name = name
    if let navVC: UINavigationController = UIApplication.sharedApplication().keyWindow?.rootViewController as? UINavigationController {
    navVC.pushViewController(distinationViewController, animated: true)
    }
}

This is just a way to do it i dont know which view you want to push or what your names array contains so kindly change those things accordingly.

get root navigationcontroller from uiapplication and perform push on it.

Upvotes: 2

Ajay Singh Thakur
Ajay Singh Thakur

Reputation: 485

ok i have recently implemented the same in my app these are the links where i refered initially -

https://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell-in-swift/

http://www.thorntech.com/2015/08/want-your-swift-app-to-scroll-in-two-directions-like-netflix-heres-how/

you are making uicollectionview delegate confirms to uitableview cell so you cannot present or push to other view controller.

here is my code hope it will help you

homeController.swift which contains uitableview

    extension HomeController : UITableViewDelegate {

        func tableView(tableView: UITableView,willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {

          guard let tableViewCell = cell as? TableViewCell else { return }
            //here setting the uitableview cell contains collectionview delgate conform to viewcontroller
          tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row, andForSection: indexPath.section)
          tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
        }

        func tableView(tableView: UITableView,didEndDisplayingCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {

            guard let tableViewCell = cell as? TableViewCell else { return }
            storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
        }

    }



    extension HomeController: UICollectionViewDelegate, UICollectionViewDataSource {
        func collectionView(collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
          let element : [CollectionViewElement] =  self.returnCollectionViewElementAccordingToIndex(collectionView.tag)
            return element.count
        }

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

          let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell",forIndexPath: indexPath) as! horizontalCollectionViewCell

          let element : [CollectionViewElement] =  self.returnCollectionViewElementAccordingToIndex(collectionView.tag)

          cell.cellTitleLabel.text = element[indexPath.row].videos.title
          cell.cellGenerLabel.text = element[indexPath.row].videos.gener

          return cell
      }

      func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){


        print("collectionviewtag:\(collectionView.tag) +  indexpathrow:\(indexPath.row)")
        //from here you can do push or present to anyview controller
        // collectionviewtag is tableView cell row value and indexpathrow return collectionView cell row value.



      }


    }

TableViewCell.swift :custom UITableViewCell which contains collectionView

    class TableViewCell: UITableViewCell {


        @IBOutlet  private weak  var collectionView: UICollectionView!

        @IBOutlet weak var cellLabel: UILabel!

        @IBOutlet weak var cellButton: UIButton!

        @IBAction func CellButtonActionTry(sender: UIButton) {

          print("Dude  \(cellButton.tag)")

        }




        var collectionViewOffset: CGFloat {
          get {
            return collectionView.contentOffset.x
          }

          set {
            collectionView.contentOffset.x = newValue
          }
        }

        func setCollectionViewDataSourceDelegate<D: protocol<UICollectionViewDataSource, UICollectionViewDelegate>>
          (dataSourceDelegate: D, forRow row: Int , andForSection section : Int) {

            collectionView.delegate = dataSourceDelegate
            collectionView.dataSource = dataSourceDelegate
            collectionView.tag = row // tableView indexpathrow equals cell tag
            collectionView.reloadData()
        }




        override func awakeFromNib() {
              super.awakeFromNib()
              // Initialization code
          }

          override func setSelected(selected: Bool, animated: Bool) {
              super.setSelected(selected, animated: animated)

          }

    }

Upvotes: 2

Related Questions