我有解决这个问题的办法,但我得说我不是它的忠实粉丝。它工作得很好,但该解决方案实际上会导致另一个问题。我已经解决了次要问题,但需要一些努力。
请记住,由于 OS3.2 或 iOS4(不确定是哪个)UIWebView 的直接子视图现在是 UIScrollView 而不是 UIScroller,所以我们可以用它做更多的事情。此外,由于访问视图的子视图不是私人操作,因此使用被转换为文档视图的子视图也不是我们可以在不违反规则的情况下对 UIWebView 做很多事情。
首先我们需要从 UIWebview 中获取 UIScrollView:
UIScrollView *sview = [[webView subviews] objectAtIndex:0];
现在我们需要更改此滚动视图的委托,以便我们可以覆盖滚动视图委托调用(这实际上可能是由于此解决方案导致的次要错误,我稍后会分享):
sview.delegate = self;
现在,如果您在这一点上尝试,缩放会被破坏。我们需要实现一个 UIScrollViewDelegate 方法来修复它。添加:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
UIView *webBrowserView = [[scrollView subviews] objectAtIndex:10];
return webBrowserView;
}
webBrowserView 实际上是一个 UIWebBrowserView,但这不是一个文档化的类,所以我们只是把它当作一个 UIView 来对待。
现在运行您的应用,放大然后缩小网页。旋转,它应该会正确显示。
这确实会导致一个相当大的错误,这可能比原来的更糟糕。
如果您放大然后旋转,您将失去滚动能力,但您的视图仍会被放大。这是完成整个事情的修复程序。
首先,我们需要跟踪一些数字,并定义一个标志:
我在我的 h 文件中定义了这些:
BOOL updateZoomData;
float zoomData; //this holds the scale at which we are zoomed in, scrollView.zoomScale
CGPoint zoomOffset; //this holds the scrollView.contentOffset
CGSize zoomContentSize; //this holds the scrollView.contentSize
您可能认为您可以从 UIScrollView 中获取这些数字,但是当您需要它们时,它们会发生变化,因此我们需要将它们存储在其他地方。
我们需要使用另一个委托方法:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
if(updateZoomData){
zoomData = scrollView.zoomScale;
zoomOffset = scrollView.contentOffset;
zoomContentSize = scrollView.contentSize;
}
}
现在我觉得它变得一团糟。
我们需要跟踪轮换,因此您需要将其添加到您的 viewDidLoad、loadView 或您用来注册通知的任何方法中:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(webViewOrientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
并创建此方法:
- (void)webViewOrientationChanged:(NSNotification *)notification{
updateZoomData = NO;
[self performSelector:@selector(adjustWithZoomData) withObject:nil afterDelay:0.0];
}
所以现在任何时候你旋转 webViewOrientationChange 都会被调用。 performSelector 延迟 0.0 秒的原因是因为我们想在下一个 runloop 上调用 adjustWithZoomData。如果直接调用,adjustWithZoomData 会根据之前的方向进行调整。
这里是 adjustWithZoomData 方法:
- (void)adjustWithZoomData{
UIScrollView *sview = [[webView subviews] objectAtIndex:0];
[sview setZoomScale:zoomData animated:YES];
[sview setContentOffset:zoomOffset animated:YES];
[sview setContentSize:zoomContentSize];
updateZoomData = YES;
}
就是这样!现在,当您旋转时,它将保持缩放,并大致保持正确的偏移量。如果有人想对如何获得准确的偏移量进行数学计算,那就去做吧!