2016-07-05 9 views
1

У меня есть пользовательский UITextView с настраиваемым интервалом между строками. Когда я пытаюсь выбрать текст, selectionRect ошибочен. Check this image где подсветка правильная, но размер ручек при выбореРазмерьте начало и конец неправильно. Эта конкретная строка имеет значение до 50px и afterSpacing 10px.Выбор текста не происходит должным образом из-за пользовательского межстрочного интервала в UITextView

Вместо этого я хочу, чтобы вести себя как this

Я изменил размер курсора, используя caretRectForPosition: и изменять положение и размер курсора, изменяя его прямоугольник, но, к сожалению, это не влияет на ручки во время выбора.

Как изменить selectionRect или размер дескрипторов выбора на основе моего размера шрифта и интервала между строками?

+0

после долгих исследований я обнаружил, что мы можем переопределить '- (NSArray *) selectionRectsForRange: (UITextRange *) range' и наследованием 'UITextSelectionView' мы можем установить пользовательский selectionRect для диапазона – Padma

ответ

1

TL; DR: Вы можете использовать -(NSArray *)selectionRectsForRange, который ведет себя странно и не очень хорошо документированы. Последние два прямоугольника, возвращаемые UITextView при вызове -(NSArray *)selectionRectsForRange, имеют нулевую ширину и определяют высоту начального и конечного курсоров. Создайте подкласс, переопределите метод, вызовите супер и измените высоту двух последних прямоугольников. Чтобы иметь возможность изменять их, вам необходимо создать подкласс UITextSelectionRect, потому что исходная версия недоступна для записи (см. Конец этого ответа).

Длинная версия: Способ, которым этот метод реализован в UITextView, является странным. Вот что я понял, методом проб и ошибок:

Если подкласс UITextView и переопределить метод так:

- (NSArray *)selectionRectsForRange:(UITextRange *)range 
{ 
    NSArray* result = [super selectionRectsForRange:range]; 
    NSLog(@"%@", result); 
    return result; 
} 

вы увидите, метод возвращает набор прямоугольников, которые охватывают выбор, но и два прямоугольника с шириной ноль, которые совпадают с расположением курсора.

Интересно, что изменение порядка массива не влияет на выбор или позиции курсора, поэтому нет необходимости делать эти прямоугольники последними двумя, это скорее деталь реализации яблок. Устранение их всех вместе имеет более интересный эффект: курсоры не исчезают, и ни один из прямоугольников выбора. Скорее, курсоры берут высоту соседнего прямоугольника. При выборе всего абзаца текста это приводит к тому, что курсоры охватывают высоту всего абзаца. Я пришел к выводу, что курсоры ориентируются на высоту и положение верхних левых/нижних правых прямоугольников в выборе, а реализация яблок -(NSArray *)selectionRectsForRange обманывает эту систему, вставляя прямоугольники нулевой ширины. Это отнюдь не обязательно, и в системе может быть несколько сложностей, касающихся направления текста и других причуд. Я протестировал свою гипотезу на iOS 8 и 10 на устройстве и в симуляторе.

Bonus это мой изменчивый UITextSelectionRect подкласс:

@interface RichTextSelectionRect : UITextSelectionRect 

//Prefix everything with _ because the original names are marked as readonly in the superclass 
@property (nonatomic) CGRect _rect; 
@property (nonatomic) UITextWritingDirection _writingDirection; 
@property (nonatomic) BOOL _containsStart; // Returns YES if the rect contains the start of the selection. 
@property (nonatomic) BOOL _containsEnd; // Returns YES if the rect contains the end of the selection. 
@property (nonatomic) BOOL _isVertical; // Returns YES if the rect is for vertically oriented text. 

@end 

@implementation RichTextSelectionRect 

- (CGRect)rect{ 
    return __rect; 
} 

- (UITextWritingDirection)writingDirection{ 
    return __writingDirection; 
} 

- (BOOL)containsStart 
{ 
    return __containsStart; 
} 

- (BOOL)containsEnd 
{ 
    return __containsEnd; 
} 

- (BOOL)isVertical 
{ 
    return __isVertical; 
} 

@end 
+0

Спасибо :) Я понял это – Padma