1
votes

I need to do something like this:

UISCrollView with UIImageViews as its subviews. When user taps on UIImageViews an action occurs. But when user want to scroll UIScrollView should scroll even if scrolling started at UIImageView (at location where UIImage of UIImageView is displayed).

Basicly I can get one of two scenarios:

  1. I can get that if user taps on UIImageView (which is subview of UIScrollView) an action occur, but when you try to scroll by draging finger from UIImageView the action also occurs (and I want a scroll to occur).

  2. I can make that regardles where user taps the view will scroll but if user taps UIImageView the action will NOT occur.

I can't get you any of my code because I'm testing a lot of aprroches here and there and it's bit messy so it would be no use at all (without a tons of commenting).

Is there a clean and simple solution for doing this?

Ok here is some code:

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event
{


if(isDragging == NO)
{


    return [super hitTest:point withEvent:event];
}
NSLog(@"dragging ><><><><><>>><><><><>");
        return nil;

}

Now if I return nil then I can scroll but I can't get to tap my UIImageView for an action. If I return [super hitTest:point withEvent:event] I can't scroll over my UIIMageView.

isDragging is test code to determine if I'm trying to scroll or just tap. But hit test occurs before I can set isDragging property accordingly to event that is happening.

Here is my init

-(id) initWithCoder:(NSCoder *)aDecoder
{

if(self = [super initWithCoder:aDecoder])
{
    [self setUserInteractionEnabled:YES];
    UISwipeGestureRecognizer *swipeRecLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
    swipeRecLeft.direction = UISwipeGestureRecognizerDirectionDown;

    UISwipeGestureRecognizer *swipeRecRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
    swipeRecRight.direction = UISwipeGestureRecognizerDirectionUp;

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapSingle)];    

    [self addGestureRecognizer:swipeRecRight]; 
    [self addGestureRecognizer:swipeRecLeft];
    [self addGestureRecognizer:singleTap];


    [swipeRecLeft release]; 
    [swipeRecRight release]; 
    [singleTap release];

    isDragging = NO;
}
else {
    self = nil;
}

return self;

}

Here are the rest of actions

-(void) tapSingle

{ [self.delegate hitOccur]; }

-(void) swipe
{
    isDragging = YES;
}

And on top of it in my UIScrollView I've setted delegate and when scrolling ends I set isDragging property manualy to NO on each subview of my UIScrollView.

It's working... but it's not perfect. To actually scroll content I must swipe TWICE in UIImageView (first one is to set isDragging to YES and then we can scroll...). How to this right and proper?

LATEST UPDATE:

Ok I've managed to solve this problem. However I'm dead sure my way isn't clean or good one (but regardles it works).

In my UIScrollView subclass I've overided hitTest method with this:

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

    if(!self.dragging)
    {
        if([[super hitTest:point withEvent:event] class] == [ResponsiveBookView class])
        {
            container = [super hitTest:point withEvent:event];
        }
    }
    return self;

}

Where the container is id container and it holds my UIView subclass. So I can recognize if the touch was on my image or on scroll view itself. Now I need to detec if it is scrolling or just touching and I do this here:

-(void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event 
{   

    if (!self.dragging) {
        NSLog(@"touch touch touch");
        [container tapSingle];
        [self.nextResponder touchesEnded: touches withEvent:event]; 
    }       


    [super touchesEnded: touches withEvent: event];
}

As you see if self.dragging (scrolling) the default behaviour will apply. If !self.dragging I will manually call tapSingle on my container (which will then make an action "occur"). It works!

1

1 Answers

0
votes

Yeah—use gesture recognizers. If you add a UITapGestureRecognizer to each UIImageView (using the UIVIew -addGestureRecognizer: method), you should get both recognition of the taps and the default scrolling behavior.