How to animate left/right swipe view using UISwipeGestureRecognizer - ios

try to make swipe in single-view and it's working but not get animation and page indicatore bubble in bottom
- (void)viewDidLoad
{
[super viewDidLoad];
UISwipeGestureRecognizer *swipeleft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(screenswipeleft)];
swipeleft.numberOfTouchesRequired=1;
swipeleft.direction=UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeleft];
UISwipeGestureRecognizer *swiperight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(viewDidLoad)];
swiperight.numberOfTouchesRequired=1;
swiperight.direction=UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swiperight];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)];
[self.view addSubview:textField];
NSLog(#"move left");
}
-(void)screenswipeleft {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 200, 300, 40)];
[self.view addSubview:textField];
NSLog(#"move right");
}

Suppose you want to animate the UITextField.
And your UITextField has a CGRect with starting point of x - 50, y - 100;
#implementation myViewController{
UITextField *myTextField; //Declaring a textfield as an instance variable (global).
}
-(void)viewDidLoad{
myTextField = [UITextField alloc]initWithFrame:CGRectMake(50,100,100,50)];//adding memory and setting its initial position
//your other codes.
}
-(void)screenswipeleft {
[UIView animateWithDuration:3 animations:^{
myTextField.frame = CGRectMake:(-75,100,100,50); //setting the same textfield in a position of -75 only showing 1/4th of the textfield.
//this block animation would make the textfield animate from its starting position to this position in 3 seconds. (animateWithDuration:3 here u mention its duration).
}];
}
Apply same logic to others and you will get the animation you want.

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_leftSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipes:)];
_rightSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipes:)];
_leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
_rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:_leftSwipeGestureRecognizer];
[self.view addGestureRecognizer:_rightSwipeGestureRecognizer];
}
- (void)handleSwipes:(UISwipeGestureRecognizer *)sender
{
if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {
CGPoint labelPosition = CGPointMake(self.swipeLabel.frame.origin.x - 100.0, self.swipeLabel.frame.origin.y);
self.swipeLabel.frame = CGRectMake( labelPosition.x , labelPosition.y , self.swipeLabel.frame.size.width, self.swipeLabel.frame.size.height);
}
if (sender.direction == UISwipeGestureRecognizerDirectionRight) {
CGPoint labelPosition = CGPointMake(self.swipeLabel.frame.origin.x + 100.0, self.swipeLabel.frame.origin.y);
self.swipeLabel.frame = CGRectMake( labelPosition.x , labelPosition.y , self.swipeLabel.frame.size.width, self.swipeLabel.frame.size.height);
}
}

Try this.
-(void)screenswipeleft
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
textField.frame = CGRectMake(10, 200, 300, 40)];
[UIView commitAnimations]
}

Related

How can I check whether its parent view or subview when touch gesture event called?

I have two view. One is transparent view which contains subviews. I want to remove screenView only when parent view is clicked. I don't want to call tapGesture when i click popUpView. How to can check?
screenView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];
screenView.backgroundColor = [UIColor clearColor];
UITapGestureRecognizer * clearTable = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(clearTableViewAction:)];
[clearTable setNumberOfTapsRequired:1];
[screenView setUserInteractionEnabled:YES];
[screenView addGestureRecognizer:clearTable];
screenView.tag = 100;
[self.view addSubview:screenView];
self.popUpView = [[UIView alloc]init];
self.popUpView.frame = ...
self.popUpView.backgroundColor = WhiteColor;
self.popUpView.userInteractionEnabled = YES;
self.popUpView.tag = 200;
[screenView addSubview:self.popUpView];
-(void)clearTableViewAction:(UITapGestureRecognizer*)sender {
if(sender.view.tag == 100){
[UIView animateWithDuration:0.2
animations:^{screenView.alpha = 0.0;}
completion:^(BOOL finished){ [screenView removeFromSuperview];
}];
}
}
Use shouldReceiveTouch delegate method and check:
Like,
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view.tag == 100)
{
return YES;
}
else
{
return NO;
}
}
Now, clearTableViewAction gesture method will not be called if you will click in popUpView.

Setting frame to view during UIPanGesture recognition

I'm trying to update frames for two labels during UIPanGesture recognition of a UIView (centre grey color).
Functionality
I need to choose a language between English and Arabic. There is a slider button in middle (grey view) and I have applied UIPanGesture to that. So while swiping towards Arabic the language English should move to centre and assumes that its selected and vice versa.
I tried my level best but I can only make upto this. Frames are not setting properly and I don't know is there any other easy way to do this.
Code
- (void)viewDidLoad {
[super viewDidLoad];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[dragview addGestureRecognizer:gesture];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
CGPoint velocity = [gestureRecognizer velocityInView: gestureRecognizer.view];
CGPoint location = [gestureRecognizer locationInView: gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
if (dragview.frame.origin.x + dragview.frame.size.width >= dragV.frame.size.width) {
[dragview setFrame:CGRectMake(dragV.frame.size.width - dragview.frame.size.width, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
english.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x-panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x + 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x + 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
else
{
NSLog(#"gesture went left");
if (dragview.frame.origin.x <= 0) {
[dragview setFrame:CGRectMake(0, dragview.frame.origin.y, dragview.frame.size.width, dragview.frame.size.height)];
arabic.center = CGPointMake(dragV.frame.size.width / 2,
dragV.frame.size.height / 2);
} else {
float dX = location.x+panCoord.x;
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x+dX, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[english setFrame:CGRectMake(english.frame.origin.x - 1.0f, english.frame.origin.y, english.frame.size.width, english.frame.size.height)];
[arabic setFrame:CGRectMake(arabic.frame.origin.x - 1.0f, arabic.frame.origin.y, arabic.frame.size.width, arabic.frame.size.height)];
}
}
}
Screenshots
Initially it looks like this,
While dragging towards arabic,
While dragging towards english,
Answers are appreciated!!
I got output.I tried your code and I used SwipeGestureRecognizer code.It works fine now.
I tried with 2 optins
OPTION 1:SwipeGestureRecognizer
- (void)viewDidLoad
{
[super viewDidLoad];
// Swipe Left
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeLeft:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[arabicView addGestureRecognizer:swipeLeft];
// Swipe Right
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeRight:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[englishView addGestureRecognizer:swipeRight];
}
- (void)handleSwipeLeft:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtRight) withObject:nil afterDelay:0.01f];
}
- (void)handleSwipeRight:(UISwipeGestureRecognizer *)recognizer
{
[self performSelector:#selector(moveAtLeft) withObject:nil afterDelay:0.01f];
}
-(void)moveAtRight
{
englishView.frame = CGRectMake(0, 0, 53, 53);
englishView.backgroundColor = [UIColor lightGrayColor];
arabicView.frame = CGRectMake(53, 0, 205, 53);
english.text = #"English";
arabic.text = #"Arabic";
arabicView.backgroundColor = [UIColor blueColor];
[dragview removeFromSuperview];
}
-(void)moveAtLeft
{
englishView.frame = CGRectMake(0, 0, 205, 53);
arabicView.frame = CGRectMake(205, 0, 53, 53);
arabicView.backgroundColor = [UIColor lightGrayColor];
englishView.backgroundColor = [UIColor blueColor];
english.text = #"English";
arabic.text = #"Arabic";
[dragview removeFromSuperview];
}
In above code I set background color to blue.If you want to any other color change.
At Initial
When I swipe towards Arabic
When I swipe towards English
Above these are output.
OPTION 2:PanGestureRecognizer
Now I tried with your PanGestureRecognizer Code.I set frame and background color for englishView and arabicView separately.Now it works fine.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_drawPath = [UIBezierPath
bezierPathWithRoundedRect:CGRectMake(0, 0, 140, 35)
byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerTopLeft | UIRectCornerTopRight)
cornerRadii:CGSizeMake(4, 4)
];
_rectLayer = [[CAShapeLayer alloc] init];
_rectLayer.path = _drawPath.CGPath;
_rectLayer.strokeColor = [UIColor blackColor].CGColor;
_rectLayer.lineWidth = 2.0f;
_rectLayer.fillColor = [UIColor clearColor].CGColor;
_rectLayer.strokeEnd = 0.f;
[vi.layer addSublayer:_rectLayer];
[self drawRectangle:nil];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture setMinimumNumberOfTouches:1];
[gesture setMaximumNumberOfTouches:1];
[englishView addGestureRecognizer:gesture];
UIPanGestureRecognizer *gesture1 = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[gesture1 setMinimumNumberOfTouches:1];
[gesture1 setMaximumNumberOfTouches:1];
[arabicView addGestureRecognizer:gesture1];
}
- (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateChanged)
{
NSLog(#"Changed");
CGPoint velocity = [gestureRecognizer velocityInView:gestureRecognizer.view];
CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
if(velocity.x > 0)
{
NSLog(#"gesture went right");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
NSLog(#"The gestureRecognizer frame is - %#",NSStringFromCGRect(gestureRecognizer.view.frame));
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y, 205, englishView.frame.size.height)];
[englishView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[arabicView setFrame:CGRectMake(205, arabicView.frame.origin.y, 53, arabicView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
else
{
NSLog(#"gesture went left");
gestureRecognizer.view.frame = CGRectMake(gestureRecognizer.view.frame.origin.x + translation.x, 0, gestureRecognizer.view.frame.size.width, gestureRecognizer.view.frame.size.height);
[arabicView setFrame:CGRectMake(53, arabicView.frame.origin.y, 205, arabicView.frame.size.height)];
[englishView setFrame:CGRectMake(0, englishView.frame.origin.y,53,englishView.frame.size.height)];
[arabicView setBackgroundColor:[UIColor colorWithRed:(15/255.0f) green:(97/255.0f) blue:(163/255.0f) alpha:1.0f]];
[englishView setBackgroundColor:[UIColor lightGrayColor]];
[gestureRecognizer setTranslation:CGPointMake(0, 0) inView:dragV];
[dragview removeFromSuperview];
}
}
}
At First once I run the app
Middle Finger towards Arabic View
Middle Finger towards English View

iOS 8 CGAffineTransformConcat with Scale and Translate cause a position jump

I am having an issue with CGAffineTransformConcat that is present in iOS 8, but not iOS 7. When animating a UIView using a concatenation with a scale and translate causes the position to jump. Running the same code in iOS 7, achieves the desired results. Is there something that has changed that causes this issue?
Here is my example code...
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//add a view
self.lilView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
self.lilView.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.lilView];
//add a tap gesture
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(poop:)];
[self.view addGestureRecognizer:tap];
}
-(void) poop:(UITapGestureRecognizer*) gesture {
if (!self.pooped) {
[UIView animateWithDuration:1 delay:0 options:0 animations:^{
self.lilView.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 2.0), CGAffineTransformMakeTranslation(200, 300));
self.pooped = YES;
} completion:nil];
} else {
[UIView animateWithDuration:1 delay:0 options:0 animations:^{
self.lilView.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(1.5, 1.5), CGAffineTransformMakeTranslation(100, 200));
self.pooped = NO;
} completion:nil];
}
}
Thank you for your help!

make some drag-able UIView

I'd like to make some drag-able UIView.
But in case of following code, you can drag only one UIView you have added at the last.
I have this code.
LabelView class is subclass of UIView.
ViewControlle.h
#interface ViewController : UIViewController
#property (nonatomic, strong) LabelView* labelView;
#end
ViewController.m
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_labelView = [[LabelView alloc]initWithFrame:CGRectMake(100, 200, 200, 50)];
[self.view addSubview:_labelView];
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[_labelView addGestureRecognizer:pan];
UIButton* addButton = [[UIButton alloc]initWithFrame:CGRectMake(270, 60, 40, 40)];
[addButton addTarget:self action:#selector(newLabelView) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:addButton];
}
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint p = [sender translationInView:self.view];
CGPoint movedPoint = CGPointMake(_labelView.center.x + p.x, _labelView.center.y + p.y);
_labelView.center = movedPoint;
[sender setTranslation:CGPointZero inView:self.view];
}
- (void)newLabelView
{
_labelView = [[LabelView alloc]initWithFrame:CGRectMake(20, 60, 200, 50)];
[self.view addSubview:_labelView];
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[_labelView addGestureRecognizer:pan];
}
You should apply the getsture for all the view. and then change the methods. _labelView.center = movedPoint; to [sender view].center = movedPoint;
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint p = [sender translationInView:self.view];
CGPoint movedPoint = CGPointMake(_labelView.center.x + p.x, _labelView.center.y + p.y);
[sender view].center = movedPoint;
[sender setTranslation:CGPointZero inView:self.view];
}
You could create a mutable array, and then add each new view into that array. You do this by adding:
NSMutableArray *viewsArray = [[NSMutableArray alloc] init];
// after creating the custom view
[viewsArray addObject:customView];
Then, you can add a pan gesture on top of the views in the array, that way they are all using the pan gesture
for(LabelView *l in viewsArray) {
[l addGestureRecognizer:panGestureRecognizer];
}
this will add a UIPanGestureRecognizer to all the custom views in the array that you created in the beginning of this answer.
Hope this helps!

How to "transfer" an ongoing gesture from a subview to the superview without interruption?

This is what I'm trying to do:
I want to start recognizing a gesture in a subview and then, when the finger leaves the subview, let the superview take over and handle the gesture. Is that possible?
At the moment, the view in which the gesture started "wins". Is there any way to "hand over" a gesture from one view to another "on the fly", without lifting the finger off the screen?
This is the code for a simple demo:
#implementation SPWKViewController {
UIView *_innerView;
UIPanGestureRecognizer *_outerGestureRecognizer;
UIPanGestureRecognizer *_innerGestureRecognizer;
UILabel *_label;
}
- (void)loadView
{
[super loadView];
self.view.backgroundColor = [UIColor yellowColor];
_innerView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, self.view.frame.size.width - 100, 200)];
_innerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_innerView.backgroundColor = [UIColor greenColor];
_label = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, self.view.frame.size.width, 40)];
_label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
_label.textAlignment = NSTextAlignmentCenter;
_label.backgroundColor = [UIColor clearColor];
[self.view addSubview:_innerView];
[self.view addSubview:_label];
}
- (void)viewDidLoad
{
[super viewDidLoad];
_outerGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[self.view addGestureRecognizer:_outerGestureRecognizer];
_innerGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
[_innerView addGestureRecognizer:_innerGestureRecognizer];
}
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateChanged) {
if (gestureRecognizer == _outerGestureRecognizer) {
_label.text = #"outer";
} else {
_label.text = #"inner";
}
} else {
_label.text = #"";
}
}
#end
Some background information: The actual problem I'd like to solve is this: I'd like to put a UIWebView inside of a UIScrollView. When I scroll to the bottom of the UIWebView, I want the parent UIScrollView to "take over" and keep scrolling without having to lift the finger off the screen first. I figured that in order to achieve that, I'd need to "hand over" the gesture from the UIWebView to the parent UIScrollView.
Thank you!

Resources