使用pathItems替代pathComponentCells获取NSPathControl点击项索引
NSPathControl 替换废弃API后的数据关联与索引获取方案
由于NSPathControl.setPathComponentCells(_:)和.clickedPathComponentCell()被废弃,改用pathItems和clickedPathItem时,会遇到每次触发action时路径项实例被重新创建的问题,导致无法直接通过实例引用关联数据或获取索引。以下是两种可行的解决思路:
方法一:利用representedObject存储自定义数据 + 标题匹配获取索引
NSPathControl重新生成的NSPathControlItem会保留原实例的representedObject属性值,因此可以用该属性存储自定义数据;同时通过标题匹配来定位索引。
class ViewController: NSViewController { @IBOutlet weak var pathControl: NSPathControl! override func viewDidLoad() { super.viewDidLoad() // 构造带自定义数据的路径项数据 let pathEntries = [ (title: "a", customData: "虚拟路径节点A"), (title: "b", customData: "虚拟路径节点B"), (title: "c", customData: "虚拟路径节点C") ] // 生成NSPathControlItem数组并设置 pathControl.pathItems = pathEntries.map { entry in let item = NSPathControlItem() item.title = entry.title item.representedObject = entry.customData return item } } @IBAction func selectPath(_ sender: NSPathControl) { guard let clickedItem = sender.clickedPathItem else { return } // 获取自定义数据 let data = clickedItem.representedObject as? String ?? "" print("选中节点:\(clickedItem.title),关联数据:\(data)") // 通过标题匹配获取索引 if let index = sender.pathItems.firstIndex(where: { $0.title == clickedItem.title }) { print("选中节点索引:\(index)") } } }
方法二:自定义NSPathControlItem子类,重写相等判断
如果存在标题重复的场景,可自定义路径项子类,通过唯一业务ID标识节点,并重写isEqual和hash方法,确保相同业务节点即使实例不同也能被正确匹配。
// 自定义路径项子类 class CustomPathItem: NSPathControlItem { let nodeID: String // 唯一业务ID init(title: String, nodeID: String) { self.nodeID = nodeID super.init() self.title = title } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 重写相等判断逻辑 override func isEqual(_ object: Any?) -> Bool { guard let other = object as? CustomPathItem else { return false } return self.nodeID == other.nodeID } override var hash: Int { return nodeID.hashValue } } class ViewController: NSViewController { @IBOutlet weak var pathControl: NSPathControl! override func viewDidLoad() { super.viewDidLoad() pathControl.pathItems = [ CustomPathItem(title: "a", nodeID: "node_001"), CustomPathItem(title: "b", nodeID: "node_002"), CustomPathItem(title: "c", nodeID: "node_003") ] } @IBAction func selectPath(_ sender: NSPathControl) { guard let clickedItem = sender.clickedPathItem as? CustomPathItem else { return } print("选中节点ID:\(clickedItem.nodeID),标题:\(clickedItem.title)") // 通过自定义相等逻辑获取索引 if let index = sender.pathItems.firstIndex(where: { $0.isEqual(clickedItem) }) { print("选中节点索引:\(index)") } } }
原理说明
NSPathControl在每次交互后会重新生成NSPathControlItem实例,但会保留原实例的核心属性(如title、representedObject);自定义子类重写相等判断后,可基于业务标识而非实例地址来识别节点,从而解决实例变化带来的数据关联和索引获取问题。
内容的提问来源于stack exchange,提问作者Nickkk
相关产品推荐
相关产品推荐

