Pad*_*dma 1 text-editor cursor spacing textselection ios
我有一个UITextView应用了自定义行间距的自定义。当我尝试选择文本时,这selectionRect是错误的。检查此图像,其中突出显示正确,但 selectionRange 开始和结束处的手柄大小错误。该特定行应用了 50px 的 beforeSpacing 和 10px 的 afterSpacing。
相反,我希望它表现得像这样
我修改了光标大小,caretRectForPosition:并通过更改其矩形来修改光标的位置和大小,但不幸的是,这不会影响选择过程中的句柄。
如何根据应用的字体大小和行距修改 selectionRect 或选择手柄的大小?
小智 5
TL;DR:
You can use -(NSArray *)selectionRectsForRange, which behaves weird and not documented very well. The last two rectangles returned by UITextView when calling -(NSArray *)selectionRectsForRange have zero width, and they determine the height of the begin and end cursors. Create a subclass, override the method, call super and modify the height of the last two rects. To be able to modify them, you need to create a subclass of UITextSelectionRect because the original version is not writable (see the end of this answer).
Long version:
The way this method is implemented in UITextView is weird. Here is what I figured by trial and error:
If you subclass UITextView, and override the method like this:
- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
NSArray* result = [super selectionRectsForRange:range];
NSLog(@"%@", result);
return result;
}
Run Code Online (Sandbox Code Playgroud)
you will see the method returns a set of rectangles that span the selection, but also two rectangles with width zero, that coincide with the location of the cursor.
Interestingly enough, changing the order of the array does not have any impact on the selection or the cursor positions, so there is no need to make these rectangles the last two, it's rather a detail of apples implementation. Removing them all together has a more interesting effect: the cursors don't disappear, and neither do any of the selection rectangles. Rather, the cursors take the height of the adjacent rectangle. When selecting a whole paragraph of text, this leads to the cursors spanning the height of the whole paragraph. My conclusion is, that the cursors orient themselves towards the height and position of the upper-leftets/lower-rightest rects in the selection, and Apples implementation of -(NSArray *)selectionRectsForRange tricks this system by inserting zero-width rectangles. This is by no means certain, and there could be some more intricacies to the system, concerning text direction and other quirks. I tested my hypothesis on iOS 8 and 10 on device and in the simulator.
Bonus this is my mutable UITextSelectionRect subclass:
@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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
305 次 |
| 最近记录: |