UITextView中光标的像素位置

Rap*_*aad 24 iphone objective-c uitextview

有没有办法在UITextView中获取光标(闪烁条)的位置(CGPoint)(相对于其内容更可取).我不是说NSRange的位置.我需要一些东西:

- (CGPoint)cursorPosition;
Run Code Online (Sandbox Code Playgroud)

它应该是非私有的API方式.

Cra*_*raz 50

需要iOS 5

CGPoint cursorPosition = [textview caretRectForPosition:textview.selectedTextRange.start].origin;
Run Code Online (Sandbox Code Playgroud)

请记住在调用此方法之前检查selectedTextRange不是nil.您还应该使用selectedTextRange.empty它来检查它是光标位置而不是文本范围的开头.所以:

if (textview.selectedTextRange.empty) {
    // get cursor position and do stuff ...
}
Run Code Online (Sandbox Code Playgroud)

  • 这只是iOS 5.虽然-caretRectForPosition可用于3.2及更高版本,但UITextView在iOS 5之前不符合UITextInput (3认同)

Ton*_*ony 10

这很痛苦,但你可以使用UIStringDrawing附加功能NSString来做到这一点.这是我使用的一般算法:

CGPoint origin = textView.frame.origin;
NSString* head = [textView.text substringToIndex:textView.selectedRange.location];
CGSize initialSize = [head sizeWithFont:textView.font constrainedToSize:textView.contentSize];
NSUInteger startOfLine = [head length];
while (startOfLine > 0) {
    /*
     * 1. Adjust startOfLine to the beginning of the first word before startOfLine
     * 2. Check if drawing the substring of head up to startOfLine causes a reduction in height compared to initialSize.
     * 3. If so, then you've identified the start of the line containing the cursor, otherwise keep going.
     */
}
NSString* tail = [head substringFromIndex:startOfLine];
CGSize lineSize = [tail sizeWithFont:textView.font forWidth:textView.contentSize.width lineBreakMode:UILineBreakModeWordWrap];
CGPoint cursor = origin;
cursor.x += lineSize.width;
cursor.y += initialSize.height - lineSize.height;
return cursor;
}
Run Code Online (Sandbox Code Playgroud)

我曾经[NSCharacterSet whitespaceAndNewlineCharacterSet]找到过单词边界.

这也可以使用CTFrameSetterin 进行(可能更有效)CoreText,但在iPhone OS 3.1.3中不可用,所以如果你的目标是iPhone,你需要坚持UIStringDrawing.


Mil*_*sáľ 6

SWIFT 4版本:

if let cursorPosition = textView.selectedTextRange?.start {
    // cursorPosition is a UITextPosition object describing position in the text (text-wise description)

    let caretPositionRectangle: CGRect = textView.caretRect(for: cursorPosition)
    // now use either the whole rectangle, or its origin (caretPositionRectangle.origin)
}
Run Code Online (Sandbox Code Playgroud)

textView.selectedTextRange?.start返回光标的文本位置,然后我们只需使用它textView.caretRect(for:)来获取其像素位置textView.