我需要帮助将tableView推送到detailView。现在我有大部分代码,但是当我的应用程序加载时,它转到详细视图,每当我尝试返回tableView时,它立即返回到详细视图,并在调试区域中显示以下错误:
在意外状态下完成导航转换。导航栏子视图树可能已损坏。
我不明白为什么会发生这种情况,因为我的代码不在代码的viewDidLoad部分......这是我的tableView代码:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Label.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel.text = Label[indexPath.row]
performSegueWithIdentifier ("showDetail", sender: self)
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showDetail" {
}
}
return cell
}
请在下面给出答案,如果你可以帮助我让我的segue如何工作。谢谢!
P.S。我也很好奇如何自定义导航栏上的后退按钮,从“< Back”到“<”。
P.S.S。如何在按下后使tableViewCell自动释放,以便它不会保持突出显示?就这样它看起来像一个更好的应用程序整体。
P.S.S.S很抱歉,但最后一件事是如何根据用户点击的单元格自定义DeatilView?我已经使用文本设置了新类,但不知道如何制作if语句来自定义每个单元格的文本。
再次感谢!
答案 0 :(得分:3)
错误发生在cellForRowAtIndexPath
:
performSegueWithIdentifier ("showDetail", sender: self)
这会在显示单元格时触发segue,而不是在选中单元格时触发。解决这个问题的最简单方法是在IB中从单元格到目标视图控制器创建一个segue。
此外,此代码:
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showDetail" {
}
}
创建一个永远不会执行的cellForRowAtIndexPath
本地函数。正确的方法是在类范围中声明它作为超类实现的覆盖。
如果你已经在IB中定义了一个segue,那么你的代码应该是:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell.textLabel.text = Label[indexPath.row]
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
}
}
答案 1 :(得分:0)
你必须在tableView(_:didSelectRowAtIndexPath:)
中执行segue
tableView(_:cellForRowAtIndexPath:)
答案 2 :(得分:0)
我发现这个老问题的答案在目标C中How to change text on a back button
您必须在您正在制作的视图控制器中进行设置。
假设我们有一个简单的iPhone应用程序,它有一个UITableViewController,其中有一堆单元格列出了数字,我们称之为" NumberListTVC"。我们将这个NumberListTVC嵌入到NavigationController中。我们在其中一个单元格上设置了一个选择segue到另一个ViewController,我们将其称为" NumberDisplayerVC"。此NumberDisplayerVC有一个标签,我们将其设置为在NumberList上单击的标签的内容。因此,当您在NumberListTVC中选择一个单元格时,它将推送到" NumberDisplayer"在NavigationController中。
因此,对于这个应用程序,您可以使用代码来自定义NumberListTVC中的后退按钮,这样当您查看NumberDisplayerVC时,它将显示我们想要的后退按钮,而不是默认值(因为后退按钮将它带回NumberListTVC。
在Objective-C中,根据链接的答案,要更改的代码"<回到"到"<"将是:
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
基本上,我们使用我们想要的任何标题创建一个新的UIBarButtonItem。在这种情况下,我只给它标题为"",这只是一个空字符串。
Swift中的相同命令是:
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style:.Plain, target: nil, action: nil)
我把它放在NumberListTVC的viewDidLoad方法中,以确保它在加载NumberListTVC时运行。
这在Objective-C的答案Selected UItableViewCell staying blue when selected
中有所介绍你只需告诉UITableViewCell在didSelectRowAtIndexPath中取消选择它。
在Objective-C中,您将覆盖它并执行此操作: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //做你想做的其他事...... [tableView deselectRowAtIndexPath:indexPath animated:YES]; }
Swift代码类似:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
//Do whatever else you want to do here...
tableView.deselectRowAtIndexPath(indexPath, animated: true)
}
为了简单起见,我将使用我的第一个例子,它只是使用带有NumberListTVC和NumberDisplayerVC的navigationController,因此不在UISplitView上,但问题会影响任一场景。
基本上,您必须从单击的单元格中获取所需内容,然后将其设置为您希望在下一个ViewController中使用它的任何内容。所以,在你的prepareForSegue中,你会做这样的事情:
if segue.identifier == "amazingSegue"
{
if let cellText = (sender as? UITableViewCell)?.textLabel.text
{
if let someVC = segue.destinationViewController as? NumberDisplayerVC
{
someVC.textToDisplay = cellText
}
}
}
这基本上是安东尼奥在his answer中所说的。我加了一点。所以在我的例子中,NumberListTVC是一堆动态创建的UITableViewCells。我想从每个标签中取出标签,然后在NumberDisplayerVC中使用它。所以我们:
cellText
。我们使用可选的类型转换操作符来检查发送者是否是UITableViewCell。然后,我们使用可选链接查看此UITableViewCell,并从text
中提取textLabel
。destinationViewController
分配给常量someVC
。我们可以选择将它转换为NumberDisplayerVC,这应该是它。如果它确实是一个,它将正确绑定到someVC变量。 textToDisplay
属性设置为我们之前选择绑定的cellText
常量。我不确定这是不是最好的方式,我对if let
陈述的大厦感觉不是很好,但它最初的工作做得很好。