Question

I know this question seems to be already asked and answered but I can't resolve my issue.

I want to move the objects of my view to follow horizontal slides of a finger (going to previous or next page)

For this, I use TouchesBegan, TouchesMoved and TouchesEnded methods.

It works fine when the touches began on the view background but does not work when touches began on uibuttons.

To solve the problem, I have subclassed the uibuttons which i want to allow the gesture and it was working fine when i was on xCode 3.x and iOS 4.x

Today I just installed OSX Moutain Lion and started to work on xCode 4.4 and iOS 5.1.1 (iPAD). And here I am with the very same app that worked fine and not working anymore.

Here is my UIButton subclass:

//  myUIButton.h

#import <UIKit/UIKit.h>

@interface myUIButton : UIButton

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

@end


//  myUIButton.m

#import "myUIButton.h"

@implementation myUIButton

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"uibutton touches began");
    [self.nextResponder touchesBegan:touches withEvent:event];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"uibutton touches moved");
    [self.nextResponder touchesMoved:touches withEvent:event];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"uibutton touches ended");
    [self.nextResponder touchesEnded:touches withEvent:event];
}

@end

Here are the methods in my main class:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"view touches began");
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"view touches moved");
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"view touches ended");
}

When my touch began on an UIButton I get every NSLog from the subclass but the main touchesMoved is executed only once. (self.nextResponder seems to works only once)

Did something changed that make it not works on xcode 4.4 or iOS 5.1.1 ?

When I first tried to do that (on xcode 3.x and iOS 4.x) i found the solution here: Is there a way to pass touches through on the iPhone?

But it not works anymore...

Could you help me?

Thanks a lot.

EDIT : The problem is the same using [super touches...] instead or in more of [self.nextResponder touches...]

Was it helpful?

Solution

I have solved the problem a while ago and does not remember how but there are differences in my files so I'll write here the new version that works.

//  myUIButton.h
#import <Foundation/Foundation.h>

@interface myUIButton : UIButton {
}

@end

.

//  myUIButton.m

#import "myUIButton.h"

@implementation myUIButton

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

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"uibutton touches moved");
    [super touchesMoved:touches withEvent:event];
    [self.nextResponder touchesMoved:touches withEvent:event];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    NSLog(@"uibutton touches ended");
    [super touchesEnded:touches withEvent:event];
    [self.nextResponder touchesEnded:touches withEvent:event];
}

@end

In each view I need this behavior, I place a Pan Gesture Recognizer in the file.xib that I link to the action panRecognizer: defined in the file.m

// file.m

@synthesize slide_origin_x;

-(IBAction)panRecognizer:(UIPanGestureRecognizer *)recognizer {
    // Recording movement
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        self.slide_origin_x = [NSNumber numberWithFloat:recognizer.view.center.x];
    }

    // Choose an action
    else if (recognizer.state == UIGestureRecognizerStateEnded) {
        int to_launch_action = 100; // Action choosen after 100 pixels
        int touch_move = [self.slide_origin_x intValue] - recognizer.view.center.x;
        if (touch_move > (0 + to_launch_action)) {
            /*
             * What happens if the view slide to the left (eg : go_to_next)
             */
        } else if (touch_move < (0 - to_launch_action)) {
            /*
             * What happens if the view slide to the right (eg : go_to_previous)
             */
        }
        // The view goes back to normal
        recognizer.view.center = CGPointMake([self.slide_origin_x intValue], recognizer.view.center.y);
    }

    // The view is moved
    else {
        CGPoint translation = [recognizer translationInView:self.view];
        recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
                                             recognizer.view.center.y);
        [recognizer setTranslation:CGPointMake(0,0) inView:self.view];
    }
}

FYI : This works also on XCode5 and SDK6.1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top