Ok so I am helping convert an android game to iOS. The game is based on 2048, but with letters instead of numbers. I have a good bit of it working but am still learning Objective C/iOS quirks. So far I have the tiles/grid working, movement is working, etc but I need a bit of help. The goal is to allow the user to long-press on a tile to select it, then slide their finger to an adjacent tile to begin spelling a word. I have the long press portion implemented but I'm at a bit of a loss on how to get it to long-press then swipe. On top of this I already have a swipe that allows the user to move the tiles. In searching on here I've seen suggestions about subclassing so I am figuring I need to subclass the UISwipeGestureRecognizer method. I already put in the simultaneously gesture recognizer, but am unsure where to go from here.
So, there are several questions to this.
What would be the best way to do this? Implement a subclass of each UISwipeGestureRecognizer?
Will my current swipe detection interfere? (right now a swipe by itself moves tiles in direction of swipe)
I would guess I need to do a (if long press) then activate subclassed swipe methods?
Any examples to answer the above questions would be of great help. I'm not asking you to do it for me but at least point me in a general direction. Thanks!
Code below.
// Grid.m
#import "Grid.h"
#import "Tile.h"
- (void)didLoadFromCCB {
// listen for swipes to the left
UISwipeGestureRecognizer * swipeLeft= [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(swipeLeft)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[[[CCDirector sharedDirector] view] addGestureRecognizer:swipeLeft];
// listen for swipes to the right
UISwipeGestureRecognizer * swipeRight= [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(swipeRight)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[[[CCDirector sharedDirector] view] addGestureRecognizer:swipeRight];
// listen for swipes up
UISwipeGestureRecognizer * swipeUp= [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(swipeUp)];
swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[[[CCDirector sharedDirector] view] addGestureRecognizer:swipeUp];
// listen for swipes down
UISwipeGestureRecognizer * swipeDown= [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(swipeDown)];
swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
[[[CCDirector sharedDirector] view] addGestureRecognizer:swipeDown];
// listen for long press
UILongPressGestureRecognizer *longpress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(onLongPress:)];
[longpress setMinimumPressDuration:0.5];
[[[CCDirector sharedDirector] view] addGestureRecognizer:longpress];
}
- (void)swipeLeft {
[self move:ccp(-1, 0)];
}
- (void)swipeRight {
[self move:ccp(1, 0)];
}
- (void)swipeDown {
[self move:ccp(0, -1)];
}
- (void)swipeUp {
[self move:ccp(0, 1)];
}
// detect longpress, convert to NodeSpace and check if touch location is within tile boundingbox. If yes, set background white, text black.
- (void)onLongPress:(UILongPressGestureRecognizer *) recognizer {
CGPoint touchPoint = [[CCDirector sharedDirector] convertToGL:[recognizer locationInView:[recognizer view]]];
touchPoint = [self convertToNodeSpace:touchPoint];
if (recognizer.state == UIGestureRecognizerStateBegan) {
for (Tile *tile in self.children) {
if([tile isKindOfClass:[Tile class]]) {
CGRect tileBoundingBox = tile.boundingBox;
if (CGRectContainsPoint(tileBoundingBox, touchPoint)) {
tile.backgroundNode.color = [CCColor whiteColor];
tile.valueLabel.color = [CCColor blackColor];
[self spellWord:tile.value];
[_word setString:[_word lowercaseString]];
CCLOG(#"%#", _word);
}
}
}
}
if (recognizer.state == UIGestureRecognizerStateChanged) {
}
if (recognizer.state == UIGestureRecognizerStateEnded) {
for (Tile *tile in self.children) {
if([tile isKindOfClass:[Tile class]]) {
CGRect tileBoundingBox = tile.boundingBox;
if (CGRectContainsPoint(tileBoundingBox, touchPoint)) {
tile.backgroundNode.color = [tile getColor:tile.value];
tile.valueLabel.color = [self getContrastColor:r green:g blue:b];
}
}
}
}
}
// allow for simultaneous gestures
- (BOOL)gestureRecognizer:(UIGestureRecognizer *) recognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
In answer to your questions:
This doesn't strike me as a coding situation that requires one to subclass UILongPressGestureRecognizer. Having said that, subclassing is often a nice way to clean up one's view controller code so you don't have gory gesture recognizer code in the view controller class. But there's nothing here (as I understand it) that demands that. You generally dive into subclassing of gesture recognizers where you need some special custom behavior (e.g. have the gesture fail if some complicated criterion fails). I'd first see if you could achieve the desired UX with standard gestures before I went down that road, though.
The only reason I could see the swipe gestures interfering with each other is that you've specified that shouldRecognizeSimultaneouslyWithGestureRecognizer should return YES. That's used in cases where you need multiple recognizers running at the same, which doesn't seem necessary here (and only a source of problems).
It's unclear to me as to whether you really wanted a separate swipe gesture or whether you just wanted a single gesture ("long press and drag"). If you needed that separate swipe gesture, though, you would generally specify the relative priority of gesture recognizers by specifying requireGestureRecognizerToFail (e.g. have the swipe require long press to fail in order for the swipe to be recognized). But if you really only have one gesture ("long press and drag"), then only one gesture recognizer is needed.
It seems unnecessary. If you want to detect movement after the long press has been recognized, you can put that "move after long press" code in the if statement for UIGestureRecognizedStateChanged in your onLongPress, which occurs after the long press has been recognized, but before the user lifts their finger. The UILongPressGestureRecognizer is a continuous gesture recognizer which will continue to get updates as the user's finger moves after the gesture was initially recognized.
I know you didn't ask for code, but if you wanted a swipe gesture, as well as a long press gesture that was, essentially, the idea of picking it up and dragging it, you could do something like the following. Note, I make the swipe gesture require the long press to fail, so if the user is long pressing, that takes precedence, otherwise it does swipe. But you may not need the swipe gesture at all, so if you don't need it, just remove it altogether:
#import <UIKit/UIGestureRecognizerSubclass.h>
- (void)viewDidLoad {
[super viewDidLoad];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[self.view addGestureRecognizer:longPress];
// if you needed a second gesture, a swipe, completely distinct from the long press and drag
// gesture, you could add it like so:
//
// UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
// [swipe requireGestureRecognizerToFail:longPress];
// // do additional swipe configuration
// [self.view addGestureRecognizer:swipe];
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)gesture
{
// do your separate swipe stuff here
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
static UIView *tileToMove;
static CGPoint startCenter;
static CGPoint startLocation;
CGPoint location = [gesture locationInView:self.view];
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
{
// find the tile
tileToMove = [self findTileToMove:location];
if (tileToMove) {
// if found, capture state ...
startCenter = tileToMove.center;
startLocation = location;
// ... and animate "pick up tile", so the user gets positive feedback
// that the drag/swipe portion of the gesture is starting.
[UIView animateWithDuration:0.25 animations:^{
tileToMove.transform = CGAffineTransformMakeScale(1.2, 1.2);
}];
} else {
gesture.state = UIGestureRecognizerStateFailed;
}
break;
}
case UIGestureRecognizerStateChanged:
{
// move the tile as the user's finger moves
CGPoint translate = CGPointMake(location.x - startLocation.x, location.y - startLocation.y);
// note, if you want to constrain the translation to be, for example, on the
// x-axis alone, you could do something like:
//
// CGPoint translate = CGPointMake(location.x - startLocation.x, 0);
tileToMove.center = CGPointMake(startCenter.x + translate.x, startCenter.y + translate.y);
break;
}
case UIGestureRecognizerStateEnded:
{
// animate "drop the tile"
[UIView animateWithDuration:0.25 animations:^{
tileToMove.transform = CGAffineTransformIdentity;
// if you want the tile to "snap" to some location having let it go,
// set the `center` or `frame` here.
}];
// clear our variables, just in case
tileToMove = nil;
startCenter = CGPointZero;
startLocation = CGPointZero;
break;
}
default:
break;
}
}
- (UIView *)findTileToMove:(CGPoint)location
{
for (UIView *tile in self.tiles) {
if (CGRectContainsPoint(tile.frame, location)) {
return tile;
}
}
return nil;
}
This might not be quite the exact UI you're looking for, but it illustrates:
How to have two gestures, where one requires the other to fail in order to establish a precedence between the gestures (and clearly only an issue if you want two distinct gestures, which you probably don't);
To not have shouldRecognizeSimultaneouslyWithGestureRecognizer method because I don't want them both to be recognized simultaneously. Note, that's only needed if you really need two gestures, which you may or may not need; and
How to have a long press that not only recognizes initial long press, but subsequent swipe/drag movement, too.
Related
I'm working on a GLKViewController based game which interprets taps and swipes as game controls. I want to support two-player mode by letting the first player tap or swipe on the left side of the screen, and letting the second player tap or swipe on the right side of the screen. In a perfect world, I'd like the gesture recognizers to work even if the swipes are sloppy and go past the centerline of the screen (with the starting point of the swipe being used to determine which player gets the input).
What would be the best way to implement this? Can I lay down a gesture recognizer on the left half of the screen, and another one on the right side of the screen? Will two separate recognizers work properly together even if both sides are being tapped/swiped rapidly at the same time? Or should I create a full-screen recognizer and parse the swipes and taps entirely on my own? I don't have experience with gesture recognizers so I don't know what the preferred approach is or how well they work when you have more than one being swiped on simultaneously.
I ended up making two UIViews overlaid on top of my GLKView, one on the left side of the screen and one on the right. Each view has a UIPanGestureRecognizer and a UILongPressGestureRecognizer (the long-press recognizer is basically a more flexible tap—I needed to use it to reject some gestures from being interpreted both as a pan and a tap at the same time). This worked magnificantly.
- (void)viewDidLoad
{
[super viewDidLoad];
// Add tap and pan gesture recognizers to handle game input.
{
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSidePan:)];
panRecognizer.delegate = self;
[self.leftSideView addGestureRecognizer:panRecognizer];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLeftSideLongPress:)];
longPressRecognizer.delegate = self;
longPressRecognizer.minimumPressDuration = 0.0;
[self.leftSideView addGestureRecognizer:longPressRecognizer];
}
{
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleRightSidePan:)];
panRecognizer.delegate = self;
[self.rightSideView addGestureRecognizer:panRecognizer];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleRightSideLongPress:)];
longPressRecognizer.delegate = self;
longPressRecognizer.minimumPressDuration = 0.0;
[self.rightSideView addGestureRecognizer:longPressRecognizer];
}
}
- (void)handleLeftSidePan:(UIPanGestureRecognizer *)panRecognizer
{
[self handleGameScreenPan:panRecognizer withVirtualController:&g_iPadVirtualController[0]];
}
- (void)handleRightSidePan:(UIPanGestureRecognizer *)panRecognizer
{
[self handleGameScreenPan:panRecognizer withVirtualController:&g_iPadVirtualController[1]];
}
- (void)handleLeftSideLongPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
[self handleGameScreenLongPress:longPressRecognizer withVirtualController:&g_iPadVirtualController[0]];
}
- (void)handleRightSideLongPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
[self handleGameScreenLongPress:longPressRecognizer withVirtualController:&g_iPadVirtualController[1]];
}
This question already has answers here:
UILongPressGestureRecognizer gets called twice when pressing down
(7 answers)
Closed 7 years ago.
I'm confused about LongPressGestureRecognizer.I placed one of these on a scroll view,but it works two times.When I lift my finger,the methods added on it called again.I wonder it only called first time.What should I do?Any help will be appreciated, thanks.
first look what apple docs have to say about it:-
"Long-press gestures are continuous. The gesture begins (UIGestureRecognizerStateBegan) when the number of allowable fingers (numberOfTouchesRequired) have been pressed for the specified period (minimumPressDuration) and the touches do not move beyond the allowable range of movement (allowableMovement). The gesture recognizer transitions to the Change state whenever a finger moves, and it ends (UIGestureRecognizerStateEnded) when any of the fingers are lifted."
- (void)LongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateBegan){
NSLog(#"UIGestureRecognizerStateBegan.");
//in your case add your functionality over here
}
else if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(#"UIGestureRecognizerStateEnded");
//if you want to add some more functionality when gesture got ended.
}
}
UILongPressGestureRecognizer is not as same as UITapGestureRecognizer. It contains some states.
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height * 2);
[self.view addSubview:scrollView];
UILongPressGestureRecognizer *lpGes = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(lpHandler:)];
[scrollView addGestureRecognizer:lpGes];
}
- (void)lpHandler:(UILongPressGestureRecognizer *)lpGes
{
switch (lpGes.state) {
case UIGestureRecognizerStateBegan:
NSLog(#"UILongPressGestureRecognizer: began");
break;
case UIGestureRecognizerStateEnded:
NSLog(#"UILongPressGestureRecognizer: ended");
break;
default:
break;
}
}
For above codes, you will get 2 logs:
2015-08-28 12:22:39.084 aaaaa[50704:2339282] UILongPressGestureRecognizer: began
2015-08-28 12:22:40.687 aaaaa[50704:2339282] UILongPressGestureRecognizer: ended
I'd like to enable UIPanGestureRecognizer on customView when the customView did longPress.
(I wish when you longPress customView, the customView will switch to "move mode", and you can move the customView by drag.)
But in this code, only longPressAction: called. panAction: did not called.
How do I fix it to enable PanAction:?
- (void)viewDidLoad
{
[self.view addSubview:customView];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(longPressAction:)];
[customView addGestureRecognizer:longPressRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[customView addGestureRecognizer:panRecognizer];
}
- (void)longPressAction:(UILongPressGestureRecognizer *)recognizer
{
if ([recognizer state] == UIGestureRecognizerStateBegan) {
CustomView *customView = (CustomView *)recognizer.view;
customView.panRecongnizerEnabled = YES; //panRecongnizerEnabled is CustomView's property
}
if ([recognizer state] == UIGestureRecognizerStateEnded) {
CustomView *customView = (CustomView *)recognizer.view;
customView.panRecongnizerEnabled = NO;
}
}
- (void)panAction:(UIPanGestureRecognizer *)recognizer
{
CustomView *customView = (CustomView *)recognizer.view;
if (customCell.panRecongnizerEnabled == NO) return;
NSLog(#"running panAction");
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Your ViewController needs to conform to the UIGestureRecognizerDelegate. I suspect you either already did that or otherwise the shouldRecognizeSimultaneouslyWithGestureRecognizer would not make any sense. But what you are definitely missing is setting the gestureRecognizer´s delegate to your viewController:
longPressRecognizer.delegate = self;
panRecognizer.delegate = self;
Now you should be receiving both long press and pan simultaneous.
Note: I tested without any customView, just added them to self.view. At least in that case, the code above worked as expected.
I know this question has been closed for a while, but I recently had to do something similar, and there is a much cleaner solution. The UILongPressGestureRecognizer is all you need to do this.
Long-press gestures are continuous. The gesture begins
(UIGestureRecognizerStateBegan) when the number of allowable fingers
(numberOfTouchesRequired) have been pressed for the specified period
(minimumPressDuration) and the touches do not move beyond the
allowable range of movement (allowableMovement). The gesture
recognizer transitions to the Change state whenever a finger moves,
and it ends (UIGestureRecognizerStateEnded) when any of the fingers
are lifted.
Because of this, for what you need, there is no need for the UIPanGestureRecognizer. Simply add the UILongPressGestureRecognizer and attach it to your main view.
- (void)viewDidLoad {
[super viewDidLoad];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(longPressAction:)];
// set this to your desired delay before the pan action will start.
longPressRecognizer.minimumPressDuration = 0.5;
[self.view addGestureRecognizer:longPressRecognizer];
}
Then, implement the longPressAction method to look at not just UIGestureRecognizerStateBegan or UIGestureRecognizerStateEnded states, but also the UIGestureRecognizerStateChanged state:
- (void)longPressAction:(UIGestureRecognizer *)recognizer
{
if ([recognizer state] == UIGestureRecognizerStateBegan || [recognizer state] == UIGestureRecognizerStateChanged ) {
CGPoint touchPoint = [recognizer locationInView:self.view];
[self.viewToMove setCenter: touchPoint];
NSLog(#"running panAction");
}
}
In my example, I simply move a dummy view to track the center of the user's finger, but you can put any logic you would have put in the UIPanGestureRecognizer's code. Simply put it inside the if block and it greatly simplifies your code and you don't need to deal with interactions between the two gesture recognizers. Your code would also result in many needless calls to the panAction method when the user is simply moving their finger around the screen (but hasn't done a long press).
You can do it by enabling the pan after the long press. Anyhow you will have to save a flag to know if the longPress was called. And in order to enable the pan gesture after the longPress, you can play with the pan gesture delegate, as following:
let previewLongPress = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressed(sender:)))
let previewPanGesture = UIPanGestureRecognizer(target: self, action: #selector(onPanGesture(sender:)))
previewPanGesture?.delegate = self
Your delegate should seems like this:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return gestureRecognizer == previewPanGesture && otherGestureRecognizer == previewLongPress
}
And now you're able to have a pan gesture after a long press gesture.
Hope it helps other people.
I want to do smooth swipe animation. I just want to that swipe only can be possible when user swipe the page from the right or left border only. Middle of the page swipe should not possible.Both the swipe should be possible left to right and right to left.
I have tried lots of swipe animation sample code or demo code. But its not what I want. I want animation like this https://itunes.apple.com/in/app/clear-tasks-to-do-list/id493136154?mt=8
In this app its like when we touch the right border its swipe smoothly.Please guide me to do this animation. Thanks in advance.
Sorry for the late reply. Just saw this question.
If you want your swipe operation to happen from the edges, create 2 subviews in the far ends (left and right) of your main view and give then a width of 30 or 40.
I believe you have 2 other views popin up from left and right. So inorder to do this you need to add 2 views right on top of your main view.
Now for the left view, set it's right horizondal space constraint connecting to the main view to a value lesser than (-1)x width of the main view. For the right view set its right horizondal space constraint connecting to the main view to a value greater than the width of the main view, so that both the views are outside the main view
X stands for a value greater than or equal to the mainview's width
Add two NSLayoutConstraint variables as IBOutlet holding these 2 values.
NSLayoutConstraint *leftViewHorizondalRightPadding;
NSLayoutConstraint *rightViewHorizondalRightPadding;
Now add the UISwipeGestures to these subViews (indicated in orange).
UISwipeGestureRecognizer *leftToRightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
[leftToRightSwipe setDirection:UISwipeGestureRecognizerDirectionRight];
[self.leftSubview addGestureRecognizer:leftToRightSwipe];
UISwipeGestureRecognizer *rightToLeftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
[rightToLeftSwipe setDirection:UISwipeGestureRecognizerDirectionLeft];
[self.rightSubview addGestureRecognizer:rightToLeftSwipe];
///Now in the swipe handler distinguish the swipe actions
-(void)handleSwipe:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"Swipe received.");
if (recognizer.direction == UISwipeGestureRecognizerDirectionRight) {
//It's leftToRight
leftViewHorizondalRightPadding.constant = 0;
[UIView animateWithDuration:1
animations:^{
[self.view layoutIfNeeded];
}];
}
else {
//It's rightToLeft
rightViewHorizondalRightPadding.constant = 0;
[UIView animateWithDuration:1
animations:^{
[self.view layoutIfNeeded];
}];
}
}
}
This will make a swipe animation from left to right and right to left.
Hope this helps..
After you create the 2 swipe gesture recognisers you should set their delegates. Then use this delegate method:
UISwipeGestureRecognizer *_swipeLeft;
UISwipeGestureRecognizer *_swipeRight;
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
static const CGFloat borderWidth = 50.0f;
if(gestureRecognizer == _swipeLeft) {
return [gestureRecognizer locationInView:self].x > self.frame.size.width - borderWidth;
}
else if(gestureRecognizer == _swipeRight) {
return [gestureRecognizer locationInView:self].x < borderWidth;
}
return YES;
}
Do note that for smooth swiping/dragging you will probably need to use a pan gesture or even long press gesture recogniser rather then the swipe gesture. They are very similar except the long press takes a bit of time to begin (which is settable). If you use them you may still want to use the same delegate method. Or you can simply do all the code in the gestures target method. Try something like this:
CGPoint gestureStartPoint;
- (void)dragFromBoreder:(UIGestureRecognizer *)sender {
static const CGFloat borderWidth = 50.0f;
switch (sender.state) {
case UIGestureRecognizerStateBegan: {
CGPoint location = [sender locationInView:self];
if(location.x > borderWidth || location.x < self.frame.size.width-borderWidth) {
//break the gesture
sender.enabled = NO;
sender.enabled = YES;
}
else {
gestureStartPoint = location;
}
break;
}
case UIGestureRecognizerStateChanged: {
CGPoint location = [sender locationInView:self];
CGFloat deltaX = location.x - gestureStartPoint.x;
UIView *viewToMove;
CGPoint defaultCenter;
viewToMove.center = CGPointMake(defaultCenter.x+deltaX, defaultCenter.y);
break;
}
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled: {
CGPoint location = [sender locationInView:self];
CGFloat deltaX = location.x - gestureStartPoint.x;
/*
if(deltaX > someWidth) {
show the left view
}
else if(deltaX < -someWidth) {
show the right view
}
else {
put everything back the way it was
}
*/
break;
}
default:
break;
}
}
In ios7 there is a gesture recogniser specifically for gestures beginning from the edge of the screen. You should use this.
I can't help with your "smooth" problem, because you haven't said what your current animation looks like or how you are doing it. But a pan gesture, like the one linked, which directly updates view positions, will track the user's movement much more smoothly than a swipe.
I think the title is pretty self explaining. I need an icon that is dragged by users touch. If this icon is droped on a certain area I would like to call a function. How´s that possible?
Thanks a lot,
Tyler
Add UIPanGesture to the View.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer *pangesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(imageIsMoved:)];
pangesture.minimumNumberOfTouches = 1;
[self.myView addGestureRecognizer:pangesture];
}
Write a gesture method when drag is over
-(void)imageIsMoved:(UIPanGestureRecognizer *)gesture{
CGRect frameToBeCompared;
if (gesture.state == UIGestureRecognizerStateEnded) {
UIView *v = [gesture view];
CGRect viewFrame = v.frame;
if (CGRectEqualToRect(frameToBeCompared, viewFrame)) {
[self callMyMethod];
}
}
}
Check out this thread. Once you have the basics down, you can use an if statement to check the bounds of your icon and if they hit a specific spot call your next function.
Here's another example from one of my favorite iOS tutorial sites, www.raywenderlich.com