Я реализую функцию переименования/редактирования в файле NSOutlineView
. Базовая реализация выглядит так:
@objc func renameAction() {
let row = outlineView.clickedRow
let rowView = outlineView.view(
atColumn: 0,
row: row,
makeIfNecessary: false) as! NSTableCellView
rowView.textField!.isEditable = true
rowView.window?.makeFirstResponder(rowView.textField!)
}
mouseDown:
обрабатывается в NSOutlineView
, так что NSTextField
может выйти из режима редактирования при нажатии на редактируемую строку. Идея использования пользовательского делегата взята из этого вопрос
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
let localLocation = self.convert(
event.locationInWindow,
from: nil)
let clickedRow = self.row(at: localLocation)
#if DEBUG
print(#file, #line, clickedRow)
#endif
if clickedRow != -1 {
self.extendedDelegate?.didClickRow(clickedRow)
}
}
В делегате:
func didClickRow(_ row: Int) {
//... get the textField
textField.isEditable = false
textField.resignFirstResponder()
textField.window?.makeFirstResponder(
textField.window?.contentView
)
}
Странная вещь заключается в том, что я могу щелкнуть правой кнопкой мыши на NSTableCellView
(включая и значок, и NSTextField
), чтобы открыть контекстное меню до щелчка левой кнопкой мыши по ЛЮБОЙ строке. После щелчка левой кнопкой мыши я могу получить контекстное меню, только щелкнув правой кнопкой мыши в любом месте за пределами NSTableCellView
(любой строки, независимо от того, нажата она или нет), но внутри строки (пустые области, окружающие NSTableCellView
).
Скриншоты
Прежде чем щелкнуть левой кнопкой мыши, щелкните правой кнопкой мыши NSTableCellView
, чтобы открыть меню:
После щелчка левой кнопкой мыши по любой строке правый щелчок не работает «на» всех NSTableCellView
, но все еще работает в пустой области строки.
// Нет меню при нажатии на
NSTableCellView
. Но меню появится при нажатии на пустые области строки.
Обновлять:
Я обнаружил, что если переопределяющий mouseDown:
закомментирован (как и ожидалось), проблем не возникает. Но это лишит возможности завершить редактирование, щелкнув текущую строку.
resignFirstResponder
, это сделаетmakeFirstResponder
. ВыполнитеisEditable = false
после перемещения первого отвечающего. Не делайтеcontentView
первым ответчиком, если толькоcontentView
не может быть первым ответчиком. Вместо этого сделайте вид схемы или окно первым ответчиком. - person Willeke   schedule 20.10.2017isEditable = false
, это тоже работает. Есть ли что-то особенное в заказе? - person LShi   schedule 20.10.2017isEditable
иisSelectable
равныfalse
. - person Willeke   schedule 20.10.2017