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
Related
I have prepared a segue but when the user selects a cell it is not pass label text to text in detail View
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "viewNumberSegue" {
guard let indexPath = sender as? IndexPath else { return }
let collectionCell = collectionView.cellForItem(at: indexPath) as! ItemCollectionViewCell
let textToPass = collectionCell.ItemLabel.text
let detailVC = segue.destination as? DetailViewController
detailVC?.number = textToPass!
}
}
// MARK: UICollectionViewDelegate
extension GridCollectionViewController {
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "viewNumberSegue", sender: indexPath)
}
}
DetailVC
import UIKit
class DetailViewController: UIViewController {
var number:String = ""
#IBOutlet weak var numberLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
print(number)
numberLabel.text = number
}
}
Instead of passing the indexPath in sender, it's better to directly pass the number as sender.
extension GridCollectionViewController {
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let collectionCell = collectionView.cellForItem(at: indexPath) as! ItemCollectionViewCell
let textToPass = collectionCell.ItemLabel.text
self.performSegue(withIdentifier: "viewNumberSegue", sender: textToPass)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "viewNumberSegue" {
guard let number = sender as? String else { return }
let detailVC = segue.destination as? DetailViewController
detailVC?.number = number
}
}
I have a collection view that is selecting an Item in its index and performing a segue to the next ViewController. When the next ViewController is presented, the value of my object is nil.
Here is the call in the collectionView:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let adViewVC = storyboard?.instantiateViewController(withIdentifier: adViewPageID) as? AdViewPageVC else {return}
let adChoice = adArray[indexPath.row]
adViewVC.advertisement = adChoice
performSegue(withIdentifier: adViewPageSegue, sender: self)
}
Note that the guard statement is going through and if I print a value from the adArray it has value in this function.
After I perform the segue which does open the right ViewController the advertisement object is always nil.
var advertisement : Advertisement!
override func viewDidLoad() {
super.viewDidLoad()
let title = advertisement.title
print(title)
}
This is never getting the value of the object even when I can see that it has value during the assignment on the didSelectItem function for the collection view.
What am I missing here?
When the user taps on the collectionViewCell, the app should perform segue with an indexPath as a sender:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: adViewPageSegue, sender: indexPath)
}
And prepare all of neccessary things in the prepare(for:sender:) method. And you don't have to init a viewController from the storyboard. segue.destination is enough.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
if identifier == adViewPageSegue {
guard let adViewVC = segue.destination as? AdViewPageVC else {return}
let indexPath = sender as! IndexPath
let adChoice = adArray[indexPath.row]
adViewVC.advertisement = adChoice
}
}
}
You should be setting the advertisement variable in a prepare(for:sender:) function. The view controller that you are creating in the didSelect function is not being used.
Add something like this:
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let viewController = segue.destination as? PlayerViewController {
let adChoice = adArray[sender]
viewController.advertisement = sender as? STZMediaItem
}
}
And update your didSelect function to be:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
performSegue(withIdentifier: adViewPageSegue, sender: indexPath)
}
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
}
}
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!
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]
}
}