views:

2751

answers:

7

Using this method to hide the status bar:

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];

When setting "hidden" back to NO, the tap-to-scroll-to-top (in UIWebView, UITableView, whatever) doesn't work any more, and requires a restart of the app to get the functionality back.

Is this a bug (I filed a rdar anyhow) or have I missed a step? Should I perhaps expect this behavior since the statusBar "loses touch" somehow with the respective view?

+2  A: 

You could try setting the ScrollsToTop property to true again after re-showing it:

[currentView setScrollsToTop:YES];

If that's not working, are you definitely only showing one view? If there is more than one scrolling view a scrollViewDidScrollToTop message is ignored...

h4xxr
Very good observation. It's probably getting confused with multiple views. Have to see if I can find a workaround.
avocade
The problem is that it's a UIWebView that needs to get the scroll-to-top behavior back–and it is not a direct UIScrollView subclass... thus that setScrollsToTop: doesn't work at all. IT probably has a scrollView somewhere in its UIWebViewInternal struct, but that seems to be _very_ opaque. [webView valueForKey:@"_scrollView"] didn't work at all to get direct hold of it. Any other name guesses? :)
avocade
You could add the UIWebView as a subview of a UIScrollView (in my implementation it is a subview of a UITableView). If it is the only view inside that UIScrollView then calling -setScrollsToTop on the UIScrollView should make it work on the UIWebView...
h4xxr
Your name really is h4x0r, isn't it :)
avocade
:-D it's my car number plate too!...
h4xxr
A: 

I just ran across a similar behavior in the app I'm currently working on. In its case, if you load a YouTube video from within a UIWebView, scroll to top stops working for the rest of the application's life cycle. I kind of assume this might happen after loading the movie player as well, but haven't confirmed. That functionality has been around a lot longer and probably has fewer bugs.

Ben Lachman
+1  A: 

You can use the following code to have the UIWebView ignore scrollToTop without the extra UIScrollView:

((UIScrollView *)[[webView valueForKey:@"_internal"] valueForKey:@"scroller"]).scrollsToTop = NO;

Nick Toumpelis
As this uses a private API call, this will likely cause your application to be rejected. You may be able to get away with `((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO;`
Alex Reynolds
Thanks Alex! Much more elegant and safe for sure.
Nick Toumpelis
This works for me. Great solution, thanks!
Jasarien
A: 

macsphere, it works like a charm ! Thanks a lot !

(sorry, I don't know how to answer directly to your post and I can't find a clue in the FAQ...)

Eric MORAND
I think you need to have reputation points or something like that. Alex's solution should be safer but I haven't had the chance to try it yet. As far as I can see, it should work.
Nick Toumpelis
+1  A: 

I had a similar problem after playing a Youtube video within my app. scrollsToTop was still set to YES but tapping the status bar had no effect.

I finally realised that my app window was no longer the key window. After adding the following line to a UIWindow subclass (which I already had for other reasons) everything worked as it should again:

if (![self isKeyWindow]) [self makeKeyWindow];
prendio2
+2  A: 

I was having a similar problem where the scroll-to-top functionality was lost. Turns out this will only work when you have only one active view at a time (within the same scroll view). In my case I had a table view and another view which would fade in/out. Adding a removeFromSuperview at the end of the animation did the trick.

The answer was in the UIScrollView.h file comments:

/*
 this is for the scroll to top gesture. by default, a single scroll visible scroll view with this flag set will get the call. if there is more than one visible with this
 flag set or the delegeat method returns NO, the view isn't scrolled 
 */
@property(nonatomic) BOOL  scrollsToTop;          // default is YES. if set, special gesture will scroll to top of view after consulting delegate
Juan
+1  A: 

The following fix by Alex worked for me. Thanks!

((UIScrollView *)[[webView subviews] objectAtIndex:0]).scrollsToTop = NO;

Being in a hurry this fix worked great, however given more time I might've subclassed the UIWebView and accessed the protected UIScrollView member directly.

The worry I have with Alex' method is that it assumes that UIScrollView is at index zero of the subviews (encapsulation allows private members to change). Which suggests another solution still:

for (UIView* v in [webView subviews])
{
    if ([v isKindOfClass:[UIScrollView class]])
    {
        (UIScrollView *)v.scrollsToTop = NO;
    }
}