2
votes

I have a view crontroller called "subcateory2", this viewcontroller has a uicollectionview wit custom cell. I need two segues from my app. One of the called "to_videostable" from the viewcontroller to other view controller and the other calles "reload_collection" from the cell to the same viewcontroller(because the subcategory can have n-level of subcategories). The problem is with my prepareForSegue(i check in this function the identifier , that is defined in the " func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)",and execute different actions). When i select a cell this should happen:

  • first: go to my "func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)", check the condition and define my identifier for segue.

  • second: go to the prepareforsegue, check the condition and execute the actions.

but actually this happen:

  • first: in my ios simulator i select a cell.
  • second: my code go the prepareforsegue and go always for the segue called "reload_collection"(before going to my func collectionView(...)), and create a white views. In this moment is like a two threads are created, one of them go to the white windows and the other to the next stop.

  • third: this "second theard" go to the func collectionview(...) and check the condition, define the identifier, call to the performSegueWithIdentifier and go to the prepareforsegue function. In the prepareforsegue check the identifier and execute the differentes actions.

This is my code:

import UIKit

class Subcategory2: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    let viewUtils = ViewControllerUtils()
    var result_category: Array<JSON> = []

    @IBOutlet weak var collectionview: UICollectionView!
    var tit: String!
    var url: String!
    var end_url:String = "?page_size=100"
    var  id_category: Int!
    var index: NSIndexPath!
    var url_children : String = ""
    let imagePath = "http://d1rkb03u2ginv9.cloudfront.net/wp-content/uploads/"

    override func viewDidLoad() {

        self.viewUtils.showActivityIndicator(self.view)
        super.viewDidLoad()
        self.viewUtils.showActivityIndicator(self.view)
        if self.result_category.isEmpty{
            var category = category_function()
            self.url = self.url + self.end_url
            self.result_category = category.load_subcategory(self.url)}

        self.viewUtils.hideActivityIndicator(self.view)

    // Do any additional setup after loading the view.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    var cell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
    println("entroooooooo")
    if (self.result_category[indexPath.row]["children"].string != nil){
        self.url_children = self.result_category[indexPath.row]["children"].string!
        //while(self.url_children.isEmpty){}

        println("voy a reloadcollection")

        performSegueWithIdentifier("reload_collection", sender: cell)
        //performSegueWithIdentifier("reload_collection3", sender: self)
    }else{

        println("voy a to_videostables")

        performSegueWithIdentifier("to_videostable", sender: cell)
        }
}


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //println(result_category.count)
    return result_category.count }

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ->UICollectionViewCell {

    let cell: CollectionViewCellController2 = collectionView.dequeueReusableCellWithReuseIdentifier("cell2", forIndexPath: indexPath) as! CollectionViewCellController2
    println(self.result_category[indexPath.row]["slug"].stringValue)
    cell.label.text = self.result_category[indexPath.row]["slug"].stringValue


    if (self.result_category[indexPath.row]["images"]["file"].string != nil){
        //println("+++++++++++++++++")
        var image = self.result_category[indexPath.row]["images"]["file"].stringValue
        cell.image.sd_setImageWithURL(NSURL(string:self.imagePath + (image as! String)))

    }else{
        var image = "http://www.camping-oaza.com/images/joomlart/demo/default.jpg"
        cell.image.sd_setImageWithURL(NSURL(string: image))
        //cell.image.image = UIImage(named: image)
    }

    cell.NumberVideosLabel.text = self.result_category[indexPath.row]["videos_count"].stringValue
    cell.NumberSubcategoryLabel.text = self.result_category[indexPath.row]["children_count"].stringValue

    return cell
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "to_videostable"{
        println("-------------")
        println("voy a to_videostables")
        let cell = sender as! UICollectionViewCell
        let index = self.collectionview!.indexPathForCell(cell) // this return -> NSIndexPath?
        //if (self.result_category[index!.row]["children"].string != nil){
        //   self.loaddata(self.result_category[index!.row]["children"].string!)
        //}else{
        let vc : VideosViewController = segue.destinationViewController as! VideosViewController

        println(self.result_category[index!.row]["id"].intValue)
        vc.id_category =  self.result_category[index!.row]["id"].intValue

    }
    if segue.identifier == "to_livevideos"{
        println("-------------")
        println("to_livevideos")
        println("-------------------")
        let vc : SWRevealViewController = segue.destinationViewController as! SWRevealViewController
    }
    if segue.identifier == "reload_collection"{
        println("-------------")
        println("reload_collection")
        println("-------------------")
        var category = category_function()

        let vc : Subcategory2 = segue.destinationViewController as! Subcategory2


        vc.url = self.url_children
        println(category.load_subcategory(self.url_children + self.end_url))

    }


}
}

With this problem, always is created a white windows and after is created a windows with the real information.

the order of the println is : - "reload_collection" - "entroooooooo" - "voy a reloadcollection" or "voy a to_videostables"

In this pictures show my main.stoyboard and the windwos that i can see in my app. enter image description here

1
thanks friend. i trying to create the segue but when i drag drom the viewcontroller to the button yellow on the top, i only see "outless datasource and delegate" and no the option like "show, show detail..." how i can create a segue from a viewcontroller to itself?BarneyL. BarStin

1 Answers

0
votes

Updated Answer

You have a situation where you want to decide which segue to take when a cell is selected. You have wired one of your segues directly from the cell, which means the storyboard will create that segue for you. You also are calling performSegueWithIdentifier which creates another segue. You need to implement shouldPerformSegueWithIdentifier to cancel the "reload_collection" segue when you want segue to "to_videostables".

In the Original Answer below, I suggested you wire both segues from the viewController, but that won't work because one of your segues is back to the same viewController.

So, another way to do this is to:

  1. Modify didSelectItemAtIndexPath to remove the code that handles the "reload_collection" segue. The Storyboard will be making that segue:

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        var cell : UICollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath)!
        println("entroooooooo")
        if result_category[indexPath.row]["children"].string == nil {
    
            println("voy a to_videostables")
    
            performSegueWithIdentifier("to_videostable", sender: cell)
        }
    }
    
  2. Wire the segue "reload_collection" from the cell to the viewController. This will allow the Storyboard to perform this segue for you.

  3. Implement shouldPerformSegueWithIdentifier to tell the Storyboard when it should make this segue:

    override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
    
        if segue.identifier == "reload_collection" {
            let indexPath = collectionView.indexPathForCell(sender as! UICollectionViewCell)
            return result_category[indexPath.row]["children"].string != nil
        }
        return true
    }
    
  4. In prepareForSegue you will need to set up url_children since it is no longer being done by didSelectItemAtIndexPath:

    if segue.identifier == "reload_collection"{
        println("-------------")
        println("reload_collection")
        println("-------------------")
        var category = category_function()
    
        let vc : Subcategory2 = segue.destinationViewController as! Subcategory2
    
        let indexPath = collectionView.indexPathForCell(sender as! UICollectionViewCell)
        url_children = result_category[indexPath.row]["children"].string!
        vc.url = url_children
        println(category.load_subcategory(self.url_children + self.end_url))
    }
    

Original Answer

Your segue is getting auto-called because you have wired it from the cell. If you want to trigger it with performSegueWithIdentifier it needs to be wired from the viewController like the other segue. Just remove the segue from the cell and rewire it from the viewController and give it the same identifier it had when you wired it from the cell and it should work.