如何在UITableView拖拽重排单元格时添加途经触觉反馈?
实现UITableView拖拽途经单元格的触觉反馈
核心思路
通过监听拖拽过程中目标索引路径的变化,当拖拽单元格途经新单元格时(即目标索引路径更新为新值)触发触觉反馈。需要维护一个变量记录上一次触发反馈的索引路径,避免重复触发。
具体实现步骤
初始化触觉反馈生成器
在视图控制器中声明并初始化UIImpactFeedbackGenerator,用于触发触觉反馈:private let feedbackGenerator = UIImpactFeedbackGenerator(style: .medium) private var lastTriggeredIndexPath: IndexPath?在视图加载完成后调用
prepare()方法预加载反馈器,提升响应速度:override func viewDidLoad() { super.viewDidLoad() feedbackGenerator.prepare() // 配置tableView拖拽代理 tableView.dragDelegate = self tableView.dropDelegate = self tableView.dragInteractionEnabled = true }监听拖拽过程中的索引变化
实现UITableViewDropDelegate的tableView(_:dropSessionDidUpdate:withDestinationIndexPath:)方法,在拖拽更新时检查目标索引路径是否发生变化:func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal { guard let currentIndexPath = destinationIndexPath, currentIndexPath != lastTriggeredIndexPath else { return UITableViewDropProposal(operation: .move) } // 触发触觉反馈 feedbackGenerator.impactOccurred() // 更新记录的索引,避免重复触发 lastTriggeredIndexPath = currentIndexPath // 预加载下一次反馈 feedbackGenerator.prepare() return UITableViewDropProposal(operation: .move) }重置记录的索引路径
在拖拽结束时(无论是否完成放下),重置lastTriggeredIndexPath,避免影响下一次拖拽:func tableView(_ tableView: UITableView, dropSessionDidEnd session: UIDropSession) { lastTriggeredIndexPath = nil } func tableView(_ tableView: UITableView, dragSessionDidEnd session: UIDragSession) { lastTriggeredIndexPath = nil }
注意事项
- 若需要更精准的“途经”检测(比如拖拽单元格进入其他单元格范围时触发,而非仅目标索引变化),可通过
UIDropSession的location(in:)方法获取拖拽位置,再转换为对应的单元格索引进行对比。 - 根据交互场景选择合适的反馈风格(
.light/.medium/.heavy),匹配操作的轻重感。 - 每次触发反馈后调用
prepare(),确保反馈器处于就绪状态,提升触觉反馈的响应速度。
内容的提问来源于stack exchange,提问作者Dexter
相关产品推荐
相关产品推荐

