Note that there are some explanatory texts on larger screens.

plurals
  1. POUIScrollView touches vs subview touches
    primarykey
    data
    text
    <p>Please can someone help sort a noob out? I've posted this problem on various forums and received no answers, while many searches for other answers have turned up stackOverflow, so I'm hoping this is the place. </p> <p>I've got a BeachView.h (subclass of UIScrollView, picture of a sandy beach) covered with a random number of Stone.h (subclass of UIImageView, a random PNG of a stone, userInteractionEnabled = YES to accept touches).</p> <p>If the user touches and moves on the beach, it should scroll. If the user taps a stone, it should call method "touchedStone". If the user taps the beach where there is no stone, it should call method "touchedBeach".</p> <p>Now, I realize this sounds dead simple. Everyone and everything tells me that if there's something on a UIScrollView that accepts touches that it should pass control on to it. So when I touch and drag, it should scroll; but if I tap, and it's on a stone, it should ignore beach taps and accept stone taps, yes?</p> <p>However, it seems that both views are accepting the tap and calling both touchedStone AND touchedBeach. Furthermore, the beach tap occurs first, so I can't even put in a "if touchedStone then don't run touchedBeach" type flag.</p> <p>Here's some code. On BeachView.m</p> <pre><code> - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (self.decelerating) { didScroll = YES; } else { didScroll = NO; } UITouch *touch = [[event allTouches] anyObject]; CGPoint touchLocation = [touch locationInView:touch.view]; NSLog(@"touched beach = %@", [touch view]); lastTouch = touchLocation; [super touchesBegan:touches withEvent:event]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { didScroll = YES; [super touchesMoved:touches withEvent:event]; } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { if (didScroll == NO && isPaused == NO) { [self touchedBeach:YES location:lastTouch]; } [super touchesEnded:touches withEvent:event]; } </code></pre> <p>On Stone.m</p> <pre><code> -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [parent stoneWasTouched]; // parent = ivar pointing from stone to beachview } -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; CGPoint touchLocation = [touch locationInView:touch.view]; NSLog(@"touched stone = %@", [touch view]); [parent touchedStone:YES location:touchLocation]; } </code></pre> <p>After a stone tap, My NSLog looks like this:</p> <pre><code> Touched beach = &lt;BeachView: 0x1276a0&gt; ran touchedBeach Touched Stone = &lt;Stone: 0x1480c0&gt; ran touchedStone </code></pre> <p>So it's actually running both. What's even stranger is if I take the touchesBegan and touchesEnded out of Stone.m but leave userInteractionEnabled = YES, the beachView registers both touches itself, but returns the Stone as the view it touched (the second time).</p> <pre><code> Touched beach = &lt;BeachView: 0x1276a0&gt; ran touchedBeach Touched beach = &lt;Stone: 0x1480c0&gt; ran touchedBeach </code></pre> <p>So PLEASE, I've been trying to sort this for days. How do I make it so a tapped stone calls only touchedStone and a tapped beach calls only touchedBeach? Where am I going wrong?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload