Sending information to detail view upon CollectionViewCell selection - ios

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]
}
}

Related

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.

The cell I press in my table sends the label for the previously pressed cell

I am new to Swift and I have this interesting problem.
I am trying to send the label of a table cell when I segue to another view controller where I print it. The problem is that it is printing the label of the cell that was pressed previous to this press.
Here is the code in the main view controller that passes the label:
// When a user taps on a cell on the tableView, it asks for a tag name for that image.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Cell \(indexPath) selected")
// Get cell image.
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!) as! ImageFeedItemTableViewCell
imagePass = currentCell.itemImageView
labelPass = currentCell.itemTitle
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Send image to GreetingViewController.
if segue.identifier == "GoToGreeting" {
var greetingvc = segue.destination as! GreetingViewController
greetingvc.passedImage = imagePass
greetingvc.passedLabel = labelPass
}
}
and here is the relevant code in the view controller that receives the passed label:
var passedImage: UIImageView? = nil
var passedLabel: UILabel? = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
print(passedLabel?.text)
}
Any help would be appreciated.
I believe prepare(for:sender:) gets called before tableView(_:didSelectRowAt:) when you hook up that segue in the storyboard.
What you can do is just use the sender parameter of the prepare(for:sender:) method to get the information you need at the right time. When a segue is triggered by a cell, as it seems to be in your case, then that cell will be the sender passed into the the prepare method. So, you could do something like:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Send image to GreetingViewController.
if let cell = sender as? ImageFeedItemTableViewCell, segue.identifier == "GoToGreeting" {
var greetingvc = segue.destination as! GreetingViewController
greetingvc.passedImage = cell.itemImageView
greetingvc.passedLabel = cell.itemTitle
}
}

prepareForSegue is never called in UICollectionView

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
}
}

Delay or error performing segue from TableView

I have seen two similar questions here but none of their answers really helped me.
I have a tableView of comments and I want to perform a segue to a detail of the comment (kind of like twitter does, if you click on a tweet you have a detail view of it). However the information given to the detail view is the penultimate row selected and not the last selected. And if you only select one, the segue wont be even performed.
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
dispatch_async(dispatch_get_main_queue()) {
self.performSegueWithIdentifier("detail_segue", sender: indexPath)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detail_segue"){
let row = (sender as! NSIndexPath).row;
let commentForSegue = self.AOS[row]
let destinationVC = segue.destinationViewController as! CommentDetailVC
destinationVC.detail_title = commentForSegue.titulo_comment
destinationVC.detail_body = commentForSegue.cuerpo_comment
destinationVC.detail_date = commentForSegue.fecha_comment
destinationVC.detail_num_agree = String(commentForSegue.num_agrees)
destinationVC.detail_num_disagree = String(commentForSegue.num_disagrees)
destinationVC.detail_agreed = commentForSegue.agreed
}
}
I've tried with and without the dispatch_async both on the prepareForSegue and didSelectRowAtIndexPath but it doesnt work. I've also tried doing all the work from the didSelectRowAtIndexPath but no success either.
Thanks!!
First of all, you need to call the segue in the method didSelectRowAtIndexPath and you're calling it from the method didDeselectRowAtIndexPath exist a little difference between both, but are some tips to get the last cell tapped too, see the following code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// the identifier of the segue is the same you set in the Attributes Inspector
self.performSegueWithIdentifier("detail_segue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detail_segue"){
// this is the way of get the indexPath for the selected cell
let indexPath = self.tableView.indexPathForSelectedRow()
let row = indexPath.row
let commentForSegue = self.AOS[row]
let destinationVC = segue.destinationViewController as! CommentDetailVC
destinationVC.detail_title = commentForSegue.titulo_comment
destinationVC.detail_body = commentForSegue.cuerpo_comment
destinationVC.detail_date = commentForSegue.fecha_comment
destinationVC.detail_num_agree = String(commentForSegue.num_agrees)
destinationVC.detail_num_disagree = String(commentForSegue.num_disagrees)
destinationVC.detail_agreed = commentForSegue.agreed
}
}
I hope this help you.

Passing value to another ViewController upon selecting cell in UICollectionView

I want to select a username from a UICollectionView, and pass that string to another view.
I can select the cell using "didSelectRowAtIndexPath". However the prepareForSegue function runs before my selection is set, and the segue passes the initial value.
I can't figure out how to get the index value in the prepareForSegue overide. If it were a UITableView, I think I could use indexPathForSelectedRow.
Here's what I have:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedUsername = userNames[indexPath.row]
selectedRow = indexPath.row
println ("Cell \(indexPath.row) selected")
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
nextVC.passedUsername = userNames[selectedRow]
println("prepareForSegue")
}
}
Running this always passes userNames[0]
The output window Prints:
prepareForSegue
Cell 2 selected
EDIT 1:
I basically think I want the following tableview code, but I can't get it working for UICollectionView (i.e. I can't get the cell number):
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
let indexPath = UserSelectCollection.indexPathForSelectedRow()
nextVC.passedUsername = userNames[indexPath.row]
}
}
Here's How I solved it:
I deleted the segue connecting the collection cell to the second view controller
I created another segue between the two view controllers (called the identifier "userSelectSegue")
Added a performSegueWithIdentifier call to the didSelectItemAtIndexPath
Here's the code:
var userNames = ["Bob", "Sally", "Mike", "Mary", "James"]
var selectedRow = 0
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
self.performSegueWithIdentifier("userSelectSegue", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "userSelectSegue") {
let nextVC = segue.destinationViewController as ViewController;
nextVC.passedUsername = userNames[selectedRow]
}
}
This is the general behavior of the iOS. What i implement is in this case is. Do not override the method didSelectRowAtIndexPath. When you tap on any cell, then in the function prepareForSegue. You can get the cell in the sender object. From that cell get the selected item. Get the indexPath.item. After that get the object from the array and pass it to the next view controller.

Resources