UIWebView not calling UIScrollViewDelegate methods

2019-07-20 21:29发布

问题:

In my iphone app i set delegate of my uiwebview to files owner but it is not calling uiscrollviewdelegate methods

my code is

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

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

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

    NSLog(@"scrollViewDidScroll  ");
}

but i am getting

webViewDidStartLoad
webViewDidFinishLoad

these messages in the console.

What is wrong with me

Thanks in advance

回答1:

UIWebView's delegate property only allows you to set the delegate for the UIWebViewDelegate protocol. (Look here for UIWebView reference.)

UIWebView is in itself a UIScrollViewDelegate, in that it receives the delegate calls from the UIScrollView it contains. Unfortunately, you have no API-access to that UIScrollView, so you cannot change its delegate; thus, it remains hard-coded to the UIWebView itself.

Now, there are several ways you can try and get those delegate messages.

One way for you to get UIScrollViewDelegate calls is subclassing UIWebView, if that works. In any case, you should be very careful, because depending on what you do you might break the UIWebView integrity and some features could stop working (possibly with some future SDK release). Furthermore, Apple discourages doing that, although it will not make your app rejected (as per many people who have reported doing that and having no problems with the App Store approval).

Another approach could be iterating through the subviews of your UIWebView until you find a UIScrollView object and then change its delegate.

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

I am not sure if this is reliable or may break anything, since the coupling between UIWebView and its UIScrollView child is very tight and not described anywhere, but you can have a try. All in all, I don't think this is much better than subclassing UIWebView.

Finally, a third approach is defining your own UIWindow type. This will allow you to override a few key methods (sendEvent or hitTest:event:) so that you can intercept the touches before they are dispatched at the view level. This will give you a chance to handle them and, if required, prevent them from reaching their original target.

This is the cleanest solution, although it is more work and it will require you to define a custom UIWindow where you do all the touch recognizing/dispatching.

A tutorial describing how to override sendEvent is available here.



回答2:

For those that are looking after the SWIFT 3 solution:

set UIScrollViewDelegate and then here is an example:

var noticias: UIWebView!
noticias.scrollView.delegate = self


回答3:

UIWebView has it's own UIScrollView.Maybe you can try like this self.webView.scrollView.delegate = self;



回答4:

the scrollView of UIWebView actually has a writeable delegate property since iOS2. It works perfectly for me to use it.