TableView 在 Swift 中推送到详细视图
Posted
技术标签:
【中文标题】TableView 在 Swift 中推送到详细视图【英文标题】:TableView Pushing to Detail View in Swift 【发布时间】:2014-11-17 21:00:26 【问题描述】:我需要帮助将我的 tableView 推送到 detailView。现在我有大部分代码,但是当我的应用程序加载时,它会转到detailedView,每当我尝试返回tableView时,它会立即返回detailedView,并且在调试区域中显示以下错误:
在意外状态下完成导航转换。导航栏子视图树可能已损坏。
我不明白为什么会这样,因为我的代码不在代码的 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 按预期工作,请在下面留下答案。谢谢!
附:我也很好奇如何将导航栏上的后退按钮从“
附言如何使 tableViewCell 在按下后自动释放,使其不会保持突出显示?只是它看起来像一个整体上更好的应用程序。
P.S.S.S 抱歉,最后一件事是如何根据用户单击的单元格自定义 DeatilView?我已经用文本设置了新类,但不知道如何制作为每个单击的单元格自定义文本的 if 语句。
再次感谢!
【问题讨论】:
您一次只能问一个问题。 【参考方案1】:错误在你的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"
【讨论】:
我在 IB 中有一个名为 showDetail 的 segue,但仍然出现此错误。你建议我改变什么?我不明白你建议我改变什么,对不起。你能告诉我使用什么代码吗?如果有帮助,我也会收到此错误:嵌套推送动画可能导致导航栏损坏【参考方案2】:你必须在tableView(_:didSelectRowAtIndexPath:)
中执行转场而不是
tableView(_:cellForRowAtIndexPath:)
【讨论】:
现在可以使用了!非常感谢!很抱歉很痛苦,但是您知道如何解决我在 P.S 和 P.S.S 中所说的问题吗?以及如何根据用户点击的单元格自定义DetailedView?我知道如何在 ObjC 中做到这一点,但尝试在 Swift 中学习。 (我刚刚也将其添加到原始问题中)【参考方案3】:附注如何将导航栏上的后退按钮从“
我发现这个老问题在 Objective C 中有答案,How to change text on a back button
您必须在您要从中进行切换的视图控制器中进行设置。
假设我们有一个简单的 iPhone 应用程序,它有一个 UITableViewController 和一堆列出数字的单元格,我们称之为“NumberListTVC”。我们将此 NumberListTVC 嵌入到 NavigationController 中。我们将其中一个单元格上的选择序列设置为另一个 ViewController,我们将其称为“NumberDisplayerVC”。这个 NumberDisplayerVC 有一个标签,我们将把它设置为在 NumberList 上单击的标签的内容。因此,当您在 NumberListTVC 中选择一个单元格时,它将推送到 NavigationController 中的“NumberDisplayer”。
所以对于这个应用程序,您可以将自定义后退按钮的代码放在 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 加载时运行。
附言如何让 tableViewCell 在按下后自动释放,使其不会保持突出显示?
这在 Objective-C 中的答案 Selected UItableViewCell staying blue when selected 中有介绍
您只需告诉 UITableViewCell 在其 didSelectRowAtIndexPath 中取消选择它。
在 Objective-C 中,您可以覆盖它并执行以下操作: - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath //在这里做任何你想做的事情... [tableView deselectRowAtIndexPath:indexPath 动画:YES];
Swift 代码类似:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
//Do whatever else you want to do here...
tableView.deselectRowAtIndexPath(indexPath, animated: true)
P.S.S.S 如何根据用户单击的单元格自定义 DetailView?
为简单起见,我将使用我的第一个示例,它只是将我们的 navigationController 与 NumberListTVC 和 NumberDisplayerVC 一起使用,因此不在 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 中使用它。所以我们:
-
检查它是否是我们想要实际使用的segue,在这种情况下,NumberListTVC 和 NumberDisplayerVC 之间的 segue 被命名为“amazing segue”。
接下来,使用可选绑定将发送方单元格的文本分配给常量
cellText
。我们使用可选的类型转换运算符来检查发送者是否是 UITableViewCell。然后,我们使用可选链查看此 UITableViewCell 内部并从其textLabel
中提取text
。
再次使用可选绑定将我们的destinationViewController
分配给常量someVC
。我们可以选择将其类型转换为 NumberDisplayerVC,这就是它应该的样子。如果它确实是 1,它将正确绑定到 someVC 变量。
然后只需将textToDisplay
属性设置为我们之前可选绑定的cellText
常量。
我不确定这是否是最好的方法,我对 if let
语句的塔感觉不太好,但它最初可以完成工作。
【讨论】:
以上是关于TableView 在 Swift 中推送到详细视图的主要内容,如果未能解决你的问题,请参考以下文章