【问题标题】:scrollToTop is not working on iPhone but it is working on iPadscrollToTop 在 iPhone 上不工作,但在 iPad 上工作
【发布时间】:2012-01-22 10:47:10
【问题描述】:

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

当我在 iPhone 上单击状态栏时,scrollToTop 不起作用,而在 iPad 中,scrollToTop 正在工作。

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

谁知道是什么原因导致 iPhone 的 scrollToTop 不工作?

谢谢

编辑: 我尝试调用 scrollView 委托。 在 iPad 中,这个委托被称为。 - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView

在 iPhone 中它不被调用。 我已经同时使用了 contentScrollView.delegate = self; 但是iphone不工作:(

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

窗口.h

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
@interface Window : UIWindow
@end

窗口.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;

【问题讨论】:

    标签: iphone objective-c uiscrollview


    【解决方案1】:

    据我了解,您在屏幕上同时有 2 个 UIScrollView。

    根据我的所见所闻, 在 iOS 4 上并排有 2 个 UIScrollView 会产生未定义的行为。其中一个滚动视图可能会滚动,有时可能会滚动,有时两者都不会。

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

    我不知道这是如何工作的,但这是我的观察。 iOS 5 很智能!!

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

    希望这会有所帮助。

    如果你想让它正常工作,那么这里有一个可能的解决方案。

    子类或在 UIWindow上添加一个类别并添加一个手势识别器/或实现仅检测Y

    编辑

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

    【讨论】:

    • 在我的 iPhone ios 5 中也无法正常工作。在 ipad 4.3 和 5 中都可以正常工作。如何在 UIWindow 上添加类别并添加手势识别器?
    • 我已经用 uiwindow 子类编辑了我的问题。那是对的吗?如果代码正确,则不会打印 nslog。
    • 我刚刚检查过了。它适用于纵向,但不适用于其他方向。看起来 UIWindow 坐标系在方向上不会改变。但是解决这个问题应该不成问题。我将发布更新的代码。我还看到您正在使用 IBOutlet for Window。您还需要在界面生成器中更改类。
    • 更新了代码。 NSLog 打印三次,因为 hitTest 被称为三次(我不知道为什么),即使是单次触摸,所以你需要确保通知不会触发三次。但这应该很容易使用 performSelector:afterDelay 和 cancelPreviousPerformRequest 函数处理
    • hit test 对 iphone 和 ipad 都有效,并打印 nslog.. 但是对于 scrollToTop,问题仍然存在。它不适用于 iphone :( 对于我的问题
    【解决方案2】:

    如果您在同一屏幕上有多个 UIScrollView 实例(包括子类,例如 UITableView 等),您需要定义一个应该对 scrollToTop 事件执行的操作。这意味着,您需要遍历这些实例并将它们的 scrollToTop 属性设置为 NO,除非您确实想要这样做。对我来说,它一直有效。如果它没有,那是因为其他一些UIScrollView 我不知道它在那里。在那种情况下,我只是遍历所有子视图,递归地禁用该属性,然后它开始按预期工作。 干杯。 :)

    【讨论】:

      【解决方案3】:

      不知道苹果在吸什么,但从设计上看,iPhone 上的行为与 iPad 明显不同。 Apple's documentation 确实包含如下“特别注意事项”说明...

      在 iPhone 上,滚动到顶部手势无效 而不是屏幕上的一个滚动视图将 scrollsToTop 设置为 YES。

      因此,在 iPhone 上,您必须确保只有一个 UIScrollView(或 UITableView/UICollectionView/UIWebView 等)具有其scrollsToTop = YES

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

      【讨论】:

        【解决方案4】:

        这是我基于 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];
        }
        

        【讨论】:

          猜你喜欢
          • 2016-10-17
          • 1970-01-01
          • 2015-03-17
          • 1970-01-01
          • 1970-01-01
          • 2013-08-08
          • 2016-07-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多