【问题标题】:Prepare for segue is autocalled为 segue 做准备是自动调用的
【发布时间】:2015-10-21 14:30:00
【问题描述】:

我有一个名为“subcateory2”的视图控制器,这个视图控制器有一个带有自定义单元格的 uicollectionview。我的应用程序需要两个 segues。一个从视图控制器调用“to_videostable”到另一个视图控制器,另一个从单元调用“reload_collection”到同一个视图控制器(因为子类别可以有n级子类别)。问题在于我的 prepareForSegue(我在此函数中检查了标识符,该标识符在“func collectionView(collectionView:UICollectionView,didSelectItemAtIndexPath indexPath:NSIndexPath)”中定义,并执行不同的操作)。当我选择一个单元格时,应该会发生这种情况:

  • 首先:转到我的“func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)”,检查条件并定义我的segue标识符。

  • 第二个:进入prepareforsegue,检查条件并执行动作。

但实际上这发生了:

  • 首先:在我的 ios 模拟器中选择一个单元格。
  • 第二个:我的代码进入 prepareforsegue 并始终进入名为“reload_collection”的 segue(在进入我的 func collectionView(...) 之前),并创建一个白色视图。这一刻就像创建了两个线程,其中一个进入白色窗口,另一个进入下一站。

  • 第三个:这个“第二个”转到 func collectionview(...) 并检查条件,定义标识符,调用 performSegueWithIdentifier 并转到 prepareforsegue 函数。在 prepareforsegue 检查标识符并执行不同的操作。

这是我的代码:

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

    }


}
}

由于这个问题,总是创建一个白色的窗口,然后创建一个带有真实信息的窗口。

println 的顺序是: - “重新加载集合” - “entroooooooo” - “voy a reloadcollection”或“voy a to_videostables”

在这张图片中显示了我的 main.stoyboard 和我可以在我的应用程序中看到的 windwos。

【问题讨论】:

  • 感谢朋友。我试图创建segue,但是当我将视图控制器拖动到顶部的黄色按钮时,我只看到“outless datasource and delegate”,没有像“show, show detail...”这样的选项我如何创建一个segue从视图控制器到自身?

标签: ios swift segue uistoryboard


【解决方案1】:

更新答案

您有一种情况,您想决定在选择单元格时采用哪种转场。您已经直接从单元格连接了您的一个转场,这意味着情节提要将为您创建该转场。您还打电话给performSegueWithIdentifier,这会创建另一个segue。当您想转至“to_videostables”时,您需要实现shouldPerformSegueWithIdentifier 以取消“reload_collection”转场。

在下面的原始答案中,我建议您从 viewController 连接两个 segue,但这不起作用,因为您的一个 segue 回到了同一个 viewController。

所以,另一种方法是:

  1. 修改didSelectItemAtIndexPath 以删除处理“reload_collection”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. 将 segue“reload_collection”从单元格连接到 viewController。这将允许 Storyboard 为您执行此转场。

  3. 实现shouldPerformSegueWithIdentifier 告诉情节提要何时应该进行此转场:

    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. prepareForSegue 中,您需要设置url_children,因为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))
    }
    

原答案

您的 segue 正在自动调用,因为您已将其从单元中连接。如果你想用performSegueWithIdentifier 触发它,它需要像其他segue 一样从viewController 连接。只需从单元格中移除 segue 并从 viewController 重新连接它,并为其提供与从单元格连接时相同的标识符,它应该可以工作。

【讨论】:

  • 感谢朋友。我试图创建segue,但是当我将视图控制器拖动到顶部的黄色按钮时,我只看到“outless datasource and delegate”,没有像“show, show detail...”这样的选项我如何创建一个segue从视图控制器到自身?
  • 嗯。我不知道你的 segue 是从一个按钮连接到同一个 viewController 的。我认为不可能在情节提要中创建一个可以使用performSegueWithIdentifier 调用的转场,该转场转到同一个viewController。您可能必须在情节提要中制作同一 viewController 的第二个副本,然后将其连接起来以转换到副本。还要使用相同的 segue 标识符连接副本以转换回原始版本。
  • 我用不同的方法更新了答案。看看吧。
  • 我刚刚更新了答案。它实际上与您最初所做的非常接近。 segues 以您拥有它们的方式连接起来。您只需要实现shouldPerformSegueWithIdentifier 即可在不需要时取消“reload_collection”segue。
猜你喜欢
  • 1970-01-01
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 2017-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多