我的应用程序在 UIScrollView 中有几个 UIWebView 视图。有时我有 html 内容,所以我使用 UIWebView loadHTMLString:baseURL: 方法加载 UIWebView。这似乎不会导致问题。最近我开始使用 loadRequest: 方法加载一些带有 url 的 UIWebView 实例。一旦我开始这样做,每当我滚动时,我都会收到以下错误:
*由于未捕获的异常“CALayerInvalidGeometry”而终止应用程序,原因:“CALayer 位置包含 NaN:[nan nan]”
使用以下堆栈跟踪:
Thread 1, Queue : (null)
#0 0x01dd5caa in objc_exception_throw ()
#1 0x01f5da48 in +[NSException raise:format:arguments:] ()
#2 0x01f5d9b9 in +[NSException raise:format:] ()
#3 0x007e8c0d in CA::Layer::set_position(CA::Vec2<double> const&, bool) ()
#4 0x007def55 in -[CALayer setPosition:] ()
#5 0x037b07d3 in -[WebFixedPositionContent scrollOrZoomChanged:] ()
#6 0x00a5bfae in -[UIWebDocumentView _updateFixedPositionContent] ()
#7 0x00c66ff3 in -[UIWebBrowserView _updateFixedPositionContent] ()
#8 0x00a5b07e in -[UIWebDocumentView _didScroll] ()
#9 0x01fb6dea in -[NSObject performSelector:] ()
#10 0x01f207f1 in -[NSArray makeObjectsPerformSelector:] ()
#11 0x0091627d in -[UIScrollView(Static) _notifyDidScroll] ()
#12 0x009029ae in -[UIScrollView setContentOffset:] ()
#13 0x00909ac8 in -[UIScrollView _updatePanGesture] ()
#14 0x0090d3c0 in -[UIScrollView handlePan:] ()
#15 0x00b84e29 in _UIGestureRecognizerSendActions ()
#16 0x00b84133 in -[UIGestureRecognizer _updateGestureWithEvent:] ()
#17 0x00b853bf in -[UIGestureRecognizer _delayedUpdateGesture] ()
#18 0x00b87a21 in ___UIGestureRecognizerUpdate_block_invoke_0541 ()
#19 0x00b8797c in _UIGestureRecognizerApplyBlocksToArray ()
#20 0x00b803d7 in _UIGestureRecognizerUpdate ()
#21 0x008e51a2 in -[UIWindow _sendGesturesForEvent:] ()
#22 0x008e5532 in -[UIWindow sendEvent:] ()
我查看了许多关于此的问题和答案,并意识到苹果不鼓励这样做,但我还没有看到任何提供替代方案的答案。
我的第一个问题:有没有其他方法可以达到同样的效果?
下面是我如何创建 UIWebView 的片段
- (void) createWebView:(NSString*)url{
NSInteger requestedHeight = 480;
NSInteger requestedWidth = 640;
self.webContent = [[UIWebView alloc] initWithFrame: CGRectMake(0, self.frame.size.height, requestedWidth, requestedHeight)];
self.webContent.scrollView.userInteractionEnabled = NO;
self.webContent.scrollView.scrollEnabled = NO;
self.webContent.scrollView.bounces = NO;
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
[self.webContent loadRequest:urlRequest];
[self addSubview:self.webContent];
NSInteger calculatedHeight = self.webContent.frame.origin.y + self.webContent.frame.size.height;
NSInteger calculatedWidth = self.webContent.frame.origin.x + self.webContent.frame.size.width;
if (calculatedHeight > self.frame.size.height || calculatedWidth > self.frame.size.width){
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, MAX(self.frame.size.width, calculatedWidth), MAX(self.frame.size.height, calculatedHeight + 5));
}
}
如您所见,我禁用了 UIWebView 的滚动和用户输入。
我的第二个问题:当我明确禁用该功能时,为什么 UIWebView(或者至少是它的一个或多个子视图)处理滚动?
我的第三个问题:由于它似乎无论如何都在处理滚动,有没有其他方法可以拦截或禁用发送到 UIWebView 的滚动通知?
如您所见,我并不打算让用户与 UIWebView 的内容进行交互 - 只是让他们看到内容。
在这种情况下,可能的替代方法是以某种方式在用户不可见的 UIScrollView 之外创建一个 UIWebView,将其内容捕获到图像中,然后在 UIImageView 中显示内容?如果是这样,我将如何将 UIWebView 的内容捕获到图像中?
编辑:我找到了一个非常简单的解决方案。基本上加载您的 UIWebView 但不要将其添加为子视图。当 UIWebView 完成加载后,使用以下代码创建图像:
- (void)webViewDidFinishLoad:(UIWebView *)webView{
UIGraphicsBeginImageContext(self.webContent.bounds.size);
[self.webContent.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.imageContent setImage:image];
}
我仍然有兴趣听到问题 1 到 3 的答案。将来,如果我们决定支持交互式 UIWebView,则此解决方案将不起作用。
有什么建议么?