NSTableView, что делает его удобным для пользователя
У меня есть NSTableView View-Based, в котором есть редактируемые строки, но я разрешаю редактирование, если пользователь нажимает на текст, а не на остальную часть ячейки. (см. изображение)
Кто-нибудь знает, как я могу сделать редактируемой всю ячейку, а не только зону ячейки, которая отображает текст?
1 ответ
Я верю, что понимаю, что происходит.
Во-первых, можете ли вы подтвердить, что когда текстовое поле действительно редактируется, кольцо фокусировки охватывает всю ячейку таблицы? Это не просто тесно связано с текущим текущим текстом, верно?
Если он охватывает всю ячейку таблицы, то это подтверждает, что ограничения растягивают ее, чтобы заполнить ячейку таблицы, а не текстовое поле, охватывающее ее содержимое. Другими словами, я пытаюсь подтвердить, что стрелка "Недоступно для редактирования" на вашем изображении действительно указывает на часть текстового поля. Я ожидаю, что это делает.
Таким образом, проблема заключается в том, как NSTableView
управляет щелчками и определяет, будут ли они отображать включенное представление в качестве первого респондента. Из Руководства по программированию табличного представления для Mac: Включение выбора строки и действий пользователя - Определение того, как подпредставления должны реагировать на события, мы узнаем, что табличное представление реализует специальную логику в переопределении validateProposedFirstResponder(_:forEvent:)
:
По умолчанию
NSTableView
реализацияvalidateProposedFirstResponder:forEvent:
использует следующую логику:
Вернуть
YES
для всех предложенных представлений первого респондента, если они не являются экземплярами или подклассамиNSControl
,Определите, является ли предлагаемый первый респондент
NSControl
экземпляр или подкласс.
Если элемент управления
NSButton
объект, возвратYES
,Если контроль не является
NSButton
Позвони контролюhitTestForEvent:inRect:ofView:
чтобы увидеть, отслеживается ли область попадания (то естьNSCellHitTrackableArea
) или является редактируемой текстовой областью (то естьNSCellHitEditableTextArea
) и вернуть соответствующее значение. Обратите внимание, что если текстовая область поражена,NSTableView
также задерживает действие первого ответчика.
Я реализовал пользовательский подкласс NSTextFieldCell
, Единственное, что он делает, это переопределение hitTestForEvent(_:inRect:ofView:)
позвонить в super, зарегистрировать результат и вернуть его. Затем я устанавливаю текстовое поле в представлении ячейки таблицы, чтобы использовать этот пользовательский класс для своей ячейки. Из этого я узнал, что нажатие на пустую область текстового поля приводит к .None
, Нажатие на фактический текст приводит к .ContentArea | .EditableTextArea
,
Первый результат не вызывает NSTableView
Реализация validateProposedFirstResponder(_:forEvent:)
позволить предложенному первому респонденту фактически быть первым респондентом. Последний результат делает.
Таким образом, вы можете реализовать свой собственный подкласс NSTextFieldCell
который переопределяет hitTestForEvent(_:inRect:ofView:)
, В своем переопределении вы бы позвонили на супер. Если результат .None
, вы бы изменили его на .ContentArea | .EditableTextArea
прежде чем вернуть его. Затем используйте этот пользовательский класс ячейки для текстовых полей в вашей таблице.
В качестве альтернативы вы можете попытаться решить эту проблему с помощью пользовательского подкласса NSTableView
что переопределяет validateProposedFirstResponder(_:forEvent:)
, Проблема в том, что нелегко переопределить логику этого метода, кроме тех, на которые он отвечает.