NSTableView, что делает его удобным для пользователя

У меня есть NSTableView View-Based, в котором есть редактируемые строки, но я разрешаю редактирование, если пользователь нажимает на текст, а не на остальную часть ячейки. (см. изображение)

Кто-нибудь знает, как я могу сделать редактируемой всю ячейку, а не только зону ячейки, которая отображает текст?

TableView

Клетка

1 ответ

Решение

Я верю, что понимаю, что происходит.

Во-первых, можете ли вы подтвердить, что когда текстовое поле действительно редактируется, кольцо фокусировки охватывает всю ячейку таблицы? Это не просто тесно связано с текущим текущим текстом, верно?

Если он охватывает всю ячейку таблицы, то это подтверждает, что ограничения растягивают ее, чтобы заполнить ячейку таблицы, а не текстовое поле, охватывающее ее содержимое. Другими словами, я пытаюсь подтвердить, что стрелка "Недоступно для редактирования" на вашем изображении действительно указывает на часть текстового поля. Я ожидаю, что это делает.

Таким образом, проблема заключается в том, как NSTableView управляет щелчками и определяет, будут ли они отображать включенное представление в качестве первого респондента. Из Руководства по программированию табличного представления для Mac: Включение выбора строки и действий пользователя - Определение того, как подпредставления должны реагировать на события, мы узнаем, что табличное представление реализует специальную логику в переопределении validateProposedFirstResponder(_:forEvent:):

По умолчанию NSTableView реализация validateProposedFirstResponder:forEvent: использует следующую логику:

  1. Вернуть YES для всех предложенных представлений первого респондента, если они не являются экземплярами или подклассами NSControl,

  2. Определите, является ли предлагаемый первый респондент 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:), Проблема в том, что нелегко переопределить логику этого метода, кроме тех, на которые он отвечает.

Другие вопросы по тегам