views:

7809

answers:

4

I have a custom UIView that generates a set of subviews and display them in rows and columns like tiles. What I am trying to achieve is to allow the user to touch the screen and as the finger move, the tiles beneath it disappears.

The code below is the custom UIView that contains the tiles:

- (id)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {
     int i, j;
     int maxCol = floor(self.frame.size.width/TILE_SPACING);
     int maxRow = floor(self.frame.size.height/TILE_SPACING);

     CGRect frame = CGRectMake(0, 0, TILE_WIDTH, TILE_HEIGHT);
     UIView *tile;  

     for (i = 0; i<maxCol; i++) {
      for (j = 0; j < maxRow; j++) {
       frame.origin.x =  i * (TILE_SPACING) + TILE_PADDING;
       frame.origin.y =  j * (TILE_SPACING) + TILE_PADDING;
       tile = [[UIView alloc] initWithFrame:frame];

       [self addSubview:tile];
       [tile release]; 
      }
     }

    }
    return self;
}


- (void)touchesBegan: (NSSet *)touches withEvent:(UIEvent *)event {
    UIView *tile = [self hitTest:[[touches anyObject] locationInView:self] withEvent:nil];

    if (tile != self)
     [tile setHidden:YES];
}



- (void)touchesMoved: (NSSet *)touches withEvent:(UIEvent *)event {
    UIView *tile = [self hitTest:[[touches anyObject] locationInView:self] withEvent:nil];

    if (tile != self)
     [tile setHidden:YES];
}

This approach works but however if the tiles get denser (i.e. small tiles and more tiles on the screen). The iPhone is less responsive as the finger move. It may be the hitTest taking a toll on the processor as it struggles to keep up but would like some opinions.

My questions are:

  1. Is this an efficient way / right way to implement the touchesMoved?

  2. If it isn't, what would be the recommended approach?

  3. I tried moving the functionality into a custom Tile class (a sub UIView) which the class above would create and add as a subview. This subview Tile can handle the TouchesBegan but as the finger move, the other tiles does not receive the TouchesBegan even since the touches are still part of the initial touch sequence. Is there a way to implement it through the subview Tile class, how do other tiles receive the TouchesBegan/TouchesMoved event as the finger move?

+6  A: 
Ben Gottlieb
Thanks for the feedback on this. If I were to shift the event handling to the custom Tile subview, how would the underlying tiles be notified when the finger move across them? The touches would still 'belong' to the initial touch sequence for the first tile.
Ronnie Liew
The way described above, all touches are handled by the parent view. I usually find that simpler than trying to bounce touches around from sibling-to-sibling.You'd have to experiment with touchesMoved messages to find out exactly how they'll behave as the target view changes.
Ben Gottlieb
A: 

Just an idea that may help... I have not tested this, but, after detecting the tap on a particular imageview turn off userInteractionEnabled of the all other imageviews...

I suppose this will help increase a little bit the speed, as iPhone will not last resources trying to find which image is being tapped during a drag. The same is true for multitouch.

Digital Robot
+1  A: 

one addition, instead of hit testing, you can just check if the point lies in the CGRect that represents the frame of each subview. I have a similar app, and this worked best for me.

for (UIView* aSubview in self.subviews) {

    if([aSubview pointInside: [self convertPoint:touchPoint toView:aSubview] withEvent:event]){

       //Do stuff
    }
}
Corey Floyd
A: 

too bad I cannnot vote. Corey++ saved the night, thanks this is working perfectly.

Proclus