UIWebView 的 UIScrollView 子视图可以滚动但会弹回框架而不出现垂直滚动指示器
Posted
技术标签:
【中文标题】UIWebView 的 UIScrollView 子视图可以滚动但会弹回框架而不出现垂直滚动指示器【英文标题】:UIWebView's UIScrollView subview can scroll but bounce back to the frame without appearing vertical scroll indicator 【发布时间】:2013-11-07 09:23:37 【问题描述】:更新 - 解决方案 2nd
第一个解决方案(如下)仅适用于 ios 7,不适用于 iOS 6 或 iOS 5。因此,另一种方法是使用 -(void)scrollViewDidScroll:(UIScrollView *)scrollView
在发生任何滚动移动时更新滚动视图的内容大小,适用于 iOS 7 , 6 和 5。
在-(void)scrollViewDidScroll:(UIScrollView *)scrollView
里面,我记录了最高的内容尺寸高度,
if (_currentWebPageContentHeight < [[_webView scrollView] contentSize].height)
_currentWebPageContentHeight = [[_webView scrollView] contentSize].height;
每当加载另一个网页或重新加载当前页面时,将_currentWebPageContentHeight
恢复为默认高度(网页视图的高度)。
更新 - 解决方案 1st
我找到了一种解决方法,但不知道它为什么有效。稍微更改滚动视图的contentInset
将强制将contentSize
刷新为当前的。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
/// Load image data in async manner from photo chosen in album or taken by camera
// ....
/// Refresh the contentSize of UIScrollView inside UIWebView
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
[_galleryPopoverController dismissPopoverAnimated:YES];
/// A patch to force refresh the contentSize of scrollView, 0.01 is chosen to give unnoticeable layout change to user
[[webView scrollView] setContentInset:UIEdgeInsetsMake(0, 0, 0.01, 0)]; // UIEdgeInsetsMake(top, left, bottom, right)
else
[picker dismissViewControllerAnimated:YES completion:^
/// A patch to force refresh the contentSize of scrollView, 0.01 is chosen to give unnoticeable layout change to user
[[webView scrollView] setContentInset:UIEdgeInsetsMake(0, 0, 0.01, 0)]; // UIEdgeInsetsMake(top, left, bottom, right)
];
原来的问题
使用 Xcode 5、iOS 7、iPhone 5,没有 nib 文件,没有手动添加自动布局约束。
在一个项目中,有一个UIWebView,左下角有一个按钮,该按钮用于将照片从iPhone的相册或相机上传到测试网站。
当我尝试从相册上传照片时单击Choose
按钮时,会调用-(void)imagePickerController:didFinishPickingMediaWithInfo:
方法,当此方法完成时,UIImagePickerController 会随着动画消失,并加载所选照片。但是 UIWebView 的 UIScrollView 子视图,虽然可以向下滚动到当前网页的末尾,但是一直弹回到 UIWebView 的可见帧(origin.x = 0, origin.y = 64, size.width = 320, size.height = 568 - 64),也看不到垂直滚动指示器。
嵌入在 UIWebView 中的 UIScrollView 的 frame/bounds 是正确的,我在下面语句的 ^ 中检查它:
// At the end of the -(void)imagePickerController:didFinishPickingMediaWithInfo:
[imagePickerControllerInstance dismissViewControllerAnimated:YES completion:^];
我还强制这些值是正确的。但不会改变上述意外行为。
[[webView scrollView] setShowsVerticalScrollIndicator:YES];
[[webView scrollView] setScrollIndicatorInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[webView scrollView] setContentSize:(CGSizeMake([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height - 64))];
关于上面使用的数字:
320 是 iPhone 5 的宽度。 568 是 iPhone 5 的高度。 64 是状态栏和导航栏的高度。谁能解决这个问题?谢谢!
【问题讨论】:
【参考方案1】:您应该将setContentSize:
设置为实际的内容大小,而不是可见的帧大小。也就是说,如果您的内容是例如1000px 高,你应该setContentSize:CGSizeMake(width, 1000)
。这样你告诉UIScrollView
它应该滚动显示 1000px 高的内容。如果您将UIScrollView
的内容大小设置为等于其框架,则不会执行滚动,也不会出现滚动指示器(仅弹跳效果)。
【讨论】:
到@gWiz,那么如何获取实际的内容大小? 对于 WebViews,我使用以下代码:CGFloat contentHeight= [[detailWebText stringByEvaluatingjavascriptFromString:@"document.body.offsetHeight + document.body.offsetTop;"] floatValue];
嗨@gWiz,detailWebText
的类是什么?
嗨@gWiz,我这样称呼它:CGFloat currentContentHeight= [[webView stringByEvaluatingJavaScriptFromString:@"document.body.offsetHeight + document.body.offsetTop;"] floatValue];
,但它没有给出正确的内容高度。
你的webView当时是否加载完毕?可能是您还需要在- (void)webViewDidFinishLoad:(UIWebView *)webView
中运行它以上是关于UIWebView 的 UIScrollView 子视图可以滚动但会弹回框架而不出现垂直滚动指示器的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollview 高度变化基于 Uiwebview 内容
UIWebView 在 UIScrollView 内消耗触摸事件
嵌入在 UIScrollview 中的 UIWebview 中的 Javascript 触摸事件