There are many other topics of passing data to another ViewController - i know - but i could not find the solution for passing data from UITableViewCell to UIViewController. The question differs from others that here i have to access an ImageView in another class of UITableViewCell. Segues, prepare for segues an other topics are discussed in other posts sufficiently but not this special constellation.
I have a class UITableViewCell:
class PostCell: UITableViewCell {
...
// networkService is downloading an image
networkService.downloadImage({ (imageData) in
let image = UIImage(data: imageData as Data)
...
// image is set to UIImageView
self.postImageView.image = image
In my ViewController i do this to go to the DetailViewController:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
aktIndex = indexPath.section
performSegue(withIdentifier: "segueDetail", sender: self)
}
I tried this:
let MainStory:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let desVC = MainStory.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
desVC.getImage = ???
self.navigationController?.pushViewController(desVC, animated: true)
DetailViewController:
class DetailViewController: UIViewController {
var getImage = UIImage()
...
I have made a segue in xcode (segueDetail):
At the moment i store the imagedata in UserDefaults and read them again in the DetailViewController. Very weird, i know.
Where do i have to pass the data from? In my PostCell or in the ViewController? The problem is to get access to image-data from PostCell in my ViewController.
In tableView(_:didSelectRowAt:)
when you call performSegue(withIdentifier: sender:)
, you can pass any data or references in it. This is now available in prepare(forSegue:sender:)
and your last shot at preparing the data to be passed to the segued viewController
.
If segueDetail
is properly hooked up via storyboard and your user taps on a row, you could send the indexPath
to the segue like:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "segueDetail", sender: indexPath)true)
}
Then in prepare(forSegue:sender:)
, depending on your solution, you can prepare access to the required data that you need to pass to the next viewController
like:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? DetailViewController {
let indexPath = sender as! IndexPath
let cell = tableView.cellForRow(at: indexPath) as! PostCell
vc.getImage = cell.postImageView.image
}
}
If you are not using a segue and the user taps on a row, you could manually push a viewController
with data like:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
let cell = tableView.cellForRow(at: indexPath) as! PostCell
vc.getImage = cell.postImageView.image
self.navigationController?.pushViewController(desVC, animated: true)
}
And your DetailViewController
should be:
class DetailViewController: UIViewController {
var getImage: UIImage?
//...
NOTE: This answer is the best I could fit to work with the given content.
It should just about work but please don't just copy-paste as it's not optimized (for example, your user taps on a cell before it's image is downloaded).
This was just to show the basics, so please improvise and apply proper case handling.