【问题标题】:touchesMoved not firing in iOS5 for the iPhone for UIScrollViewtouchesMoved 没有在 iOS5 中为 iPhone 触发 UIScrollView
【发布时间】:2011-10-17 13:51:50
【问题描述】:

我有一个带有 ScrollView 的 iPhone 应用程序,它需要响应触摸事件。

为了在滚动视图中支持触摸事件,我需要将它基于一个自定义类,该类捕获触摸事件并将它们传递给主视图。

在 4.3 iPhone 模拟器中运行时按预期工作。使用 NSLOG 条目,我得到如下输出:

2011-10-17 09:28:06.782 SingleView[7000:b303] gameTable began
2011-10-17 09:28:06.784 SingleView[7000:b303] outside began
2011-10-17 09:28:09.976 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:09.976 SingleView[7000:b303] outside moved
2011-10-17 09:28:09.977 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:09.978 SingleView[7000:b303] outside moved
2011-10-17 09:28:10.019 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:10.020 SingleView[7000:b303] outside moved
2011-10-17 09:28:10.046 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:10.047 SingleView[7000:b303] outside moved
2011-10-17 09:28:10.077 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:10.077 SingleView[7000:b303] outside moved
2011-10-17 09:28:10.143 SingleView[7000:b303] gameTable moved
2011-10-17 09:28:10.144 SingleView[7000:b303] outside moved
2011-10-17 09:28:12.433 SingleView[7000:b303] gameTable ended
2011-10-17 09:28:12.434 SingleView[7000:b303] outside ended

gameTable 是自定义类中的事件,它只是将它传递给外部视图。

如果您在 iOS 5 iPhone 模拟器中运行相同的应用程序,您会得到如下输出:

2011-10-17 09:41:46.319 SingleView[7077:f803] gameTable began
2011-10-17 09:41:46.322 SingleView[7077:f803] outside began
2011-10-17 09:41:47.851 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:47.852 SingleView[7077:f803] outside moved
2011-10-17 09:41:47.853 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:47.860 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:47.893 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:47.916 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:47.945 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:48.009 SingleView[7077:f803] gameTable moved
2011-10-17 09:41:48.062 SingleView[7077:f803] gameTable moved

注意外部移动事件只触发一次。

这里是代码。这是 Xcode 中的单视图项目。

//
//  XYZAppDelegate.h
//  SingleView
//

#import <UIKit/UIKit.h>

@class XYZViewController;

@interface XYZAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) XYZViewController *viewController;

@end



//
//  XYZAppDelegate.m
//  SingleView
//

#import "XYZAppDelegate.h"

#import "XYZViewController.h"

@implementation XYZAppDelegate

@synthesize window = _window;
@synthesize viewController = _viewController;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[XYZViewController alloc] initWithNibName:@"XYZViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

@end


//
//  XYZViewController.h
//  SingleView
//

#import <UIKit/UIKit.h>
#import "GameTableScrollView.h"

@interface XYZViewController : UIViewController <UIScrollViewDelegate> {
    IBOutlet GameTableScrollView *outsideScrollView;

}

@property (nonatomic, retain) GameTableScrollView *outsideScrollView;

@end

    //
    //  XYZViewController.m
    //  SingleView
    //

    #import "XYZViewController.h"

    @implementation XYZViewController
    @synthesize outsideScrollView;

    #pragma mark - View lifecycle

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.

        [outsideScrollView setScrollEnabled:NO];
        [outsideScrollView setContentSize:CGSizeMake(480,555)];
    }


    // Handles the start of a touch
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"outside began");
    }

    // Handles the continuation of a touch.
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {  
        NSLog(@"outside moved");
    }


    // Handles the end of a touch event.
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"outside ended");
    }

    -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"outside cancelled");
    }

    @end

    //
    //  GameTableScrollView.h
    //

    #import <UIKit/UIKit.h>

    @interface GameTableScrollView : UIScrollView <UIScrollViewDelegate> {

    }

    @end

//
//  GameTableScrollView.m
//

#import "GameTableScrollView.h"

@implementation GameTableScrollView

#pragma mark - Touch 

// Handles the start of a touch
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"gameTable began");
    if (!self.dragging) {
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    else [super touchesBegan:touches withEvent:event];
}


// Handles the continuation of a touch.
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{  
    NSLog(@"gameTable moved");
    if (!self.dragging) {
        [self.nextResponder touchesMoved:touches withEvent:event];
    }
    else [super touchesMoved:touches withEvent:event];
}


// Handles the end of a touch event.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"gameTable ended");
    if (!self.dragging) {
        [self.nextResponder touchesEnded:touches withEvent:event];
    } 
    else [super touchesEnded:touches withEvent:event];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"gameTable cancelled");
    if (!self.dragging) {
        [self.nextResponder touchesCancelled:touches withEvent:event];
    } 
    else [super touchesCancelled:touches withEvent:event];
}

@end

【问题讨论】:

  • 上面的代码足以重现问题。通常在 UIScrollView 中有一个 UIImageView ,用户将拖动它。这就是我需要处理触摸事件的原因。
  • 我不确定这是否是答案,但您可能想在 XYZViewController.h 文件中使用 GameTableScrollView 而不是使用 UIScrollView。此外,您可能需要导入 GameTableScrollView 标头,进入 IB 并更改滚动视图的类,然后将其重新连接回 IBOutlet。
  • 值得一试,但很抱歉没有运气。我已经用您建议的更改更新了原始帖子中的代码,以便您查看。
  • 我已经记录了 Apple 的一个错误,因为我觉得这不是正确的行为。当(如果)我得到回复时,我会在这里发布答案。
  • 与此同时,我找到了另一种方法来完成它。我扩展了 UIScrollViewDelegate 以包含我自己版本的 touchevents 的方法。然后我在我的子类 UIScrollView 中调用这些方法。

标签: iphone uiscrollview ios5 touchesmoved


【解决方案1】:

我最近向类似的question 发布了answer

GameTableScrollView 你有这个代码:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"gameTable began");
    if (!self.dragging) {
        [self.nextResponder touchesBegan:touches withEvent:event];
    }
    else [super touchesBegan:touches withEvent:event];
}

要解决问题,您需要更改此行:

[self.nextResponder touchesBegan:touches withEvent:event];

对此:

[[self.nextResponder nextResponder] touchesBegan:touches withEvent:event];

这将导致GameTableScrollView 将触摸事件传递给外部视图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    相关资源
    最近更新 更多