Preparing segue in Collection View - ios

I have collection view implemented but have an error for the segue. I am trying to hand the image to another view controller using a segue. This is the code for it.
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("showImage", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "showImage"
{
let indexPaths = self.collectionView!.indexPathsForSelectedItems()!
let indexPath = indexPaths[0] as NSIndexPath
let vc = segue.destinationViewController as! NewViewController
vc.image = self.imageArray[indexPath.row]!
vc.title = self.appleProducts[indexPath.row]
}
}
}
However I am having an error at collectionView!.indexPathsForSelectedItemssaying that Could not find member indexPathsForSelectedItems. Why is this happening and how should it be changed. Thank you

I have mode some changes to your code
Add following changes in your code
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
{
self.performSegueWithIdentifier("showImage", sender: indexPath)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "showImage"
{
let indexPath : NSIndexPath = sender as! NSIndexPath
let vc = segue.destinationViewController as! NewViewController
vc.image = self.imageArray[indexPath.row]!
vc.title = self.appleProducts[indexPath.row]
}
}

Related

How to pass data from collection view to table view class?

Here I am having a model class in which from this I need to pass selected sku value from collection view to table view in another class can anyone help me how to implement this ?
Here is the code for didselect item at index path method
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// Here you can check which Collection View is triggering the segue
if collectionView == firstCategory {
} else if collectionView == secondCategory {
// from other CollectionView
}else if collectionView == newCollection{
newPassedSku = newModel[indexPath.item].sku as? String
print(newPassedSku)
}else{
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "firstCategorySegue" {
_ = segue.destination as! ProductListViewController
}
else if segue.identifier == "secondCategorySegue" {
_ = segue.destination as! ProductListViewController
}else if segue.identifier == "newSegue"{
let detailsViewController = segue.destination as! ProductDetailsViewController
detailsViewController.index = newPassedSku
print(newPassedSku)
}
else {
_ = segue.destination as! ProductDetailsViewController
}
}
You need to make your segue directly from your collectionview controller to tableview controller, you are calling it from collectionview cell hence prepareforsegue is getting called first
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == newCollection{
newPassedSku = newModel[indexPath.item].sku as? String
self.performSegue(withIdentifier: "secondCategorySegue",
sender: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "newSegue"{
let detailsViewController = segue.destination as! ProductDetailsViewController
detailsViewController.index = newPassedSku
}
}
You have made direct segue from the Collection Cell instead of from ViewController. That is why the override func prepare(for segue: UIStoryboardSegue, sender: Any?) method is called before func collectionView(_ collectionView: UICollectionView, didSelectItemAt.
So you basically do need to make your segue from View Controller to the next View Controller.
Then you have to call the segue manually like:
self.prepare(for: "segueIdentifier", any: nil) inside func collectionView(_ collectionView: UICollectionView, didSelectIt method.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == newCollection{
newPassedSku = newModel[indexPath.item].sku as? String
print(newPassedSku)
self.prepare(for: "segueIdentifier", sender: newPassedSku)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "newSegue"{
guard index = sender as? String else {
return //do not segue if index is not valid
}
let detailsViewController = segue.destination as! ProductDetailsViewController
detailsViewController.index = index
print(newPassedSku)
}
}
Works perfectly when u need to pass data from model class
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "firstCategorySegue" {
_ = segue.destination as! ProductListViewController
}
else if segue.identifier == "secondCategorySegue" {
_ = segue.destination as! ProductListViewController
}else if segue.identifier == "newSegue"{
let detailsViewController = segue.destination as! ProductDetailsViewController
let indexPaths = self.newCollection.indexPathsForSelectedItems
let indexPath = indexPaths?[0]
let obj = newModel[(indexPath?.row)!]
detailsViewController.index = obj.sku as! String
print(obj.sku)
}
else {
_ = segue.destination as! ProductDetailsViewController
}
}

How to send a selected collectionview cell to another view controller (ios)?

I'm being able to detect the selected row (image) in my collection view, But I need to send it to another view controller. Here is a part of the code :
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? CollectionViewCell {
cell.cellImage.image = UIImage(named: images[indexPath.row])
return cell
} else {
return CollectionViewCell()
}
}
//Printinig the selected image ID in console
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
SelectedItem = indexPath.row + 1
print(SelectedItem)
}
//Navigate to MPViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let DestViewController = segue.destination as! MPViewController
DestViewController.labelText = String(SelectedItem)
}
}
Initialize a variable first
var imageToPass: UIImage!
Then update didSelectItemAt func
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
SelectedItem = indexPath.row + 1
print(SelectedItem)
self.imageToPass = UIImage(named: images[SelectedItem])
performSegue(withIdentifier: "TargetVC", sender: imageToPass) //here you give the identifier of target ViewController
}
Go to your TargetVC and initialize a variable
var getImage: UIImage!
Then override the function in previous VC
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "TargetVC" {
if let targetVC = segue.destination as? TargetVC {
if let imageToPass = sender as? UIImage {
TargetVC.getImage = imageToPass
}
}
}
}
//Printinig the selected image ID in console
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
self.SelectedItem = indexPath.row + 1
self.selectedImage = UIImage(named: images[indexPath.row]);
print(SelectedItem)
}
//Navigate to MPViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let DestViewController = segue.destination as! MPViewController
DestViewController.imageSelected = self.selectedImage;
DestViewController.selectedItem = String(self.SelectedItem);
}
Now in MPViewController you can use the data self.imageSelected and self.selectedItem as per your requirements.
Take one instance variable in your destination class and set value of it in prepare for segue and then in viewDidload set that string to your label's text like,
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let DestViewController = segue.destination as! MPViewController
DestViewController.yourText = String(SelectedItem)
}
ans in viewDidload
yourLabel.text = yourText

UICollectionView prepareForSegue indexPathForCell is nil iOS 9

The problem is this line return nil:
if let indexPath = self.collectionView?.indexPathForCell(sender as! UICollectionViewCell)
For that reason I can't pass any information, The identifier is set and the delegate is set.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "DetalleSegueIdentifier" {
if let indexPath = self.collectionView?.indexPathForCell(sender as! UICollectionViewCell) {
let detailVC = segue.destinationViewController as! DetalleNoticiaViewController
detailVC.contact = self.noticia[indexPath.row]
}
}
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("DetalleSegueIdentifier", sender: collectionView.cellForItemAtIndexPath(indexPath))
}
Any help?
The problem is how to try to get the cell back. You must pass the cell in the performSegueWithIdentifier and then recover it in prepareForSegue.
Here is the code:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("DetalleSegueIdentifier", sender: collectionView.cellForItemAtIndexPath(indexPath))
}
And then
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "DetalleSegueIdentifier" {
if let cell = sender as? UICollectionViewCell{
let indexPath = self.collectionView!.indexPathForCell(cell)
let detailVC = segue.destinationViewController as! DetalleNoticiaViewController
detailVC.contact = self.noticia[indexPath.row]
}
}
}
Hope it helps!
Try Like this..
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("DetalleSegueIdentifier", sender: indexPath)
}
and get your indexpath like this...
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "DetalleSegueIdentifier" {
let aIndPath = sender as! NSIndexPath
let detailVC = segue.destinationViewController as! DetalleNoticiaViewController
detailVC.contact = self.noticia[aIndPath.item]
}
}
The problem is the var collectionView is not reference in my ViewController for that reason always return nil. My mistake thanks you for your answers.
#IBOutlet weak var collectionView: UICollectionView!

Swift didSelectRowAtIndexPath and prepareForSegue

I need to add a value to the selected row than in prepareForSegue that it does its action.But my prepareForSegue is doing the action before it.When i try to place the "performSegueWithIdentifier" it crashes,also i have added the id to the segue idenfifier in the storyboard.Im working with sqlite.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath.row
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "editSegue")
{
let viewController : WorkoutView = segue.destinationViewController as! WorkoutView
viewController.workoutInfoData = marrStudentData.objectAtIndex(selectedRow) as! WorkoutInfo
navigationItem.title = ""
}
}
You can fetch the selected indexPaths from tableView in your prepare for segue
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "editSegue")
{
if let indexPath = tableView.indexPathForSelectedRow{
let viewController : WorkoutView = segue.destinationViewController as! WorkoutView
viewController.workoutInfoData = marrStudentData.objectAtIndex(indexPath.row) as! WorkoutInfo
navigationItem.title = ""
}
}
}

Refresh same view controller with new data?

I have a song page with recommended songs in a table view. When a user clicks on a recommended song, I want to essentially reload the song page with the new data. To do that, I'm using this method, with a segue from the cell to its own view controller:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let newSong = recommendedTitles[indexPath.row]
self.performSegueWithIdentifier("refreshSong", sender: newSong)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "refreshSong" {
let newSong:String = sender as! String
let song = segue.destinationViewController as! SongViewController
song.search = newSong
}
}
But I'm getting an error at let newSong:String = sender as! String, that it could not cast value of type recommendationCell to NSString. Is the best way to do all of this with the aforementioned tableView methods?
You do not have to declare global variable.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("refreshSong", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "refreshSong" {
let indexPath = tableView.indexPathForSelectedRow()
let song = segue.destinationViewController as! SongViewController
song.search = recommendedTitles[(indexPath?.row)!]
}
}
you try this. Take the variable newSong in declaration section
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
newSong = recommendedTitles[indexPath.row]
self.performSegueWithIdentifier("refreshSong", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "refreshSong" {
let song = segue.destinationViewController as! SongViewController
song.search = newSong
}
}

Resources