UIWebView不调用UIScrollViewDelegate方法

Joh*_*tty 2 iphone objective-c uiwebview uiscrollview ios

在我的iPhone应用程序中,我将我的uiwebview的委托设置为文件所有者,但它没有调用uiscrollviewdelegate方法

我的代码是

- (void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"webViewDidStartLoad  ");
}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
     NSLog(@"webViewDidFinishLoad  ");
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

     NSLog(@"scrollViewDidEndDecelerating  ");
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    NSLog(@"scrollViewDidScroll  ");
}
Run Code Online (Sandbox Code Playgroud)

但我得到了

webViewDidStartLoad
webViewDidFinishLoad
Run Code Online (Sandbox Code Playgroud)

控制台中的这些消息.

我是怎么了

提前致谢

ser*_*gio 6

UIWebViewdelegate属性只允许您设置UIWebViewDelegate协议的委托.(看这里UIWebView参考.)

UIWebView本身就是一个UIScrollViewDelegate,因为它接收来自UIScrollView它包含的委托调用.不幸的是,您没有API访问权限UIScrollView,因此您无法更改其委托; 因此,它UIWebView本身仍然是硬编码的.

现在,有几种方法可以尝试获取这些委托消息.

如果可以的话,你获得UIScrollViewDelegate调用的一种方法是子类化UIWebView.在任何情况下,您都应该非常小心,因为根据您的操作,您可能会破坏UIWebView完整性,某些功能可能会停止工作(可能会有一些未来的SDK版本).此外,Apple不鼓励这样做,虽然它不会让您的应用程序被拒绝(根据许多报告这样做并且App Store批准没有问题的人).

另一种方法可能是迭代subviews你的,UIWebView直到你找到一个UIScrollView对象,然后改变它的委托.

UIScrollView* scrollView = nil;
for (UIView* subview in [webView subviews]) {
   if ([subview isKindOfClass:[UIScrollView class]]) {  
      scrollView = (UIScrollView*)subview;
      scrollView.delegate = <YOUR_DELEGATE_HERE>;
      break;
   }
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否可靠或可能会破坏任何东西,因为UIWebView它和它的UIScrollView孩子之间的耦合很紧,并没有在任何地方描述,但你可以尝试一下.总而言之,我认为这不比子类化好得多UIWebView.

最后,第三种方法是定义您自己的UIWindow类型.这将允许您覆盖一些关键方法(sendEventhitTest:event:),以便您可以在视图级别调度之前拦截触摸.这将使您有机会处理它们,并在必要时阻止它们达到其原始目标.

这是最干净的解决方案,虽然它是更多的工作,它将要求您定义一个自定义UIWindow,您可以执行所有触摸识别/分派.

这里sendEvent提供一个描述如何覆盖的教程.