scrollToTop无法在iPhone上运行,但它可以在iPad上运行

时间:2011-12-17 02:21:53

标签: iphone objective-c uiscrollview

我有两个视图控制器。一个用于页面控制的滚动视图和一个用于细节的滚动视图(垂直滚动)。

当我点击iPhone上的状态栏时,scrollToTop无效,而在iPad中,scrollToTop正在工作。

我确信scrollView.scrollToTop为YES。因为我已经打印出来了。

有人知道导致iPhone scrollToTop无法正常工作的原因吗?

谢谢

编辑: 我尝试通过调用scrollView委托。 在iPad中,这个委托给它打电话。 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView

在iPhone中它没有被调用。 我已经两个都用了     contentScrollView.delegate = self; 但是iPhone无法正常工作:(

编辑:尝试子类化UIWindow(不工作)

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;

4 个答案:

答案 0 :(得分:3)

根据我的理解,你在屏幕上同时拥有2个UIScrollViews。

从我所看到的&amp;有经验的, 在具有2个UIScrollViews并排的iOS 4上给出了未定义的行为。其中一个滚动视图可能会滚动,有时也可能滚动,有时也不滚动。

在iOS 5上,如果您并排放置2个UIScrollViews,然后点击状态栏“滚动到顶部”UIScrollView右侧“点按”

我不知道这是怎么回事,但这是我的观察。 iOS 5很聪明!!

如果您的UIScrollViews高于其他,那么可能行为未定义。我没有检查过。

希望这有帮助。

如果你想让它继续工作,那么这是一个可能的解决方案。

子类或在 UIWindow上添加一个类别并添加一个手势识别器/或实现hitTest,它只检测点击Y&lt; 20等等然后让它发送通知并在你的viewController中监听它并以编程方式将UIScrollView滚动到顶部。

修改

在UIWindow子类(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];
}

答案 1 :(得分:1)

如果您在同一屏幕上有多个UIScrollView实例(包括子类,例如UITableView e.t.c),则需要定义哪一个应该对scrollToTop事件起作用。这意味着,您需要遍历这些实例并将其scrollToTop属性设置为NO,除非您希望这样做。对我而言,它始终有效。如果它没有,那是因为其他一些UIScrollView,我不知道它在那里。在那种情况下,我只是通过递归禁用thet属性走过所有子视图,然后它开始按预期工作。 干杯。 :)

答案 2 :(得分:1)

不知道Apple吸烟的是什么,但按照设计,iPhone上的行为与iPad明显不同。 Apple's documentation确实包括以下“特别恭维”说明......

  

在iPhone上,如果有更多内容,滚动到顶部的手势无效   一个滚动视图在屏幕上,其中scrollsToTop设置为YES。

所以在iPhone上你必须确保只有一个UIScrollView(或UITableView / UICollectionView / UIWebView等)有scrollsToTop = YES

由于scrollsToTop默认为YES,因此您必须为UIScrollView显式设置scrollsToTop = NO,当用户点击状态栏时您不想滚动。

答案 3 :(得分:0)

这是我的解决方案,基于NSIntegerMax的答案。这样我们就不必关心方向或者有硬编码的值。

声明此宏

#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))

并实施方法:

- (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];
}