简体   繁体   中英

Properly segue from collectionview inside tableviewcell to another viewcontroller

I am trying to segue (pass data) from a collectionview inside a tableviewcell to a another viewcontroller. I tried using the didselect delegate but stuck on how to pass the data properly. It seems i kind of somehow hack my way around it but i would like to learn the proper way. Below is my code:

My Main view controller:

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "segue" {
        let vc = segue.destination as! DetailViewController
        vc.text = "Hello World"
    }
}

func segue() {
    self.performSegue(withIdentifier: "segue", sender: self)
}

}

My Table View:

 import UIKit

 class MainTableView: UITableView, UITableViewDelegate, UITableViewDataSource {

override func awakeFromNib() {
    self.delegate = self
    self.dataSource = self
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MainTableViewCell", for: indexPath) as! MainTableViewCell

    return cell
}

}

My Collection View:

import UIKit

class MoviesCollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {

override func awakeFromNib() {
    self.delegate = self
    self.dataSource = self
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MoviesCollectionViewCell", for: indexPath) as! MoviesCollectionViewCell

    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let vc = ViewController()
    vc.segue()
}

}

The View controller I am trying to segue to:

class DetailViewController: UIViewController {

@IBOutlet weak var label: UILabel!

var text: String?

override func viewDidLoad() {
    super.viewDidLoad()

    self.label.text = text
    // Do any additional setup after loading the view.
}
}

My tableviewcell and collectionviewcell are empty at the moment.

Your question is a little hard to answer as currently stated because it's not entirely clear what you are doing. For example, it's not clear if you are using Storyboards or not.

If you are, then you probably want to define your segues in the storyboard and let UIKit invoke them for you. This documentation provides the overview that will hopefully help you. In particular, you don't have to do the segue manually because UIKit will do it for you once you've set it up in the Storyboard (emphasis mine):

You do not need to trigger segues programmatically. At runtime, UIKit loads the segues associated with a view controller and connects them to the corresponding elements. When the user interacts with the element, UIKit loads the appropriate view controller, notifies your app that the segue is about to occur, and executes the transition. You can use the notifications sent by UIKit to pass data to the new view controller or prevent the segue from happening altogether.

In figure 9-4 you will see the event flow of a segue process. In particular, note that if you override prepareForSegue:sender: in your source view controller for the segue then that is your opportunity to prepare data and send it to the destination view controller (either view setting the representedObject for the destination view controller, or via a custom setter method defined for your destination view controller class). The description text below that figure spells it out:

The prepareForSegue:sender: method of the source view controller lets you pass data from the source view controller to the destination view controller. The UIStoryboardSegue object passed to the method contains a reference to the destination view controller along with other segue-related information.

If you aren't using storyboards, then you're essentially doing the same thing by hand. You allocate the UIViewController subclass you want to show in response to the touch in the cell item, and then set its representedObject to the data it should display (or call a custom method defined by that class and pass in the data the view controller needs to display), then you show the view controller. To present it manually you'll want to read the Presenting a View Controller document from Apple. In particular:

Presenting a View Controller

There are several ways to initiate the presentation of a view controller:

Use a segue to present the view controller automatically. The segue instantiates and presents the view controller using the information you specified in Interface Builder. For more information on how to configure segues, see Using Segues . Use the showViewController:sender: or showDetailViewController:sender: method to display the view controller. In custom view controllers, you can change the behavior of these methods to something more suitable for your view controller. Call the presentViewController:animated:completion: method to present the view controller modally.

Hopefully that's enough to get you going. If not, maybe clarify your question with a bit more context and we'll try again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM