I have two view controller. One scrollview for page control and one for detail (scroll vertical).
When i click status bar on iPhone the scrollToTop not working, and in iPad the scrollToTop is working.
I am sure that the scrollView.scrollToTop is YES. because i already print it.
Anyone know what cause the iPhone scrollToTop not working?
Thank you
Edit:
I try by calling the scrollView delegate.
in iPad this delegate its called.
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
in iPhone it is not called.
I already use both
contentScrollView.delegate = self;
But the iphone not working :(
Edit: Try subclassing UIWindow (not working)
Window.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface Window : UIWindow
@end
Window.m
#import "Window.h"
@implementation Window
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([event type] == UIEventTypeTouches && point.y < 250) {
//Send Your Notification Here
NSLog(@"KAROOO");
}
NSLog(@"HELLOWW");
return [super hitTest:point withEvent:event];
}
@end
AppDelegate.h
@property (nonatomic, strong) IBOutlet Window *window;
AppDelegate.m
@synthesize window = _window;
From what I understand you have 2 UIScrollViews simultaneously on screen.
From what I have seen & experienced,
On iOS 4 having 2 UIScrollViews side by side gives undefined behaviour. One of the scrollview may scroll, sometimes other, sometimes neither.
On iOS 5 if you have 2 UIScrollViews side by side then tapping on status bar "scrolls to top" the UIScrollView right "under your tap"
I don't know how this works, but this has been my observation. iOS 5 is smart !!
If your UIScrollViews are one above other then probably the behaviour is undefined. I haven't checked.
Hope this helps.
If you want to get it working anyways then here is a possible solution.
Subclass or Add a category on UIWindow and add a gesture recognizer / or implement hitTest that detects tap only for Y < 20 and so on and then have it send a notification and listen to this in your viewController and programmatically scroll the UIScrollView to top.
EDIT
Implement this in the UIWindow subclass (iPad)
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([event type] == UIEventTypeTouches && point.y < 20 && [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait) {
NSLog(@"Portrait");
} else if ([event type] == UIEventTypeTouches && point.y > 1004 && [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown) {
NSLog(@"PortraitUpsideDown");
} else if ([event type] == UIEventTypeTouches && point.x < 20 && [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) {
NSLog(@"LandscapeLeft");
} else if ([event type] == UIEventTypeTouches && point.x > 748 && [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
NSLog(@"LandscapeRight");
}
return [super hitTest:point withEvent:event];
}
In case you have more then one UIScrollView
instance (including subclasses e.g. UITableView
e.t.c) on the same screen you need to define wich one should act on scrollToTop event. That means, that you need to go through those instances and set their scrollToTop
property to NO except for the one you do want to do so. For me it worked always. In case it didn't, it was because of some other UIScrollView
that I didn't knew it's there. In that case I just walked throug all subviews recursively disabling thet property and then it started to work as espected.
Cheers. :)
Don't know what Apple were smoking but by design, the behaviour on iPhone is distinctly different from iPad. Apple's documentation does include a "Special Condsideration" note as follows...
On iPhone, the scroll-to-top gesture has no effect if there is more
than one scroll view on-screen that has scrollsToTop set to YES.
So on iPhone you have to ensure that there is only ever one UIScrollView (or UITableView/UICollectionView/UIWebView etc) that has its scrollsToTop = YES
.
Since scrollsToTop defaults to YES you have to explicitly set scrollsToTop = NO
for the UIScrollView's you do not want to scroll when the user taps the status bar.
Here is my solution based on NSIntegerMax's answer. This way we don't have to care about the orientation or have hardcoded values.
declare this macro
#define isInStatusBar(frame, point) (point.x >= frame.origin.x && point.x <= (frame.origin.x+frame.size.width) && point.y >= frame.origin.y && point.y <= (frame.origin.y+frame.size.height))
and implement the method:
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGRect frame = [[UIApplication sharedApplication] statusBarFrame];
if ([event type] == UIEventTypeTouches && isInStatusBar(frame, point)) {
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationAppDidTouchStatusBar object:nil];
}
return [super hitTest:point withEvent:event];
}