prepareForSegue is never called in UICollectionView - ios

Good afternoon,
I'm trying to perform a segue from my CollectionView but the prepareForSegue is never triggered when touching a Cell. This is working for my TableView but it's not for my CollectionView.
As you can see in my code, I have both in the same ViewController, but I don't know why it's only working for the TableView. The "segueCollection" is never triggered.
What I have to do in order to make this work? There is some type of problem because I'm also using the TableView segue? I'm a little bit lost here.
Here is my code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showMovieFromTable", let destination = segue.destinationViewController as? MovieViewController, index = tableView.indexPathForSelectedRow?.row {
destination.year = searchMovies[index].year
} else if segue.identifier == "showMovieFromCollection" {
print("segueCollection")
}
print("segueTriggered")
}
I'm also trying inside this code (but it's also not showing anything):
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
print(indexPath)
self.performSegueWithIdentifier("showMovieFromCollection", sender: self)
}
Thanks in advance,
Regards.

I had the same problem and got stuck there for a bit time. Finally I realize, instead of using prepareForSegue, I have to use prepare function.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "YourIdentifier" {
// stuff you want to do
}
}

Related

Passing value from table view controller to view controller

I tried to pass the value of the cell that the user clicks on to another view controller.
Here is my code.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
productDisplayed = currentProductList[indexPath.row] as? Product
performSegue(withIdentifier: "ProductDetailSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if ( segue.identifier == "AddProductSegue"){
let controller: AddProductViewController = segue.destination as! AddProductViewController
controller.delegate = self
}
if ( segue.identifier == "ProductDetailSegue"){
let controller: ProductDetailsViewController = segue.destination as! ProductDetailsViewController
controller.currentProduct = productDisplayed
}
}
Firstly, I didn’t write “performSegue()”.
The issue I met is that the screen will be transferred firstly rather than assign the value to “productDisplayed”, which means the object “currentProduct” in the second VC is nil.
Then I added “performSegue()”.
It still didn’t work. The thing is the second screen was displayed twice. The first time is same with the picture above. And the second time is correct.
But when I tried to click the back button on the left top. It returned to the nil page rather than the ProductDetail page. The screenshot is as follows.
It seems like "prepare" method always being called first then the tableView. How to change the order? If can, this should be fixed I think.
Hope to get your help.
Thank you.
Cause of Problem:
In your storyboard, you may have bound, ProductDetailsViewController with UITableViewCell directly.
It means, upon click/selection of row, it will perform segue (navigation) operation directly.
At the same time, programatically you perform navigation operation using performSegue(withIdentifier: "ProductDetailSegue", sender: self)
Solution:
You have two ways to solve this issue.
I recommend - In your story board, switch segue connection from UITableViewCell to UIViewController (Remove segue connection from UITableViewCell and attach the same segue connection with UIViewController of your tableview)
In your source code, delete/remove this line performSegue(withIdentifier: "ProductDetailSegue", sender: self) and handle data transmission from this function override func prepare(for segue: UIStoryboardSegue, sender: Any?)

How to send collectionView data to another ViewController in swift3?

I want to my collection View data (list.assets_id) want to parse DetailChannel
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
vedioId = id
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "detailChannel"{
let destinationVC = segue.destination as! DetailsChannel
destinationVC.vedio_id = vedioId
}
}
In my DetailChannel ,
override func viewDidLoad() {
super.viewDidLoad()
debugPrint("DetailsChannel:::::\(vedio_id)")
if let stringVideo = vedio_id {
print(stringVideo)
}
}
but didn't work my project and didn't call func prepare().How to slove?
I guess you've added segue from CollectionViewCell to
DetailChannel. Delete that segue.
Now add a segue from your CollectionViewController (not CollectionViewCell) to DetailChannel. If you don't know how to add it, here is the process:
First control-drag from the CollectionViewController to
DetailChannel and let go. visualize
here
Then select the segue and name it something meaningful to you (in your case detailChannel).
visualize here
Now inside your collectionView(_:didSelectItemAt:) method add this line:
performSegue(withIdentifier: "detailChannel", sender: self)
I hope your prepare(for:sender:) is now being called.

How to create View Controller and its Controls programmatically in Swift?

I am populating a table view as menu using a custom table view cell and using it as menu.I am able to navigate to other views using navigation controller.
But I want to create views and its controls programmatically. Is it possible?
Can anyone please share me an example. Please find my menu structure in the following image.
This is how i did it. It works like a charm!!!
func tableView(_tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Remove the below line from this function as it will perform segue.
//performSegue(withIdentifier: "DynamicSegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {
// This will actually perform your segue
var DestViewController = segue.destination as! DynamicSuperView
let selectedRow = tableView.indexPathForSelectedRow?.row
DestViewController.labelText = names[selectedRow!]
}

displaying pictures when tapping a tableview cell

i recently made a tableview filled with cells. i was wondering if i can, when i tap a cell display a certain picture instead of a blank screen
i tried linking cells with different image views but i can't do that using a tableview ,so what is the required code
i do know that I'm supposed to use the prepareForSegue statement
override prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {}
i just don't know what to type
i only want to add an image display when i tap one of the cells
thanks for the help
You have to add another view controller in your storyboard which will be opened after tapping the cell.
In tableView(_:didSelectRowAtIndexPath:) you have to remember which cell was tapped, and in prepareForSegue you can pass data to the destination view controller. In destination view controller just load the image based on data passed.
You can use prepareForSegue to pass data from your cell to the next ViewController (the image one).
I would do something similar to this.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.indexTapped = indexPath.row
self.performSegueWithIdentifier("goToImageViewController", sender: self)
}
....
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "goToImageViewController") {
var vc = segue.destinationViewController as! ImageViewController
vc.image = imageDatasource[indexTapped] as! UIImage
}
}
Once you call performSegueWithIdentifier(identifier: String?, sender: AnyObject?) the transition will be automatically handled after executing the prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) code.

Sending information to detail view upon CollectionViewCell selection

I'm trying to send information to a detail view about the cell selected upon selection. Right now, prepareForSegue runs prior to the collection view delegate method I'm using. This results in me sending the information of the previous cell selection and not the current one.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
collectionView.deselectItemAtIndexPath(indexPath, animated: true)
nextScreenRow = indexPath.row
self.performSegueWithIdentifier("toDetails", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toDetails" {
let vc = segue.destinationViewController as HistoryDetailsViewController
vc.postcard = postcards[nextScreenRow]
}
}
Two things. If the segue is made from the cell, then you shouldn't be calling performSegue in code; selecting the cell will trigger the segue with no code. Secondly, when you connect a segue this way, you don't need to implement didSelectItemAtIndexPath at all (but it's ok if you just want to call deselectItemAtIndexPath). There's no need for it; you can do everything you need to in prepareForSegue. The cell will be the sender, so can just do this,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "toDetails" {
let cell = sender as UICollectionViewCell
let indexPath = collectionView!.indexPathForCell(cell)
let vc = segue.destinationViewController as HistoryDetailsViewController
vc.postcard = postcards[indexPath.item]
}
}

Resources