如何在UITextView中将光标移动到当前行的开头?

4
我希望为我的UITextView添加一个插入标签按钮,以便用户能够在当前行的开头插入一个标签。无论光标在行中的哪个位置,标签都应该插入在行的开头,之后光标必须移到行的末尾。
是否可能实现?

当前行,还是当前段落?后者很容易,前者则不那么简单。 - jrturton
3个回答

3

我对 positionFromPosition:inDirection:offset:characterRangeByExtendingPosition:inDirection: 没有什么好运气。

但是这个对我来说很好用:

UITextRange *range = [textView selectedTextRange];
CGRect rect = [textView caretRectForPosition:range.start];
UITextPosition *start = [textView closestPositionToPoint:CGPointMake(0, rect.origin.y)];
[textView setSelectedTextRange:[textView textRangeFromPosition:start toPosition:start]];
更新:上述代码已在iOS7及更早版本上测试,但无法在iOS9上运行。实际上,在我的在iOS9设备上运行的文本编辑应用中存在一些错误。修复完我的应用程序后,我会更新答案。

这段代码不会跳到当前行的开头,而是将光标放在上一行的开头。 - user2356557
1
看一下第三行。这段代码将执行前一行。您还需要添加矩形的高度以获取下一行。 UITextPosition *start = [textView closestPositionToPoint:CGPointMake(0, rect.origin.y+rect.size.height)]; - horseshoe7
@horseshoe7,是的,这是可能的。上面的代码是为iOS7编写的(甚至可能是iOS6)。而UITextView在iOS8和iOS9中发生了变化。我稍后会更新答案。需要先检查新的行为。 - zxcat

2

UITextView实现了UITextInput协议,该协议具有一整套用于确定文本位置的方法。我不确定,但也许您可以调用:

  1. selectedTextRange获取插入符号的位置。
  2. positionFromPosition:inDirection:offset:使用UITextLayoutDirectionLeft查找到当前行开头的范围。(对此我不太确定;也许characterRangeByExtendingPosition:inDirection:更好?)
  3. 使用textRangeFromPosition:toPosition:获取行的起始范围。
  4. 使用replaceRange:withText:插入一个制表符。

如果这些方法无法解决问题,可能还有其他协议方法可供使用。

编辑:似乎UITextView只在iOS 5及以上版本中实现了UITextInput协议。如果您的目标是之前的版本,我不确定该怎么建议。


0

我将添加一些代码来移动光标到行首(homeTap),因为这样可以解决在@zxcat回答中提到的一些问题,即将光标移动到上一行的开头而不是当前行:

- (void)homeTap:(id)s {
    UITextRange* range = [_textView selectedTextRange];
    CGRect rect = [_textView caretRectForPosition:range.start];
    float halfLineHeight = _textView.font.lineHeight / 2.0;
    UITextPosition* start = [_textView closestPositionToPoint:CGPointMake(0, rect.origin.y + halfLineHeight)];
    [_textView setSelectedTextRange:[_textView textRangeFromPosition:start toPosition:start]];
}

具体来说,我将halfLineHeight添加到rect.origin.y中,以确保closestPositionToPoint的结果是针对当前行的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接