【问题标题】:How can I get the selected text frame from a UITextView如何从 UITextView 获取选定的文本框
【发布时间】:2011-12-30 20:38:39
【问题描述】:

我正在尝试从UITextView 中选定文本的矩形中显示UIPopoverController,如何获取选定文本CGRect

谢谢!

【问题讨论】:

  • 如果这个问题是我认为的,那么标题中的 UIPopoverController 可能会产生误导?你想从文本选择中获取CGPoint,对UIPopoverController来说没什么特别的吧?
  • 修复了标题,因为您的建议是有效的@barley。

标签: iphone ios cocoa-touch ipad uipopovercontroller


【解决方案1】:

我认为 [UITextInput selectedTextRange][UITextInput caretRectForPosition:] 是您正在寻找的。

[UITextInput selectedTextRange]以字符形式返回所选范围

[UITextInput caretRectForPosition:] 返回此输入中字符范围的CGRect

UITextView 符合 UITextInput(自 iOS 5 起),因此您可以将这些方法用于您的 UITextView 实例。

它会是这样的。

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)};

编辑:由于示例代码变得有点难以获得,我添加了一张图片作为补充。

【讨论】:

  • 小问题,你称它为中心点,但你实际上是在计算右下角。
  • @Till 是的,最初我认为 [UITextInput caretRectForPosition:] 会将 UITextRange 作为输入,但(顾名思义)它实际上需要 UITextPosition。我修复了示例代码,我认为它现在更准确,虽然有点难以获得。感谢您的编辑!
  • 您的中心计算仍有一个小问题:D ...再次检查 X 坐标,括号设置错误以计算中心。
  • 嗯,我认为它或多或少是准确的。我对编码进行了采样,它按我的预期工作。我忽略了 selectionXXXRect 的宽度,因为它非常小,但除此之外,示例代码应该可以很好地计算近似中心。我添加了一张图片以便于理解。如果我仍然做错了什么,或者有什么可以改进的,请告诉我......
  • 哦,哎呀 - 看,你的补充让我很明显我错了。我认为您的回答确实做得很好,应该得到一点额外的……一旦可能,就会增加赏金。
【解决方案2】:

在某些情况下,大麦的答案实际上不会给出选择的中心。例如:

在这种情况下,您可以看到复制/粘贴菜单显示在所选内容的中心,该菜单横跨文本字段的整个宽度。但是计算两个插入符号的中心会使位置更靠右。

您可以使用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);
}

还值得澄清的是,如果您仍然支持 iOS 4 并使用这些答案中的任何一个,则需要在调用它们之前确保支持这些方法:if ([textView respondsToSelector:@selector(selectedTextRange)]) { …

【讨论】:

  • 您实际上不需要检查 CGRectIsNull,因为 CGRectUnion 已经处理了这个。根据 CGRectUnion 的文档:“如果其中一个矩形是空矩形,则返回另一个矩形的副本”
【解决方案3】:

Swift 5 版本:

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)
            }
        }
    }

【讨论】:

    猜你喜欢
    • 2013-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多