NSTableView设为Gap拖拽反馈样式时向上拖动行重叠异常求助
我拥有多个NSTableView实例,其draggingDestinationFeedbackStyle属性被设置为NSTableViewDraggingDestinationFeedbackStyleGap。代理方法tableView:validateDrop:proposedRow:proposedDropOperation:返回NSDragOperationMove。
当我向上拖动某一行时,位于被拖动行上方且在目标位置下方的所有行都会下移以形成“间隙”,但被拖动行正上方的那一行始终不会下移,导致本该下移的下一行与它发生重叠。
(向下拖动行的功能表现正常。)
该问题在我测试过的所有macOS版本(11至15)以及所有测试过的表格视图中均会出现,甚至在仅包含一个表格窗口的测试项目中也存在。
请问我哪里操作出错了?
检查
proposedDropOperation参数的赋值
在tableView:validateDrop:proposedRow:proposedDropOperation:里,别只返回NSDragOperationMove,还要确认你有没有根据拖动方向正确设置*proposedDropOperation。向上拖动时,这个参数应该被设为.above,如果没正确赋值,表格的间隙反馈逻辑会出错,导致上方行不移动。核对数据源的行更新逻辑
虽然是UI显示问题,但数据源的行位置处理不对也会影响视图刷新。在tableView:acceptDrop:row:dropOperation:里,移动行后要确保数据源数组的索引调整正确,并且调用tableView.reloadData()或者精准刷新相关行的方法,避免视图布局没有同步更新。排查自定义行高/单元格的布局问题
如果用了自定义行高或者自定义NSTableCellView,检查有没有布局约束冲突,或者行高计算的缓存问题。向上拖动时正上方行没下移,可能是这个单元格的布局没有触发重绘。可以在拖动验证或接受方法里,手动调用tableView.reloadRows(at: [IndexPath(row: targetRow, section: 0)], with: .none)强制刷新该行。确认拖动代理方法的完整性
确保你实现了所有必需的拖动代理方法:tableView:writeRowsWithIndexes:toPasteboard::负责把拖动的数据写入剪贴板tableView:acceptDrop:row:dropOperation::处理接受拖动后的行移动逻辑
缺了任意一个都可能导致拖动过程中的UI反馈异常。
调整
draggingDestinationFeedbackStyle的设置时机
别在viewDidLoad里设置这个属性,试试把设置代码移到viewWillAppear(_:)或者viewDidLayoutSubviews()里,确保表格视图完成初始化和布局后再配置拖动反馈样式,避免早初始化导致的逻辑异常。
内容的提问来源于stack exchange,提问作者jeanlain

