长按时像 iMessage 一样突出显示 UITableViewCell
Posted
技术标签:
【中文标题】长按时像 iMessage 一样突出显示 UITableViewCell【英文标题】:Highlight UITableViewCell like iMessage when long pressed 【发布时间】:2019-02-11 10:03:47 【问题描述】:我使用UITableView
创建了简单的聊天。我想添加长按后突出显示消息的功能。事实上,我想创建和 iMessage 一样的功能:
长按后,我们取消突出显示背景(更暗),突出显示消息,滚动到此消息并显示actionSheet
目前我只添加了longPress
和actionSheet
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 谢谢!突出显示选定的单元格呢? 让我检查一下我的代码。我已经实现了类似的东西。 我已经发布了我的答案。请注意,我没有对其进行测试,但希望对您有所帮助。 我做了一些更新。感谢您的反馈。 【参考方案1】:如您所见,背景颜色在导航栏上方,所以我猜当用户选择单元格时,集合视图上方巧妙地呈现了一个辅助视图控制器。
我认为这是两个不同的视图层次结构,它们看起来像一个:
一个视图控制器包含气球列表 一个视图控制器包含所选气球的副本以及与之关联的一些操作这是路线图:
-
检测集合视图单元格中的长按
复制选定的气球并将其显示在辅助视图控制器 (ActionVC) 中
调整所选气球在 ActionVC 内的位置。如果选定的气球在未来的行动按钮下,它应该被移动。如果所选气球不会打扰任何人,则应原样显示。
调整集合视图的内容偏移以反映 3。修改应与 3 一起进行,以使单元格看起来像实际移动了。
检测 ActionVC 上的任何触摸
关闭 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).
【讨论】:
以上是关于长按时像 iMessage 一样突出显示 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章
对于 iPhone - 但不是 iOS 模拟器 - UIToolbar UIBarButtonItem 将仅在长按时突出显示,而不是在点击时突出显示
如何使用选择器在长按时“永久”突出显示 ListView 行,但在正常按下时短暂显示
如何像在 iMessage 群聊中一样在导航栏中放置集合视图