Search code examples
xcodeuiviewuiscrollviewtouchesmoved

touchesMoved no longer triggers after changing UIView to UIScrollView?


I had a UIView with lots of objects. I also had an implementation of touchesMoved like this:

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

I recently wanted the view to scroll, so I simply opened up the UIView, and in Interface Builder changed its object class to UIScrollView. However, now the 'touchesMoved' method is never called even when I touch the screen.

Can someone please help me get touchesMoved working again? I'm not sure what I did to break it!

EDIT: I tried following this guide but I might've done something wrong. From reading other posts it seems like UIScrollView can't accept touch events itself, and they need to be sent up the responder chain? I will be extremely grateful for anyone who can help guide me through this problem... my app was just about ready for submission when I realized the UIScrolView killed my touch detection! (I just changed my apps UIView to UIScrollView to allow compatibility with iPhone 4).


Solution

  • I just took a look at the guide in your edit, and I think I can see the problem. See this answer on a similar question.

    Your UIScrollView subclass will look something like this:

    #import "AppScrollView.h"
    
    @implementation AppScrollView
    
    - (id)initWithFrame:(CGRect)frame
    {
        return [super initWithFrame:frame];
    }
    
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"AppScrollView touchesEnded:withEvent:");
    
        // If not dragging, send event to next responder
        if (!self.dragging)
            [[self.nextResponder nextResponder] touchesEnded:touches withEvent:event];
        else
            [super touchesEnded: touches withEvent: event];
    
    }
    
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"AppScrollView touchesMoved:withEvent:");
    
        [[self.nextResponder nextResponder] touchesMoved:touches withEvent:event];
    }
    
    @end
    

    And your class that includes the AppScrollView object should adopt the UIScrollViewDelegate protocol and implement these methods:

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

    Then the logged output will look like this:

    2013-06-11 10:45:21.625 Test[54090:c07] AppScrollView touchesMoved:withEvent:
    2013-06-11 10:45:21.625 Test[54090:c07] SomeClass touchesMoved:withEvent:
    2013-06-11 10:45:21.642 Test[54090:c07] AppScrollView touchesMoved:withEvent:
    2013-06-11 10:45:21.642 Test[54090:c07] SomeClass touchesMoved:withEvent:
    2013-06-11 10:45:21.655 Test[54090:c07] AppScrollView touchesEnded:withEvent:
    2013-06-11 10:45:21.656 Test[54090:c07] SomeClass touchesEnded:withEvent: