在 iPad 上的 UIWebView 中定位弹出框
Posted
技术标签:
【中文标题】在 iPad 上的 UIWebView 中定位弹出框【英文标题】:Positioning a popover in a UIWebView on the iPad 【发布时间】:2013-04-11 11:59:32 【问题描述】:我已向 UIMenuController 添加了一个自定义操作。单击该操作时,我希望弹出窗口类似于“定义”操作的工作方式(请参见下面的屏幕截图)。
但是,我无法让弹出框在 UIWebView 中正确定位。这是我的代码的摘录,当用户选择自定义操作时会生成弹出框:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
popover = [[UIPopoverController alloc]
initWithContentViewController:contentController];
[popover setDelegate:self];
popover.popoverContentSize = CGSizeMake(240., 60.);
UIMenuController *menuController = [UIMenuController sharedMenuController];
[popover presentPopoverFromRect:menuController.menuFrame
inView:webView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
这是设备处于纵向模式时的结果:
如您所见,这还不错,但我无法让它与所选文本完全对齐;在横向模式下,弹出框的位置甚至不接近。
有人知道我如何将弹出框正确定位到所选文本,并在用户旋转设备时使其正确定位吗? SDK 版本为 ios 6.1。
【问题讨论】:
我觉得不错。您能否提供显示所需输出的图像? 如果你看一下我原始帖子中的第一张图片,弹出框的箭头与文本选择的左侧齐平;同样,如果它在下方,箭头的点将与所选文本的底部对齐。在我的例子中,当(理想情况下)它应该与选择的顶部对齐时,箭头的点位于所选文本的中间。 【参考方案1】:你的代码在这里出错了:
[popover presentPopoverFromRect:menuController.menuFrame
inView:webView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
您正在使用 menuController 的视图作为定位弹出窗口的矩形,而您真正想要的是文本选择的矩形。
你可以像这样得到文本选择矩形:
- (CGRect) textSelectionRect:(UITextView*)textView
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);
return completeRect;
(见答案here)
【讨论】:
我没有使用 UITextView。所选文本位于 UIWebView 中。 @Simon,那么需要使用javascript来获取rect,但原理是一样的。请参阅this useful explanation 以及 Cassius 的回答。【参考方案2】:您可以使用 Javascript 代码从选定的文本中返回 CGRect。创建一个 file.js 并添加此代码(或将其放在 NSString 上):
// Method that gets the Rect of current selected text
// and returns in a JSON format
var getRectForSelectedText = function(elm)
if (typeof elm === "undefined")
elm = window.getSelection().getRangeAt(0);
var rect = elm.getBoundingClientRect();
return "" + rect.left + "," + rect.top + ", " + rect.width + "," + rect.height + "";
加载 Javascript(文件或 NSString)
- (void)webViewDidFinishLoad:(UIWebView *)theWebView
//Load JS file
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"file" ofType:@"js"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSString *jsString = [[NSMutableString alloc] initWithData:fileData encoding:NSUTF8StringEncoding];
[self.webview stringByEvaluatingJavaScriptFromString:jsString];
现在展示你的弹出框:
CGRect rect = CGRectFromString([self.webview stringByEvaluatingJavaScriptFromString:@"getRectForSelectedText()"]);
[popover presentPopoverFromRect:rect
inView:webView
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
如果你需要在你的self.view中使用矩形,调整框架:
- (CGRect)rectForSelectedText
CGRect rect = CGRectFromString([self.webview stringByEvaluatingJavaScriptFromString:@"getRectForSelectedText()"]);
rect.origin.x += self.webview.frame.origin.x;
rect.origin.y += self.webview.frame.origin.y;
return rect;
希望对你有所帮助!
【讨论】:
不幸的是它没有用。这是screenshot。有什么想法吗? Simon,如果你给我发一个测试项目来解释我出了什么问题,我可以更好地帮助你!以上是关于在 iPad 上的 UIWebView 中定位弹出框的主要内容,如果未能解决你的问题,请参考以下文章