【问题标题】:"deselectRow" doesn't animate if using "popViewController"如果使用“popViewController”,“deselectRow”不会动画
【发布时间】:2019-11-12 05:08:16
【问题描述】:

Swift 5,Xcode 10

我的应用使用了两个ViewControllers:

  1. VC1,UITableView,点击一个单元格调用
  2. VC2,通过左上角默认的UINavigationBarItem“后退”按钮和底部添加的“保存”按钮显示有关单元格的更多信息

“保存”按钮保存所做的更改。要返回 VC2,您可以单击“返回”按钮或保存更改,这也会自动加载 VC2:

@IBAction func onClickSave(_ sender: Any) {
    //Save changes
    delegate?.passRowSavedBack(true) //Tell VC1 that changes were saved
    navigationController?.popViewController(animated: true)
}

如果我使用UINavigationBarItem“返回”按钮返回,则单元格还会将其选择颜色保持一秒钟,然后使用以下命令将其删除(如在 iOS“联系人”应用程序中):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    myTableView.deselectRow(at: mylastRowPickedIndex!, animated: true)
}

例如gif

问题是:如果我按“保存”按钮返回,也会调用此代码,但没有动画。

我的猜测是,popViewController 返回所需的时间比“返回”按钮调用的任何时间都长,因此播放了动画,但您没有及时“到达”看到它。

但是我该如何解决这个问题?是否有其他方法可以通过仍然播放动画的“保存”按钮(不删除默认的“返回”按钮!)返回 VC1?

编辑:我在做什么:

  1. 在 VC2 中:保存更改
  2. 告诉 VC1 他们是通过委托保存的(检查上面的第一个代码):
protocol PassingProtocol {
    func passRowSavedBack(_ valueSent: Bool)
}
  1. 使用popViewController返回VC1(检查上面的第一个代码)
  2. 在 VC1 中:deselectRowviewWillAppear 中(检查上面的第二个代码)
  3. rowsSaved[lastRowPicked] = true,所以它可以在这里添加一个accessoryType
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
    cell.accessoryType = (rowsSaved[indexPath.row]==true) ? .checkmark : .none
    return cell
}
  1. myTableView.reloadData() - 所以它会显示新的复选标记

【问题讨论】:

  • onClickSave 操作中,“//保存更改,然后”部分是否有异步任务?
  • 你试过用 viewDidAppear(_ animated: Bool) 代替 viewWillAppear 吗??
  • @AhmadF 没有异步任务正在进行,没有(还没有来)。它在主线程上完成保存后立即调用开关。
  • @m1sh0 刚刚做了。使用“返回”按钮,动画现在稍后开始(因为它在视图实际加载之前不会开始)但是如果我使用“保存”按钮返回,它仍然不会显示。我也让它输出mylastRowPickedIndex - 两者都是一样的。
  • 事实上,我在我的项目上对其进行了测试,没关系,有一点不同,我只是存储行而不是 IndexPath。我不相信这是我认为可能在您的 onClickSave 函数中的问题。保存数据时是否有一些通知或触发重新加载表的东西?

标签: ios swift uitableview uinavigationcontroller


【解决方案1】:

好的,我想我终于明白问题所在了。

您正在调用myTableView.reloadData(),这是取消选择动画的问题。

您可以在 viewDidAppear() 中移动myTableView.reloadData(),一切都会好起来的。

【讨论】:

  • 你说得对,将其移至viewDidAppear 可以,谢谢。不幸的是,当表格已经可见时,它会重新加载表格。 :/ 如果我使用默认的“后退”按钮,它甚至可以与viewWillAppear 一起使用,所以也必须缺少其他东西。是否有任何其他类型的“pop”可以用于导航控制器而不是popViewController?与默认设置完全一样的东西?
  • 它们是同样的东西,你的后退按钮和 poViewController 做同样的事情。我不知道你的代码,但你需要做的是在 func passRowSavedBack(_ valueSent: Bool) 中保存,如果你需要刷新,在 viewDidAppear 上检查和刷新是否需要。 (如果您认为我的答案是正确的,也可以将其标记为正确的答案:))
  • 如果“后退”按钮和“弹出”按钮执行完全相同的操作,我不明白为什么它适用于前者而不适用于后者。保存和passRowSavedBack是在VC1甚至开始替换VC2之前完成的,所以最后加载过程应该是一样的,不管我用哪个按钮返回(我在VC1中不区分),但看起来好像还是有区别的。
  • 不确定,如果我有完整的图片,也许我可以看到问题所在。一种可能的解释:在动画中,如果您想在 360 度上旋转某些东西,您需要以 180 度的 2 步进行,因为如果您直接在 360 度上旋转,则视图不会移动。不过,我不相信重新加载数据会出现这种情况,但如果没有所有信息,很难调试。
  • 我理解为什么你的例子会/不会工作,但 deselectRow 甚至不是我可以控制的动画 - 我告诉它动画,就是这样,但它的行为就像它设置不动画。如果您将测试中的所有内容都移动到viewWillAppear 并使用“pop”函数,它是否仍然为您设置动画? if I have the full picture maybe I can see what is the problem - 你到底需要什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-15
相关资源
最近更新 更多