简体   繁体   中英

How can I get the selected text frame from a UITextView

I'm trying to display an UIPopoverController from the rect of a selected text in an UITextView , How can I get the selected text CGRect ?

Thanks!

I think [UITextInput selectedTextRange] and [UITextInput caretRectForPosition:] is what you are looking for.

[UITextInput selectedTextRange] returns the selected range in character

[UITextInput caretRectForPosition:] returns the CGRect of the character range in this input.

UITextView conforms to UITextInput (since iOS 5), so you can use these methods for your UITextView instance.

It is going to be something like this.

UITextRange * selectionRange = [textView selectedTextRange];
CGRect selectionStartRect = [textView caretRectForPosition:selectionRange.start];
CGRect selectionEndRect = [textView caretRectForPosition:selectionRange.end];
CGPoint selectionCenterPoint = (CGPoint){(selectionStartRect.origin.x + selectionEndRect.origin.x)/2,(selectionStartRect.origin.y + selectionStartRect.size.height / 2)};

EDIT : Since the sample code became a little hard to get, I added an image for complementing.

说明局部变量代表什么的图像

There are some situations where barley's answer won't actually give the center of the selection. For example:

屏幕截图显示了使用插入符 rect 不准确的示例

In this case you can see the Copy/Paste menu is displaying in the center of the selection, which spans the entire width of the text field. But calculating the center of the two caret rects would give a position much further to the right.

You can get a more precise result using selectionRectsForRange:

UITextRange *selectionRange = [textView selectedTextRange];
NSArray *selectionRects = [self.textView selectionRectsForRange:selectionRange];
CGRect completeRect = CGRectNull;
for (UITextSelectionRect *selectionRect in selectionRects) {
    if (CGRectIsNull(completeRect)) {
        completeRect = selectionRect.rect;
    } else completeRect = CGRectUnion(completeRect,selectionRect.rect);
}

It's also worth clarifying that if you're still supporting iOS 4 and using either of these answers, you'll need to make sure these methods are supported before calling them: if ([textView respondsToSelector:@selector(selectedTextRange)]) { …

Swift 5 version:

if let selectionRect = textView.selectedTextRange {
        let selectionRects = textView.selectionRects(for: selectionRect)
        var completeRect = CGRect.null
        for rect in selectionRects {
            if (completeRect.isNull) {
                completeRect = rect.rect
            } else {
                completeRect = rect.rect.union(completeRect)
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM