Метод делегата NSTextView -textView: shouldChangeTextInRange: replaceString: позволит вам сделать это. Вы можете «просто сказать НЕТ», чтобы измениться. ; -)
Обновление / Разработка (ноябрь 2015 г.)
Чтобы уточнить, основываясь на комментариях к этому ответу, идея состоит в том, чтобы использовать ваши собственные пользовательские атрибуты для атрибутивной строки , которую ваш текстовый вид редактирует. Помимо стандартных атрибутов , вы можете указать собственное имя атрибута (любое NSString
) и PLIST-совместимый объект в качестве значения для этого имени.
Например, если вы хотите назначить диапазон текста как «не редактируемый», вы можете добавить атрибут для этого диапазона с атрибутом, названным (например) @"TextIsEditableAttributeName"
с NSNumber
со значением BOOL
YES
или NO
: [NSNumber NO]
или @( NO )
(для использования числового бокса ObjC - тот же результат: экземпляр NSNumber). Позже, когда текстовое представление спрашивает своего делегата, должно ли оно изменить текст в диапазоне, вы можете проверить диапазон на наличие вашего атрибута @"TextIsEditableAttributeName"
.
Действительно, нужно только присвоить атрибут диапазонам, которые не являются редактируемыми, поэтому вам даже не нужно проверять значение. Вы можете просто поместить пустой экземпляр NSData
для заполнителя, чтобы у атрибута было значение. Ваше имя атрибута может быть @"EditingLocked"
или что-то еще. Это означает, что вам нужно только проверить наличие атрибута @"EditingLocked"
в любом месте предлагаемого диапазона и вернуть NO
, когда запрос текстового представления. Это отловит перекрывающиеся выделения (если вы разрешите выделение для копирования нередактируемого текста) редактируемых и нередактируемых диапазонов.
Этот же подход, конечно, может работать для -textView:willChangeSelectionFromCharacterRanges:toCharacterRanges:
, другого метода делегата, который позволяет вам возвращать «исправленный» массив значений диапазона для выбора. Если вы не хотите, чтобы нередактируемый текст выделялся, вы можете «вырезать» диапазоны, описанные любыми экземплярами атрибута @"EditingLocked"
, которые вы найдете в предлагаемых диапазонах.
Надеюсь, это поможет.