Swift中如何获取拖拽过程中NSTableColumn的X坐标
追踪NSTableView列拖动时的像素级位置变化方案
以下是几种可行的解决思路,针对你遇到的无法实时获取列拖动像素位置的问题:
自定义NSTableHeaderView子类拦截拖动事件
直接在表头的鼠标拖动事件里实时计算或获取列位置:
重写mouseDown(with:)记录初始拖动的列和鼠标位置,在mouseDragged(with:)中实时获取当前列的rect,或者通过鼠标偏移量计算像素级变化。示例代码:class TrackingHeaderView: NSTableHeaderView { private var draggedColumn: Int? override func mouseDown(with event: NSEvent) { super.mouseDown(with: event) let localPoint = convert(event.locationInWindow, from: nil) draggedColumn = tableView?.column(at: localPoint) } override func mouseDragged(with event: NSEvent) { super.mouseDragged(with: event) guard let columnIndex = draggedColumn, let tableView = tableView else { return } // 获取当前列的实时矩形 let currentRect = tableView.rect(ofColumn: columnIndex) // 在这里处理实时位置变化,比如通过闭包或通知传递出去 print("Column \(columnIndex) current position: \(currentRect.origin.x)") } override func mouseUp(with event: NSEvent) { super.mouseUp(with: event) draggedColumn = nil } }使用时只需将NSTableView的
headerView替换为这个自定义实例即可。监听
NSTableView.columnPositioningChangedNotification通知
这个通知会在列拖动过程中实时触发(而非仅在拖动结束时),刚好满足追踪像素级位置变化的需求。在通知回调里可以直接调用rect(ofColumn:)获取当前列的位置:// 注册通知 NotificationCenter.default.addObserver( self, selector: #selector(onColumnPositioningChanged(_:)), name: NSTableView.columnPositioningChangedNotification, object: yourTableView ) // 回调处理 @objc private func onColumnPositioningChanged(_ notification: Notification) { guard let tableView = notification.object as? NSTableView else { return } // 可以结合表头的拖动状态,只处理当前拖动的列 if let headerView = tableView.headerView as? TrackingHeaderView, let draggedColumn = headerView.draggedColumn { let rect = tableView.rect(ofColumn: draggedColumn) print("Dragged column position: \(rect.origin.x)") } }监听NSTableColumn的headerCell frame变化(备选方案)
尝试对NSTableColumn的headerCell.frame进行KVO监听,不过这个方法可能会有额外的触发场景,需要做过滤:// 为所有列添加监听 for column in yourTableView.tableColumns { column.addObserver(self, forKeyPath: "headerCell.frame", options: .new, context: nil) } // KVO回调 override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == "headerCell.frame", let column = object as? NSTableColumn else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } if let index = yourTableView.tableColumns.firstIndex(of: column) { print("Column \(index) frame updated: \(column.headerCell.frame)") } }注意记得在合适的时机移除KVO监听,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Cherub
相关产品推荐
相关产品推荐

