TL; DR: 您可以使用-(NSArray *)selectionRectsForRange
,这种行为很古怪,但没有很好地记录。调用-(NSArray *)selectionRectsForRange
时由UITextView
返回的最后两个矩形的宽度为零,它们确定开始和结束游标的高度。创建一个子类,重写该方法,调用super并修改最后两个rects的高度。为了能够修改它们,您需要创建UITextSelectionRect
的子类,因为原始版本不可写(请参阅此答案的结尾)。
长版本: 该方法在UITextView
中实现的方式很奇怪。以下是我想通通过试验和错误:
如果你继承的UITextView,并覆盖这样的方法:
- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
NSArray* result = [super selectionRectsForRange:range];
NSLog(@"%@", result);
return result;
}
,你会看到该方法返回一组跨越的选择长方形的,但也两个宽度为零的矩形与光标的位置重合。有趣的是,改变数组的顺序并不会对选择或光标位置产生任何影响,所以不需要将这些长方形变成最后两个,这是苹果实现的细节。将它们一起移除会产生更有趣的效果:游标不会消失,也不会执行任何选择矩形。相反,光标取相邻矩形的高度。当选择一段文本时,这会导致跨越整个段落高度的光标。我的结论是,游标将自己定位在选择中的上层/最低层次的区域的高度和位置,苹果实施-(NSArray *)selectionRectsForRange
通过插入零宽度的矩形来欺骗这个系统。这绝不是确定的,系统中可能存在一些更复杂的问题,涉及文本方向和其他怪癖。我在设备和模拟器上的iOS 8和10上测试了我的假设。
奖金这是我的可变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
了大量的研究,我发现,我们可以覆盖 '后 - (NSArray的*)selectionRectsForRange:(UITextRange *)range'和通过继承'UITextSelectionView'我们可以设置范围 – Padma