将segue从UITableViewCell推送到Swift中的ViewController

时间:2015-02-04 14:32:36

标签: ios iphone uitableview swift uistoryboardsegue

我遇到了UITableViewCells的问题。我将我的UITableView连接到API以填充我的单元格。

然后我创建了一个函数,该函数抓取indexPath.row以识别应该发送到RestaurantViewController的数组中的哪个JSON对象。

  

Link to my Xcode Project for easier debugging and problem-solving

这是我的小片段如何设置"行点击"到全局变量。

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
     i = indexPath.row
}

这是我的prepareForSegue()函数,它应该将我的push-segue连接到RestaurantViewController

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "toRestaurant"{
    let navigationController = segue.destinationViewController as UINavigationController
    let vc = navigationController.topViewController as RestaurantViewController
    vc.data = currentResponse[i] as NSArray
 }
}

以下是我如何设置UITableViewCell中的segue

这是我的结果,我试图点击这些单元格中的每一个但我不会被推到另一个viewController ......我也没有收到错误。这有什么不对?

  

尝试了无法解决的解决方案

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if segue.identifier == "toRestaurant"{
            let vc = segue.destinationViewController as RestaurantViewController
            //let vc = navigationController.topViewController as RestaurantViewController
            vc.data = currentResponse[i] as NSArray
        }
    }

9 个答案:

答案 0 :(得分:20)

问题是您没有正确处理数据。 如果您查看currentResponse数组,您会看到它包含NSDictionaries,但在您的prepareForSegue中,您尝试将NSDictionary强制转换为NSArray,这将使应用程序崩溃。

data中的RestaurantViewController变量更改为NSDictionary并更改prepareForSegue以传递NSDictionary

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if let cell = sender as? UITableViewCell {
        let i = redditListTableView.indexPathForCell(cell)!.row
        if segue.identifier == "toRestaurant" {
            let vc = segue.destinationViewController as RestaurantViewController
            vc.data = currentResponse[i] as NSDictionary
        }
    }
}

答案 1 :(得分:4)

以下步骤可以解决您的问题。如果没有,请告诉我。

  1. 删除tableView(tableView, didSelectRowAtIndexPath:)实施。

  2. dataRestaurantViewController NSDictionary!类型prepareForSegue

  3. 确定override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { if let cell = sender as? UITableViewCell { let i = tableView.indexPathForCell(cell)!.row if segue.identifier == "toRestaurant" { let vc = segue.destinationViewController as RestaurantViewController vc.data = currentResponse[i] as NSDictionary } } } 中所选行:

    {{1}}

答案 2 :(得分:3)

Dropbox link to stack3 directory

  1. 我很难理解为什么您的软件与标准的2级tableview结构有很大不同。所以我编写了一个简短的例子,你可以从这个链接访问。我还在下面列出了源代码。

  2. 该程序模仿你拥有的东西(尽我所知)。表控制器1从tableview单元中分离到表控制器2。我对segue-ing没有任何问题。请注意,我没有也不需要增加故事书来启动segue。

  3. 我在导航控制器中嵌入了两个控制器。我的经验是,它可以节省很多设置导航的工作。

  4. 或者,我可以控制 - 从屏幕顶部的第一个TableViewController符号拖动到第二个控制器并设置segue。

  5. 我使用了一个全局变量(selectedRow),虽然它不是推荐的做法。但你可以轻松地使用prepareForSegue在RestaurantTableViewController中设置一个变量(我展示了一个例子)

    1. 最后,我建议检查Connections Inspector(对于第一个控制器中的表格视图单元格)以确认第二个控制器有一个segue。如果您正确控制拖动,则应该有确认提示以及Connections Inspector中的条目。
  6. 不幸的是,我无法正确地获取格式化代码

    import UIKit
    
    var selectedRow = -1
    
    class TableViewController: UITableViewController {
    
    var firstArray = ["Item1","Item2","Item3","Item4"]
    
    override func viewDidLoad() {
    
    super.viewDidLoad()
    
    }
    
    override func didReceiveMemoryWarning() {
    
    super.didReceiveMemoryWarning()
    
    }
    
    // MARK: - Table view data source
    
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    
    return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return firstArray.count
    
    }
    
    
    let nameOfCell = "RestaurantCell"
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
    
    cell.textLabel!.text = firstArray[indexPath.row]
    
    return cell
    
    }
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
    selectedRow = indexPath.row
    
    }
    
    // MARK: - Navigation
    
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
    let vc = segue.destinationViewController as RestaurantTableViewController
    
    // can write to variables in RestaurantTableViewController if required
    
    vc.someVariable = selectedRow
    
    }
    
    
    }
    
    
    import UIKit
    
    class RestaurantTableViewController: UITableViewController {
    
    var secondArray = ["Item 2.1", "Item 2.2", "Item 2.3", "Item 2.4"]
    
    var someVariable = -1
    
    override func viewDidLoad() {
    
    super.viewDidLoad()
    
    }
    
    override func didReceiveMemoryWarning() {
    
    super.didReceiveMemoryWarning()
    
    }
    
    // MARK: - Table view data source
    
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    
    return 1
    
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    
    return secondArray.count
    
    }
    
    let nameOfCell = "RestaurantCell"
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
    let cell = tableView.dequeueReusableCellWithIdentifier(nameOfCell, forIndexPath: indexPath) as UITableViewCell
    
    cell.textLabel!.text = secondArray[indexPath.row]
    
    if indexPath.row == selectedRow {
    
    cell.textLabel!.text = cell.textLabel!.text! + " SELECTED"
    
    }
    
    return cell
    
    }
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    
    selectedRow = indexPath.row
    
    }
    
    }
    

答案 3 :(得分:2)

我注意到,在故事板的屏幕截图中,segue将第一个原型单元连接到RestaurantViewController。这个原型单元看起来像是“基本”样式的单元格,在右侧有一个披露指示器附件。但请查看正在运行的应用的屏幕截图。该表格中填充的单元格似乎是“Subtitle”样式的单元格,右侧没有披露指示器附件。

无论你做什么,你的segue永远不会被触发的原因是segue只被配置为适用于特定的原型单元格,但是在填充表格时永远不会使用该原型单元格。无论你在tableView:cellForRowAtIndexPath:做什么,你都没有使用你想要的原型单元。

@Starscream有正确的想法使用正确的标识符对正确的单元格进行排队,并将其与Interface Builder中的原型单元格的标识符进行匹配。在这样做之后你甚至会遇到崩溃可能是因为上面评论中提到的上一个问题。故事板中的segue明显指向UITableViewController。只要prepareForSegue:sender:let vc = segue.destinationViewController as RestaurantViewController的子类,RestaurantViewController中的代码就应该是UITableViewController。如果您尝试将其强制转换为UINavigationController,则会崩溃。还要确保故事板中目标UITableViewController的类在Identity Inspector窗格中列为RestaurantController。如果您的程序编译认为故事板只包含通用UITableViewController,那么您将崩溃。

更多地回到原始问题,我不知道你是如何实施tableView:cellForRowAtIndexPath:的,这可能是至关重要的。也许这不是那么简单。也许您计划在运行时处理许多原型单元或生成自定义单元。在这种情况下,一种简单的方法是在用户点击单元格时以编程方式执行segue。不要使用特定的原型单元格,而是将segue作为源自“Restaurangernäramig”UITableViewController的连接转到RestaurantViewController。 (通过控制单击从界面生成器中连接,从第一个顶部的表视图控制器图标拖动到第二个主体的主体)。您必须在“属性检查器”窗格中为此segue指定一个标识符,以使其有用。我们说它是"toRestaurant"。然后在tableView:didSelectRowAtIndexPath:方法的最后,输入以下代码:self.performSegueWithIdentifier("toRestaurant", sender: self)。现在无论在表中选择了什么单元格,这个segue总是会为你开火。

答案 4 :(得分:1)

尝试在cellForRow方法中创建这样的单元格:

let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("MyTestCell", forIndexPath: indexPath)

答案 5 :(得分:1)

我在这里突发奇想,因为我现在正快速进入,但我在prepareForSegue()中这样做的方式是这样的:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "toRestaurant"{
        let navigationController = segue.destinationViewController as UINavigationController
        let vc = navigationController.topViewController as RestaurantViewController
        //notice I changed [i] to [index!.row]
        vc.data = currentResponse[index!.row] as NSArray
     }
    }

对我来说,看起来你正在调用i变量,它有点像你班级方法中的私有变量。您可以使用selectRow变量执行类似@Syed Tariq的操作并将其设置在class SomeController: UIViewController /*, maybe some more here? */ {上方,然后在

中签署变量
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    selectedRow = indexPath.row

}
像上面这样的方法,但两种方式都应该运作良好。

答案 6 :(得分:0)

我遇到了同样的问题,我发现解决方案是:

performSegueWithIdentifier(" toViewDetails",sender:self)

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var cellnumber = procMgr.processos[indexPath.row].numero
    println("You selected cell #\(indexPath.row)")
    println(cellnumber)
    performSegueWithIdentifier("toViewDetails", sender: self)
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "toViewDetails" {
         let DestViewController : ViewDetails = segue.destinationViewController as! ViewDetails
    }
}

答案 7 :(得分:0)

您可能需要获取UItableview的选定单元格索引。下面的代码使用选定的单元格索引(UItableview.indexPathForSelectedRow)来获取数组的正确元素。

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "seguaVisitCardDetial" {
        let viewController = segue.destinationViewController as! VCVisitCardDetial
        viewController.dataThisCard =   self.listOfVisitCards[(tblCardList.indexPathForSelectedRow?.row)!]
    }
}

答案 8 :(得分:0)

我也有这个问题; UITableViewCell的segue没有调用。 经过一番搜索,我发现这是因为我在“选择”字段中选择了“没有选择”。