问题
I have an iPhone app with a ScrollView which needs to respond to touch events.
In order to support touch events in the scrollview I needed to base it off a custom class which captured the touch events and passed them to the main view.
It works as expected when run in the 4.3 iPhone simulator. With the NSLOG entries I get output like this:
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
The gameTable is the event inside the custom class which just passes it to the outside view.
If you run the same app in the iOS 5 iPhone simulator you get output like this:
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
Notice the outside moved event only fires once.
Here is the code. It's a single view project in 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
回答1:
I recently posted an answer to a similar question.
In GameTableScrollView
you have this code:
-(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];
}
And to fix the problem you need to change this line:
[self.nextResponder touchesBegan:touches withEvent:event];
To this:
[[self.nextResponder nextResponder] touchesBegan:touches withEvent:event];
This will cause the GameTableScrollView
to pass the touch event to the outside view.
来源:https://stackoverflow.com/questions/7794783/touchesmoved-not-firing-in-ios5-for-the-iphone-for-uiscrollview