gpt4 book ai didi

swift - 在 Swift 中使用 NSTableView 仅在一列上使用类型选择

转载 作者:行者123 更新时间:2023-11-28 07:49:27 24 4
gpt4 key购买 nike

我正在使用 XCode 9.3,Swift 开发适用于 MacOS 的应用程序。

我创建了一个目前有两列的表。我想使用只作用于一列的类型选择,这样当用户键入前几个字母时,它只在第一列中选​​择,而不是在第二列中选择。

Apple 文档中有一个 Objective-C 示例:https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/TableView/RowSelection/RowSelection.html#//apple_ref/doc/uid/10000026i-CH6-SW1但我似乎无法将其转化为 Swift。我在下面包含了表格代码。任何帮助都将不胜感激。

extension ViewController: NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return directoryItems?.count ?? 0
}

// Sorting.
func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {
guard let sortDescriptor = tableView.sortDescriptors.first else {
return
}

if let order = Directory.FileOrder(rawValue: sortDescriptor.key!) {
sortOrder = order
sortAscending = sortDescriptor.ascending
reloadFileList()
}
}

}

extension ViewController: NSTableViewDelegate {

fileprivate enum CellIdentifiers {
static let NameCell = "NameCellID"
static let TimeCell = "TimeCellID"
static let SizeCell = "SizeCellID"
}

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

var image: NSImage?
var text: String = ""
var cellIdentifier: String = ""

let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
dateFormatter.timeStyle = .long

guard let item = directoryItems?[row] else {
return nil
}

if tableColumn == tableView.tableColumns[0] {
image = item.icon
text = item.name
cellIdentifier = CellIdentifiers.NameCell

} else if tableColumn == tableView.tableColumns[1] {
let asset = AVAsset(url: item.url as URL)
let audioTime = asset.duration
text = audioTime.durationText
cellIdentifier = CellIdentifiers.TimeCell

} else if tableColumn == tableView.tableColumns[2] {
text = item.isFolder ? "--" : sizeFormatter.string(fromByteCount: item.size)
cellIdentifier = CellIdentifiers.SizeCell
}

if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: cellIdentifier), owner: nil) as? NSTableCellView {
cell.textField?.stringValue = text
cell.imageView?.image = image ?? nil
return cell
}

return nil
}

}

最佳答案

你的问题是双重的:

首先,您需要为每个表格列设置一个标识符。您可以通过在 Interface Builder 中选择该列,转到身份检查器并将其设置为某个字符串值来执行此操作:

enter image description here

完成后,创建一些静态属性来引用这些标识符(这不是严格必需的,因为您当然可以只使用 rawValue 来以 Objective-C 的方式进行纯字符串比较,但新的 Swift 4 标识符是类型安全的,因此是首选)。这样做:

extension ViewController: NSTableViewDelegate {
private struct TableColumns {
static let foo = NSUserInterfaceItemIdentifier("Foo")
static let bar = NSUserInterfaceItemIdentifier("Bar")
}

...

}

现在,您可以使用这些标识符来引用您的列,使用 tableColumn(withIdentifier:)(如果您只需要列号,则可以使用 column(withIdentifier:) ).我建议在你引用它们的任何地方都这样做,包括在你的 tableView(:viewFor:row:) 方法中,因为你现在使用 tableView.tableColumns[0] 等等取决于列的顺序,如果用户重新排序它们,可能会导致意外行为。使用标识符将确保您始终查看您认为正在查看的列。

无论如何,一旦设置了标识符,就可以解决第二个问题:您使用了错误的委托(delegate)方法。而不是 tableView(:shouldTypeSelectFor:searchString:),这是为了在事件级别捕获这些东西(即,用户只是按下了一个键。我是否应该调用类型选择系统?) ,使用 tableView(:typeSelectStringFor:row:)。此方法允许您为表中的每个行/列组合返回提供给类型选择机制的字符串。对于您希望类型选择忽略的那些,只需返回 nil;否则,返回您希望必须键入以选择该特定行的字符串。所以,像这样:

func tableView(_ tableView: NSTableView, typeSelectStringFor tableColumn: NSTableColumn?, row: Int) -> String? {
if tableColumn?.identifier == TableColumns.foo {
return directoryItems?[row].name
} else {
return nil
}
}

关于swift - 在 Swift 中使用 NSTableView 仅在一列上使用类型选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50092686/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com