Swipe gestures in Multiview App
I am quite new to iOS development and trying hard to develop an App. I am unable to use swipe gestures in a multiview app. I am pasting the code, can you guys please point out the error. It's a view based application.
Here is mainViewController.h
#import <UIKit/UIKit.h>
@interface mainViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
NSArray *listData;
}
@property (nonatomic, retain) NSArray *listData;
@end
Now mainViewController.m
#import "mainViewController.h"
@implementation mainViewController
@synthesize listData;
- (void)viewDidLoad {
NSArray *array =[[NSArray alloc] initWithObjects:@"Apple",@"Boy",@"Cat", nil];
self.listData = array;
[array release];
[super viewDidLoad];
}
- (void)dealloc
{
[listData release];
[super dealloc];
}
#pragma mark - View lifecycle
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SimpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
//cell.textLabel.font = [UIFont boldSystemFontOfSize:50];
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
NSString *rowValue = [listData objectAtIndex:row];
if([rowValue isEqualToString:@"Apple"])
{
cell.backgroundColor开发者_运维百科 = [UIColor redColor];
}
else
if([rowValue isEqualToString:@"Boy"])
cell.backgroundColor= [UIColor yellowColor];
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
NSString *rowValue = [listData objectAtIndex:row];
if([rowValue isEqualToString:@"Apple"])
{
mainViewController* flashView=[[mainViewController alloc] initWithNibName:@"fl" bundle:[NSBundle mainBundle]];
[self.view addSubview:flashView.view];
}
//[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.listData=nil;
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 110;
}
@end
I have added an UIViewSubController class with the xib file named "fl".
In fl.h:
#define kMinimumLength 5
#define kMaxVariance 1
#import <UIKit/UIKit.h>
#import "mainViewController.h"
@protocol flDelegate;
@interface fl : UIViewController <UIGestureRecognizerDelegate>
{
CGPoint gestureStartPoint;
id <flDelegate> delegate;
}
@property CGPoint gestureStartPoint;
@property (nonatomic,retain) id <flDelegate> delegate;
@end
@protocol flDelegate
-(IBAction)flDidFinish:(fl *)controller;
@end
And now in fl.m:
#import "fl.h"
@implementation fl
@synthesize delegate;
@synthesize gestureStartPoint;
- (void)dealloc
{
[super dealloc];
}
#pragma mark - View lifecycle
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch =[touches anyObject];
gestureStartPoint =[touch locationInView:self.view];
}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch =[touches anyObject];
CGPoint CurrentPosition =[touch locationInView:self.view];
if(CurrentPosition.x >= kMinimumLength)
{
NSLog(@"Go");
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
Here everything is working, but it is not detecting swipes, and not printing Go.
I also suggest taking a look at UISwipeGestureRecognizer, but if you prefer staying with your current design, this is the code that I am using elsewhere to detect swipes and pinch (zoom). You will need to adapt it to your case (you have three methods instead of three branches).
if (touch.phase == UITouchPhaseBegan) {
// NSLog(@"TOUCH BEGAN");
_initialView = touchView;
startTouchPosition1 = [touch locationInView:self];
startTouchTime = touch.timestamp;
if ([allTouches count] > 1) {
startTouchPosition2 = [[[allTouches allObjects] objectAtIndex:1] locationInView:self];
previousTouchPosition1 = startTouchPosition1;
previousTouchPosition2 = startTouchPosition2;
}
}
if (touch.phase == UITouchPhaseMoved) {
// NSLog(@"TOUCH MOVED");
if ([allTouches count] > 1) {
CGPoint currentTouchPosition1 = [[[allTouches allObjects] objectAtIndex:0] locationInView:self];
CGPoint currentTouchPosition2 = [[[allTouches allObjects] objectAtIndex:1] locationInView:self];
CGFloat currentFingerDistance = CGPointDist(currentTouchPosition1, currentTouchPosition2);
CGFloat previousFingerDistance = CGPointDist(previousTouchPosition1, previousTouchPosition2);
if (fabs(currentFingerDistance - previousFingerDistance) > ZOOM_DRAG_MIN) {
NSNumber* movedDistance = [NSNumber numberWithFloat:currentFingerDistance - previousFingerDistance];
if (currentFingerDistance > previousFingerDistance) {
NSLog(@"zoom in");
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ZOOM_IN object:movedDistance];
} else {
NSLog(@"zoom out");
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_ZOOM_OUT object:movedDistance];
}
}
}
}
if (touch.phase == UITouchPhaseEnded) {
CGPoint currentTouchPosition = [touch locationInView:self];
// Check if it's a swipe
if (fabsf(startTouchPosition1.x - currentTouchPosition.x) >= SWIPE_DRAG_HORIZ_MIN &&
// fabsf(startTouchPosition1.y - currentTouchPosition.y) <= SWIPE_DRAG_VERT_MAX &&
fabsf(startTouchPosition1.x - currentTouchPosition.x) > fabsf(startTouchPosition1.y - currentTouchPosition.y) &&
touch.timestamp - startTouchTime < 0.7
) {
// It appears to be a swipe.
if (startTouchPosition1.x < currentTouchPosition.x) {
NSLog(@"swipe right");
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SWIPE_RIGHT object:touch];
} else {
NSLog(@"swipe left");
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_SWIPE_LEFT object:touch];
}
}
startTouchPosition1 = CGPointMake(-1, -1);
_initialView = nil;
}
EDIT: about your code...
you are not doing a proper swipe detection. indeed, take this line:
if(CurrentPosition.x >= kMinimumLength)
you are comparing a position (CurrentPosition.x) with a distance (kMinimumLength). This is not really meaningful. What you need saving the last touch position and then calculate the distance between the last touch and the current touch and compare this distance to kMinimumLenght.
The reason why I posted the sample code is that, by inspecting a working implementation you can understand what needs to be done in order to detect a swipe.
You should definitely take a look at UISwipeGestureRecognizers.
精彩评论