我有一个解决这个问题的方案,但是我必须说我不太喜欢它。它很好用,但是这个解决方案实际上会导致另一个问题。我有一个修复次要问题的方法,但需要花费一些努力。
请记住,自从OS3.2或iOS4(我不确定哪个版本)之后,UIWebView的直接子视图现在是UIScrollView而不是UIScroller,因此我们可以做更多的事情。此外,由于访问View的子视图不是私有操作,使用作为文档化视图转换的子视图也不违反规则,所以我们可以在不违反规则的情况下对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。
现在运行你的应用程序,缩放网页然后再次缩小。旋转后,它应该正确显示。
这确实会导致一个相当大的bug,可能比原来的更糟糕。
如果你放大然后旋转,你将失去滚动能力,但你的视图仍然会被放大。这里是修复整个问题的方法。
首先,我们需要跟踪一些数字,并定义一个标志:
我已经在我的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;
}
就是这样!现在当您旋转时,它将保持缩放,并大致保持正确的偏移量。如果有人想要计算如何获得精确的正确偏移量,那就去做吧!