4

So I just have a standard UIViewController with a UIWebView in it that displays a pdf. For the app functionality, I have need to be able to respond to the UIWebView's nested UIScrollView events like scrollViewWillBeginDragging, scrollViewDidScroll, etc.

The only way I can get access to the scrollView is to (it seems like a hack) go in and get it by the subviews array:

for (id subview in webView.subviews){
    if ([[subview class] isSubclassOfClass: [UIScrollView class]])  {
        UIScrollView * s = (UIScrollView*)subview;
        s.delegate = self;
        s.tag = 1;
        scrollView = s;
    }
}

But that seems to introduce more problems than it's worth, because I lose native UIScrollView stuff like zooming.

So to sum up what I'm needing:

What is the best way to set my UIViewController class as the delegate of the UIScrollView inside of the UIWebView? Is there something I need to do with subclassing my own UIWebView so that it handles events from it's built in UIWebView a certain way and then pass it along somehow to the UIViewController? How does that passing thing work anyway?

Please advise!

Thank you!

Stephen J.
  • 3,127
  • 4
  • 20
  • 28

1 Answers1

4
  1. Have you checked there is only one UIScrollView subclass in the subviews? Bung in a log in your loop to see. If there is more than one, then you'll only pick up the last one using your code.

  2. If there is just one UIScrollView subclass, you could try saving a reference to its delegate and then in your own delegate methods passing messages on after you have done your business.

So, in your loop, something like

originalDelegate = s.delegate

And then for the delegate methods, something like:

- (void) scrollViewDidScroll: (UIScrollView*) scrollView;
{
     // do your stuff

     [originalDelegate scrollViewDidScroll: scrollView];
}

You might need to check whether originalDelegate responds to the selector before calling it, i.e. if ([originalDelegate respondsToSelector: @selector(scrollViewDidScroll:)) etc. If it were me, I'd start by implementing all twelve delegate methods defined in the UIScrollView delegate protocol.

Not tested this, so will be interested to know if it can be made to work. Do note, the docs explicitly say that UIWebView "should not be subclassed"

Obliquely
  • 7,002
  • 2
  • 32
  • 51
  • Thanks for your answer! I tried it, and it half-way works. I'm sure the bugs I'm facing can be ironed out when I implement all 12 delegate methods. Maybe a silly question, but how do you know what to return for all the methods? I mean especially for the ones that you don't explicitly need to override? I want to implement them all, but found the documentation lacking in actual implementation instructions (like after the method signature implementation). Thanks! – Stephen J. Jul 11 '11 at 04:46
  • Two of the UIScrollViewDelegate methods return a value. For those cases, just return what they return, e.g. - (UIScrollView*) viewForZoomingInScrollView: (UIScrollView*) scrollView { // do your stuff return [originalDelegate viewForZoomingInScrollView: originalDelegate]; } Is that what you were asking?? – Obliquely Jul 11 '11 at 04:52
  • Yeah so you mentioned that I should implement all 12 delegate methods, but if there are only two that return anything, what good does it do to implement all of them myself? I think that's what I don't get...:) – Stephen J. Jul 11 '11 at 05:02
  • Wait, I think it's clicking now! SO in each of the delegate implementations, I just pass the method call on to the delegate variable I stored the original delegate in? So in each method, I would do [originalDelegate whateverTheCurrentMethodIs]; just to make sure it gets passed on to the original delegate? – Stephen J. Jul 11 '11 at 05:10
  • YES - you're getting it... You may not implement them, but the original delegate may. You need to give the original delegate a chance to respond to the information being sent to it by the scrollView if you to keep the original behaviour. Say you are ignoring viewDidScroll for your purposes. If you don't pass the message on, then originalDelegate can't do any of the work it might need to adjust the view as a result of the move. I don't know what the originalDelegate will do. You'll start to get an idea as you work through. – Obliquely Jul 11 '11 at 05:11
  • Thank you so much! That just filled in a major void in my brain. I appreciate you taking the time to help me out. – Stephen J. Jul 11 '11 at 05:15