UIWebView scrollView 没有在触摸时调用 scrollViewDidScroll
Posted
技术标签:
【中文标题】UIWebView scrollView 没有在触摸时调用 scrollViewDidScroll【英文标题】:UIWebView scrollView not calling scrollViewDidScroll on touch 【发布时间】:2013-06-22 17:20:15 【问题描述】:我正在为 ios 6 进行开发,我正在开发一种位于 UIWebView 顶部的工具栏,当您在 UIWebView 上向上滚动时,该工具栏会后退。
我的想法是,我可以设置 UIWebView 内的 UIScrollView 的委托来向我的 UIViewController 发送消息,这将动画顶部工具栏上的约束以使其缩小和移动等等。
但是,scrollViewDidScroll:
方法似乎没有被调用,这让我很困惑。
现在,SO 上还有许多与此类似的其他问题,其中大部分似乎是人们忘记在 scrollView 上设置委托属性...
Why does a UIWebView instance not call scrollViewDidScroll? - 代表。 scrollViewDidScroll never called - 代表。 UIWebView not calling UIScrollViewDelegate methods - 代表?不得不说。 How to implement scrollViewDidScroll in UIScrollView - 代表。 scrollViewDidScroll not executing - 和...代表。不用说,我正在设置委托。部分代码sn-ps:
SDDefinitionViewController.h:
@interface SDDefinitionViewController : UIViewController <UIWebViewDelegate, UIScrollViewDelegate>
...
SDDefinitionViewController.m:
...
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
[self loadDefinitions];
// Grab a reference to the ScrollView so that we can set the delegate and then use those method calls to animate the top bar.
self.scrollView = self.webView.scrollView;
self.scrollView.delegate = self;
self.lastScrollViewVerticalOffset = 0;
...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
// (Code) <= Never gets called
...
而且,最重要的是,我做了一些调试器控制台操作:
(lldb) po self
$0 = 0x095c0600 <SDDefinitionViewController: 0x95c0600>
(lldb) po self.scrollView
$1 = 0x0954e8d0 <_UIWebViewScrollView: 0x954e8d0; frame = (0 0; 1024 596); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x954ec50>; layer = <CALayer: 0x954eab0>; contentOffset: 0, 0>
(lldb) po self.scrollView.delegate
$2 = 0x095c0600 <SDDefinitionViewController: 0x95c0600>
所以,delegate 的设置肯定是正确的,不会随机释放任何东西。
最后,我以编程方式在self.scrollView
上调用了setContentOffset
,并且委托方法确实 被调用了。但这并没有真正的帮助,因为我想检测用户何时使用手势滚动。
那么,这有什么独家新闻呢?为什么 scrollView 不会调用它的委托方法?
编辑:
因此,使用Reveal 查看我的应用程序,我发现我的 UIWebView 有一个 _UIWebViewScrollView 作为子视图,并且在其下方有一个 UIWebBrowserView。 UIWebBrowserView 的大小与 UIWebView 完全相同...
可能是 UIWebViewScrollView 没有正常的内容视图,它会偏移等等,webkit 正在滚动还是什么?
【问题讨论】:
【参考方案1】:作为UIWebView
内部实现UIScrollViewDelegate
方法。 UIScrollViewDelegate
不太可能被重新分配给除当前 UIWebView 对象之外的其他对象。
所以,我找到了一个小工作。您可以继承 UIWebView 实现该类中的UIScrollViewDelegate
方法,并且不要忘记将该方法转发给超级,否则可能会发生意外行为。
这就是我解决上述问题的方法:
/////in WebView.h file
//////WebView is subclass of UIWebView
#import <UIKit/UIKit.h>
@interface WebView : UIWebView
@property(nonatomic,weak) NSObject <UIScrollViewDelegate> *mScrollDelegate;
@end
//// in WebView.m file
#import "WebView.h"
@synthesize mScrollDelegate;
@implementation WebView
- (id)init
self = [super init];
if (self)
self.scrollView.delegate = self;
return self;
/////scrollViewDidScroll Method, Also I am forwarding it to super class UIWebView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
[super scrollViewDidScroll:scrollView];
if([self.mScrollDelegate respondsToSelector:@selector(scrollViewDidScroll:)])
[self.mScrollDelegate scrollViewDidScroll:scrollView];
NSLog(@"scrollViewDidScroll");
@end
并确保您的self.webView
必须是WebView
类型。
在 SDDefinitionViewController.m
self.webView.mScrollDelegate = self;
现在 SDDefinitionViewController.m 中的 scrollViewDidScroll 方法将被调用
【讨论】:
感谢您的回复。问题:在我上面的帖子中,当我在self.webView.scrollView
上直接调用setContentOffset:
时,它确实 在我的视图控制器上调用了scrollViewDidScroll:
,这表明我已经成功地将滚动视图的委托设置为我的视图控制器。你确定子类化UIWebView
是必要的吗?我相信问题在于滚动视图根本没有调用scrollViewDidScroll:
,无论代表是谁......除非你有更多信息?
考虑在子 scrollView
的 contentOffset
属性上使用 KVO。修改 UIScrollView
的委托属性不一定是安全的,因为 UIWebView
可以在内部使用它。【参考方案2】:
我会回答我自己的问题,即使答案很愚蠢。
与我一起从事该项目的另一个人设置了 UIWebView 的内容,发现 Web 视图中的滚动视图没有正确滚动。所以他禁用了 web 视图的滚动,然后在 html 中粘贴了-webkit-overflow-scrolling: touch;
标签,这导致 webkit 滚动而不是 web 视图——尽管它看起来大致相同。他试图解决的最初问题是,某些 div,无论出于何种原因,具有 CSS 样式 overflow:hidden;
,这导致 div 的实际大小不适合其内容,并使 web 视图认为页面非常小,因此滚动不起作用。
这花了我大约 8 个小时来解决,尽管我承认当我缺乏 Web 开发知识导致我从字面上破解 CSS 样式表直到我弄清楚是什么属性导致 div 不自动-size 到他们的内容。
无论如何,也许有一天这会对某人有所帮助。
【讨论】:
以上是关于UIWebView scrollView 没有在触摸时调用 scrollViewDidScroll的主要内容,如果未能解决你的问题,请参考以下文章
在目标 c 中从 UIWebView.scrollView 写入 PDF 文件
UIScrollview中的UIWebview向scrollview发送垂直滚动事件