I'm developing for iOS 6, and I am working on a sort of toolbar at the top of a UIWebView that will recede as you scroll up on the UIWebView.
My thought was that I could set the delegate of the UIScrollView that's inside the UIWebView to send messages to my UIViewController, which will animate the constraints on the toolbar at the top to get it to shrink and move and so forth.
However, the scrollViewDidScroll:
method does not seem to get called, which confuses me.
Now, there are a number of other questions on SO similar to this one, most of which seem to be people forgetting to set the delegate property on the scrollView…
- Why does a UIWebView instance not call scrollViewDidScroll? – Delegate.
- scrollViewDidScroll never called – Delegate.
- UIWebView not calling UIScrollViewDelegate methods – Delegate? Had to tell.
- How to implement scrollViewDidScroll in UIScrollView – Delegate.
- scrollViewDidScroll not executing – And…delegate.
Needless to say, I'm setting the delegate. Some code snippets:
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
}
...
And, to top it off, I did some debugger console action:
(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>
So, the delegate is definitely set correctly, there's nothing being released randomly.
Finally, I programmatically called setContentOffset
on self.scrollView
and the delegate method did get called. But that's not really helpful, because I want to detect when the user is scrolling with a gesture.
So, what's the scoop on this? Why would the scrollView not be calling its delegate methods?
EDIT:
So, looking at my app with Reveal, I see that my UIWebView has as a subview a _UIWebViewScrollView, and beneath that there is a UIWebBrowserView. The UIWebBrowserView is exactly the same size as the UIWebView…
Could it be that the UIWebViewScrollView doesn't have a normal content view that it offsets and so on, that webkit is doing the scrolling or something?
Best Answer
As
UIWebView
internally implementsUIScrollViewDelegate
Methods. Its is unlikely that theUIScrollViewDelegate
will get reassigned to other objects except the current UIWebView object. So, I found a small work around. You can subclass UIWebView implement theUIScrollViewDelegate
methods in that class and don't forget to forward the method to super or else unexpected behavior may occur.This is how I solved the above problem:
And make sure your
self.webView
must be of typeWebView
. in SDDefinitionViewController.mNow your scrollViewDidScroll method in SDDefinitionViewController.m will get called