【问题标题】:Highlight UITableViewCell like iMessage when long pressed长按时像 iMessage 一样突出显示 UITableViewCell
【发布时间】:2019-02-11 10:03:47
【问题描述】:

我使用UITableView 创建了简单的聊天。我想添加长按后突出显示消息的功能。事实上,我想创建和 iMessage 一样的功能:

长按后,我们取消突出显示背景(更暗),突出显示消息,滚动到此消息并显示actionSheet

目前我只添加了longPressactionSheet

viewDidLoad 上的长按识别器:

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(onCellLongPressed(gesture:)))
messagesTableView.addGestureRecognizer(longPressRecognizer)

onCellLongPressed函数:

@objc func onCellLongPressed(gesture: UILongPressGestureRecognizer) {

    if gesture.state == UIGestureRecognizerState.began {
        let touchPoint = gesture.location(in: self.messagesTableView)
        if let indexPath = messagesTableView.indexPathForRow(at: touchPoint) {
            self.messagesTableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableViewScrollPosition.none)
            shareWithFriend()
        }
    }
}

@objc func shareWithFriend() {
    alert(style: .actionSheet, actions: [
        UIAlertAction(title: "Share with friend", style: .default, handler: { [weak self] (_) in
            print("SHARE HERE")
        }),
        UIAlertAction(title: "Cancel", style: .destructive),
        ])
}

func alert(_ title: String? = nil, message: String? = nil, style: UIAlertController.Style, actions: [UIAlertAction]) {
    let alertController = UIAlertController(title: title, message: message, preferredStyle: style)
    actions.forEach(alertController.addAction)
    present(alertController, animated: true)
}

【问题讨论】:

  • 关于滚动,我建议使用以下代码: tableView?.scrollToRow(at: [0,0], at: UITableViewScrollPosition.top, animated: true) 只需将 [0,0] 替换为索引路径
  • @DJ-Glock 谢谢!突出显示选定的单元格呢?
  • 让我检查一下我的代码。我已经实现了类似的东西。
  • 我已经发布了我的答案。请注意,我没有对其进行测试,但希望对您有所帮助。
  • 我做了一些更新。感谢您的反馈。

标签: ios swift uitableview


【解决方案1】:

如您所见,背景颜色在导航栏上方,所以我猜当用户选择单元格时,集合视图上方巧妙地呈现了一个辅助视图控制器。

我认为这是两个不同的视图层次结构,它们看起来像一个:

  • 一个视图控制器包含气球列表
  • 一个视图控制器包含所选气球的副本以及与之关联的一些操作

这是路线图:

  1. 检测集合视图单元格中的长按
  2. 复制选定的气球并将其显示在辅助视图控制器 (ActionVC) 中
  3. 调整所选气球在 ActionVC 内的位置。如果选定的气球在未来的行动按钮下,它应该被移动。如果所选气球不会打扰任何人,则应原样显示。
  4. 调整集合视图的内容偏移以反映 3。修改应与 3 一起进行,以使单元格看起来像实际移动了。
  5. 检测 ActionVC 上的任何触摸
  6. 关闭 ActionVC

这是example project

  • 为了复制气球,我实际上创建了一个与集合视图单元格中使用的类相同的视图。但您可以使用快照。
  • 为了调整 ActionVC 中选定的气球位置,我使用了带优先级的约束。一个声称“不要在操作按钮下”,另一个声称“正好在牢房所在的位置”。我使用简单的坐标转换来计算 ActionVC 中预期的选定气球位置。
  • 为了在 4 旁边执行 3,我使用了 ActionVC 的 transitionCoordinator,但您可以使用简单的动画块并在没有动画的情况下呈现 ActionVC。

【讨论】:

  • 感谢您的出色解决方案!如何调整顶部的气球位置?
  • 不客气@DenAndreychuk。与底部情况一样,添加顶部约束并在气球移动时调整偏移量。
  • 太棒了。你认为他们对按钮使用自定义类吗?现在我在考虑行动表。这是个好主意吗?
  • 使用警报表不起作用,因为您无法确定按钮的大小。重新创建它:一个 UIButton + 一个 UIVisualEffectView。
【解决方案2】:

如果这个答案不能完全满足您的要求,我很抱歉,但希望它对您有所帮助。

您的初始代码是正确的,但您没有设置滚动类型。所以我建议你使用这种方法selectRow(at:animated:scrollPosition:)只需设置滚动位置:

self.messagesTableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableViewScrollPosition.top)

这也将选择这一行并因此调用以下方法tableView(_:didSelectRowAt:)。所以你需要在这里实现高亮逻辑:

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// your logic of changing color
    }

然后您应该执行类似的操作,但是要使用deselectRow(at:animated:)取消选择行,我相信这应该在用户完成操作时完成。您还需要实现类似的功能tableView(_:didDeselectRowAt:) 以返回颜色:

override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
// change color back
}

更新: 您还可以使用setHighlighted(_:animated:) 方法突出显示单元格。通过这种方式,您可以避免使用 selectRowAt/didSelectRowAt/didDeselectRowAt 和滚动 tableView 使用

tableView?.scrollToRow(at: indexPath, at: UITableViewScrollPosition.top, animated: true).

【讨论】:

    猜你喜欢
    • 2011-10-29
    • 2017-07-06
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多