Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

lutius

macrumors newbie
Original poster
Jul 28, 2008
2
0
Hi,

I have the following setup:

A UITableView which list summary information about items.
When you select an item, you switch to another UITableView, which contains Detail Information about the selected item. The detail information is presented as a List too (UITableView).

Now, say I select item No. 3 in the summary list, i'll switch to the detail view and show detail information about that No. 3 item.

What I'd like now in this Detail UITableView is to be able to:

a) use normal vertical scrolling (just normal behaviour of a UITableView)
b) Here's the tricky part: detect horizontal scrolling (swipes) within the UITableView to switch to the previous/next item Detail, eg. right-swipe = show Item No. 2 Detail, left swipe = show No. 4 Detail.

I have written a custom UITableView and implemented

Code:
#define HORIZ_SWIPE_DRAG_MIN  12 
#define VERT_SWIPE_DRAG_MAX    4 
  
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    startTouchPosition = [touch locationInView:self]; 
} 
  
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = touches.anyObject; 
    CGPoint currentTouchPosition = [touch locationInView:self]; 
  
    // If the swipe tracks correctly. 
    if (fabsf(startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN && 
        fabsf(startTouchPosition.y - currentTouchPosition.y) <= VERT_SWIPE_DRAG_MAX) 
    { 
        // It appears to be a swipe. 
        if (startTouchPosition.x < currentTouchPosition.x) 
            [self myProcessRightSwipe:touches withEvent:event]; 
        else 
            [self myProcessLeftSwipe:touches withEvent:event]; 
    } 
    else 
    { 
        // default handling
        [super touchesMoved:touches withEvent:event];
    } 
}

Now, this implementation seemed to work at first, but the problem is that when i do a vertical scroll to the bottom of the table, everything is fine, but as soon as i retouch the display, say to scroll up a bit, it jumps back to the top of the table.

Any idea ?
 
Never mind, I ended up with this, which apparently works well.
-------------
Code:
#define HORIZ_SWIPE_DRAG_MIN  100

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	
    UITouch *touch = [touches anyObject];
	CGPoint newTouchPosition = [touch locationInView:self];
	if(mystartTouchPosition.x != newTouchPosition.x || mystartTouchPosition.y != newTouchPosition.y) {
		isProcessingListMove = NO;
	}
	mystartTouchPosition = [touch locationInView:self];
	[super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = touches.anyObject;
    CGPoint currentTouchPosition = [touch locationInView:self];
	
    // If the swipe tracks correctly.
	double diffx = mystartTouchPosition.x - currentTouchPosition.x + 0.1;  // adding 0.1 to avoid division by zero
	double diffy = mystartTouchPosition.y - currentTouchPosition.y + 0.1; // adding 0.1 to avoid division by zero
    
    if(abs(diffx / diffy) > 1 && abs(diffx) > HORIZ_SWIPE_DRAG_MIN)
	{
        // It appears to be a swipe.
		if(isProcessingListMove) {
			// ignore move, we're currently processing the swipe
			return;
		}
		
        if (mystartTouchPosition.x < currentTouchPosition.x) {
			isProcessingListMove = YES;
			[detailController moveToPreviousItem];
			return;
		}
        else {
			isProcessingListMove = YES;
			[detailController moveToNextItem];
			return;
		}
    }
	else if(abs(diffy / diffx) > 1)
	{
		isProcessingListMove = YES;
		[super touchesMoved:touches	withEvent:event];
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	isProcessingListMove = NO;
	[super touchesEnded:touches withEvent:event];
}
 
Never mind, I ended up with this, which apparently works well.
-------------

#define HORIZ_SWIPE_DRAG_MIN 100

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
.....................

Lutius You are the Man! Thank you! I had to change it a little

Code:
#define HORIZ_SWIPE_DRAG_MIN 100
CGPoint mystartTouchPosition;
BOOL isProcessingListMove;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	UITouch *touch = [touches anyObject];
	CGPoint newTouchPosition = [touch locationInView:self.view];
	if(mystartTouchPosition.x != newTouchPosition.x || mystartTouchPosition.y != newTouchPosition.y) {
		isProcessingListMove = NO;
	}
	mystartTouchPosition = [touch locationInView:self.view];
	[super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{
	UITouch *touch = touches.anyObject;
	CGPoint currentTouchPosition = [touch locationInView:self.view];
	
	// If the swipe tracks correctly.
	double diffx = mystartTouchPosition.x - currentTouchPosition.x + 0.1; // adding 0.1 to avoid division by zero
	double diffy = mystartTouchPosition.y - currentTouchPosition.y + 0.1; // adding 0.1 to avoid division by zero
	
	if(abs(diffx / diffy) > 1 && abs(diffx) > HORIZ_SWIPE_DRAG_MIN)
	{
		// It appears to be a swipe.
		if(isProcessingListMove) {
			// ignore move, we're currently processing the swipe
			return;
		}
		
		if (mystartTouchPosition.x < currentTouchPosition.x) {
			isProcessingListMove = YES;
			[self moveToPreviousItem];
			return;
		}
		else {
			isProcessingListMove = YES;
			[self moveToNextItem];
			return;
		}
	}
	else if(abs(diffy / diffx) > 1)
	{
		isProcessingListMove = YES;
		[super touchesMoved:touches	withEvent:event];
	}
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{
	isProcessingListMove = NO;
	[super touchesEnded:touches withEvent:event];
}

Code:
-(void)moveToPreviousItem{
	NSLog(@"Move To Previous Item");
}
-(void)moveToNextItem{
	NSLog(@"Move To Next Item");
}

Hint: use the CODE tags[]
 
iOS 3.2 and above include UIGestureRecognizer, and notably, UISwipeGestureRecognizer.
 
@all - My UI is a scrollable tableview which i wanna swipe to next or previous pages. When I tried the above, the swiping action works only outside the tableview, at the borders of the screen. Could u suggest any changes so that I could apply for swipes anywhere on the screen?

Thanks,
Shruthi
 
Its the UITableView's fault

The reason why this trick works only outside of the tableview is because tableview (which is a subclass of UIScrollView) overtakes the swipe handling.

The simplest solution might be to customize (i.e. extends) UITableView to handle the gesture.
(see: http://www.iphonedevsdk.com/forum/i...-how-detect-touch-table-view-header-view.html)

However, it is unusual if you swipe across a tableview (or a cell) to change the screen.
Standard behavior when you swipe across a cell is to delete the cell.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.