Search code examples
iosswiftuitableviewuistoryboardsegue

prepareForSegue out of custom UITableViewCell


I have a new problem waiting for a solution. I have a little bit wired layout now. My MainView is a TableView, in one of the 6 custom cells is one cell that have a TableView in it. By clicking on a cell of this inner tableView I want a segue to a new YTPlayerViewController, a view for watching a youtube video using googles YThelper classes.

The problem is, that performSegueWithIdentifier and override func prepareForSegue stuff doesn't work because I have to handle them in my custom UITableViewCell class that don't know these functions.

Is there any alternative?

I just want to transfer my videoId from the cell to the YTPlayerViewController, open it and play the Video. From there it should be possible to go back.

hope you guys can understand and help me.

Greetings from germany

My Class:

class DetailVideoCell: UITableViewCell , UITableViewDelegate, UITableViewDataSource {


    @IBOutlet weak var tableView: UITableView!

    var selectedVideoIndex: Int!



    /*override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showPlayer" {
            let playerViewController = segue.destinationViewController as! YTPlayerViewController
            playerViewController.videoID = Data.youTubeVideos[selectedVideoIndex]["videoId"] as! String
        }
    }*/



    // MARK: TableViewDataSource functions.

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Data.youTubeVideos.count ?? 3
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: VideoDetailCell = tableView.dequeueReusableCellWithIdentifier("VideoDetailCell") as! VideoDetailCell

        let url = NSURL(string: Data.youTubeVideos[indexPath.row]["thumbnail"] as! String)
        let data = NSData(contentsOfURL: url!)
        let image = UIImage(data: data!)

        cell.videoThumbnail.image = image
        cell.channelTitle.text = Data.youTubeVideos[indexPath.row]["channelTitle"] as? String
        cell.videoTitle.text = Data.youTubeVideos[indexPath.row]["title"] as? String

        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedVideoIndex = indexPath.row
        print(selectedVideoIndex)
        //performSegueWithIdentifier("showPlayer", sender: indexPath)
    }

}

Solution

  • In your DetailVideoCell:

    // Create a protocol that will act as the delegate
    
    protocol DetailVideoCellDelegate: class {
        func selectedCellAtIndex(index: Int)
    }
    
    class DetailVideoCell: UITableViewCell , UITableViewDelegate, UITableViewDataSource {
    
    
    @IBOutlet weak var tableView: UITableView!
    
    var selectedVideoIndex: Int!
    
    // Create a delegate object
    weak var delegate: DetailVideoCellDelegate?
    
    
    /*override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
     if segue.identifier == "showPlayer" {
     let playerViewController = segue.destinationViewController as! YTPlayerViewController
     playerViewController.videoID = Data.youTubeVideos[selectedVideoIndex]["videoId"] as! String
     }
     }*/
    
    
    
    // MARK: TableViewDataSource functions.
    
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Data.youTubeVideos.count ?? 3
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell: VideoDetailCell = tableView.dequeueReusableCellWithIdentifier("VideoDetailCell") as! VideoDetailCell
    
        let url = NSURL(string: Data.youTubeVideos[indexPath.row]["thumbnail"] as! String)
        let data = NSData(contentsOfURL: url!)
        let image = UIImage(data: data!)
    
        cell.videoThumbnail.image = image
        cell.channelTitle.text = Data.youTubeVideos[indexPath.row]["channelTitle"] as? String
        cell.videoTitle.text = Data.youTubeVideos[indexPath.row]["title"] as? String
    
        return cell
    }
    
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedVideoIndex = indexPath.row
        print(selectedVideoIndex)
    
        // use the delegate to send the selected index back to your MainView
        delegate?.selectedCellAtIndex(selectedVideoIndex)
        //performSegueWithIdentifier("showPlayer", sender: indexPath)
        }
    
    }
    

    In your MainView:

    class MainView: DetailVideoCellDelegate {
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        // However you are configuring your cells set the DetailVideoCell delegate to self
    
        if cell.delegate == nil {
            cell.delegate = self
        }
    
        return cell
    }
    
    func selectedCellAtIndex(index: Int) {
    
        // Or whatever you are using the index for
        let identifier = yourArray[index]
    
        // Easiest way is to use a navigation controller to handle the segues to be able to go back
        // Otherwise you will need to do it in a custom way
        self.navigationController?.performSegueWithIdentifier(identifier, sender: self)
    
        }
    }