Setting frame to view during UIPanGesture recognition - ios

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

Related

How to drag and drop, rotate and zoom correctly a UIView?

In my iOS application, I use UITouchGestureRecognizer to drag/drop, zoom and rotate UIImageView. I also store the information on the last position of the ImageView to retrieve it when the app restarts.
That was working well with iOS7 but I have recently started to test with iOS8 and I'm facing some issues, especially with the zoom. Whenever the imageview has a non-0 angle in the rotation parameter, the zoom is not acting like expected and reduces the size of the image.
I don't understand why the OS change does that, here is my code:
-(void) viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
[self loadAllImages];
for (GIFavorite *favorite in self.favorites){
UIImage *image = favorite.image;
ImageView *imageView = [[ImageView alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
imageView.center = CGPointMake(favorite.x, favorite.y);
imageView.transform = CGAffineTransformMakeRotation(favorite.rotation);
imageView.transform = CGAffineTransformScale(imageView.transform, favorite.scale, favorite.scale);
imageView.image = image;
imageView.userInteractionEnabled = YES;
UIPanGestureRecognizer * panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panRecognizer.delegate = self;
[imageView addGestureRecognizer:panRecognizer];
UIRotationGestureRecognizer * rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotate:)];
rotationRecognizer.delegate = self;
[imageView addGestureRecognizer:rotationRecognizer];
UIPinchGestureRecognizer * pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinch:)];
pinchRecognizer.delegate = self;
[imageView addGestureRecognizer:pinchRecognizer];
[self.view addSubview:imageView];
}
}
I guess the way I am doing the transforms is wrong because when I put the CGAffineTransformMakeRotation instruction after the CGAffineTransformScale instead of reducing the size it increases it.
Where am I doing things wrong?
Edit: the code for handleRotate
- (void)handleRotate:(UIRotationGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
ImageView *imageView = recognizer.view;
CGFloat radians = atan2f(imageView.transform.b, imageView.transform.a);
favorite.rotation = radians;
recognizer.rotation = 0;
}
First, you need to make your view controller implements UIGestureRecognizerDelegate.
SWIFT 3 :-
func setUpGestures () {
let panGesture = UIPanGestureRecognizer(target: self, action:#selector(self.handlePanGesture(gesture:)))
self.imageView.addGestureRecognizer(panGesture)
let rotationGesture = UIRotationGestureRecognizer(target: self, action:#selector(self.handleRotationGesture(gesture:)))
self.imageView.addGestureRecognizer(rotationGesture)
let pinchGesture = UIPinchGestureRecognizer(target: self, action:#selector(self.handlePinchGesture(gesture:)))
self.imageView.addGestureRecognizer(pinchGesture)
}
func handlePinchGesture(gesture: UIPinchGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
//print("UIPinchGestureRecognizer")
gesture.view?.transform = (gesture.view?.transform)!.scaledBy(x: gesture.scale, y: gesture.scale)
gesture.scale = 1.0
}
}
func handleRotationGesture(gesture: UIRotationGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
//print("UIRotationGestureRecognizer")
gesture.view?.transform = (gesture.view?.transform)!.rotated(by: gesture.rotation)
gesture.rotation = 0
}
}
func handlePanGesture(gesture: UIPanGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began || gesture.state == UIGestureRecognizerState.changed{
//print("UIPanGestureRecognizer")
let translation = gesture.translation(in: view)
gesture.view?.transform = (gesture.view?.transform)!.translatedBy(x: translation.x, y: translation.y)
gesture.setTranslation(CGPoint(x: 0, y: 0), in: view)
}
}
Hope, this is what you're looking for. Any concern get back to me. :)
First, you need to make your view controller implements UIGestureRecognizerDelegate.
Then add the gesture recognizers to your UIView (I see that you already did that, but just putting it here again to have the solution in one place).
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panGesture.delegate = self;
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotate:)];
rotationGesture.delegate = self;
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinch:)];
pinchGesture.delegate = self;
[yourView addGestureRecognizer:panGesture];
[yourView addGestureRecognizer:rotationGesture];
[yourView addGestureRecognizer:pinchGesture];
Then, this is how your handle... methods should be:
- (void)handlePinch:(UIPinchGestureRecognizer *)pinchRecognizer
{
UIGestureRecognizerState state = [pinchRecognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat scale = [pinchRecognizer scale];
[pinchRecognizer.view setTransform:CGAffineTransformScale(pinchRecognizer.view.transform, scale, scale)];
[pinchRecognizer setScale:1.0];
}
}
- (void)handleRotate:(UIRotationGestureRecognizer *)rotationGestureRecognizer {
UIGestureRecognizerState state = [rotationGestureRecognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [rotationGestureRecognizer rotation];
[rotationGestureRecognizer.view setTransform:CGAffineTransformRotate(rotationGestureRecognizer.view.transform, rotation)];
[rotationGestureRecognizer setRotation:0];
}
}
- (void)handlePan:(UIPanGestureRecognizer *)panRecognizer {
UIGestureRecognizerState state = [panRecognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [panRecognizer translationInView:panRecognizer.view];
[panRecognizer.view setTransform:CGAffineTransformTranslate(panRecognizer.view.transform, translation.x, translation.y)];
[panRecognizer setTranslation:CGPointZero inView:panRecognizer.view];
}
}
And this is how it looks:
try doing these..
first in your ViewControllers .h do these..
#interface RotationViewController : UIViewController<UIGestureRecognizerDelegate>//Add these..
{
UIView *testView;
}
now do these in .m file of your ViewController..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
testView=[[UIView alloc]initWithFrame:CGRectMake(100, 100, 160, 160)];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 160, 160)];
[imageView setImage:[UIImage imageNamed:#"ImageName.png"]];
[imageView setContentMode:UIViewContentModeScaleAspectFit];
[testView addSubview:imageView];
[self.view addSubview:testView];
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotate:)];
[testView addGestureRecognizer:rotationGestureRecognizer];
}
-(void) handleRotate:(UIRotationGestureRecognizer *)rotationGestureRecognizer
{
testView.transform = CGAffineTransformRotate(testView.transform, rotationGestureRecognizer.rotation);
rotationGestureRecognizer.rotation = 0.0;
}
i hope it helps..

How to animate left/right swipe view using UISwipeGestureRecognizer

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]
}

UIPanGestureRecognizer always move from location (0, 0)

I'd like to drag customView.
But, when I drag the customView, it always move from location (0, 0).
Please look at following image.
the red parts is the customView, and when I drag it, it move to the location.
How do I fix it to make move customView correctly?
I have this code.
labelview is the customView(subclass of UIView).
- (void)viewDidLoad
{
[super viewDidLoad];
_labelView = [[LabelView alloc]initWithFrame:CGRectMake(20, 60, 200, 100)];
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[_labelView addGestureRecognizer:pan];
[self.view addSubview:_labelView];
}
- (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:movedPoint inView:self.view];
}
While the other two answers are technically correct, they are not ideal solutions because when you add a gesture recognizer to self.view then anytime you drag anywhere in self.view you will drag your LabelView, but I imagine you only want to drag it when you actually have your finger on the LabelView itself.
So, just keep what you have, but change this one line:
[sender setTranslation:movedPoint inView:self.view];
to
[sender setTranslation:CGPointZero inView:self.view];
You have implemented the logic upside down. It has to be exactly other way around. Set the ´UIPanGestureRecognizer´ to UIViewController's view and set the center of your custom view.
- (void)viewDidLoad
{
[super viewDidLoad];
_labelView = [[LabelView alloc]initWithFrame:CGRectMake(20, 60, 200, 100)];
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
// [_labelView addGestureRecognizer:pan]; must be removed
[self.view addGestureRecognizer:pan]; // must be added
[self.view addSubview:_labelView];
}
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint p = [sender translationInView:self.view];
CGPoint movedPoint = CGPointMake(_labelView.center.x + p.x, _labelView.center.y + p.y);
[_labelView setCenter:movedPoint];
}
I solved by writing following code.
Thank you for answers.
- (void)viewDidLoad
{
[super viewDidLoad];
_labelView = [[LabelView alloc]initWithFrame:CGRectMake(20, 60, 200, 100)];
UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(panAction:)];
[_labelView addGestureRecognizer:pan];
[self.view addSubview:_labelView];
}
- (void)panAction:(UIPanGestureRecognizer *)sender
{
CGPoint p = [sender translationInView:sender.view];
CGPoint movedPoint = CGPointMake(sender.view.center.x + p.x, sender.view.center.y + p.y);
sender.view.center = movedPoint;
[sender setTranslation:CGPointZero inView:sender.view];
}

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!

Imitating button click with UIGestureRecognized

Having added a UITapGestureRecognized to a UIView, how do I parse the view for ie. changing the background color during the tap? The purpose of this is to imitate a button click.
UIView *locationView = [[UIView alloc] init];
locationView.tag = 11;
locationView.backgroundColor = [UIColor clearColor];
locationView.userInteractionEnabled = YES;
[locationView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(promptForLocation)]];
Let's say I want locationView.backgroundColor = [UIColor blueColor] right after the tap gesture. Would you just implement it in the target action or is there a specific implementation for this?
Update:
This is my final code inspired by #0x7fffffff
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ...
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressDetectedLocation:)];
longPress.allowableMovement = 50.0f;
longPress.minimumPressDuration = 0.05;
UILongPressGestureRecognizer *longPress2 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressDetectedPhoto:)];
longPress2.allowableMovement = 50.0f;
longPress2.minimumPressDuration = 0.05;
[leftView addGestureRecognizer:longPress];
[rightView addGestureRecognizer:longPress2];
// ...
}
- (BOOL)longPressDetected:(UILongPressGestureRecognizer *)sender {
if ([self.view hasFirstResponder]) {
return NO;
}
if (sender.state == UIGestureRecognizerStateBegan) {
[sender.view setBackgroundColor:[UIColor colorWithRed:(4/255.0) green:(129/255.0) blue:(241/255.0) alpha:1]];
} else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed) {
[sender.view setBackgroundColor:[UIColor clearColor]];
}
CGPoint location = [sender locationInView:sender.view];
return sender.state == UIGestureRecognizerStateEnded && location.x > 0 && location.x < sender.view.frame.size.width && location.y > 0 && location.y < sender.view.frame.size.height;
}
- (void)longPressDetectedLocation:(UILongPressGestureRecognizer *)sender {
if ([self longPressDetected:sender]) {
[self promptForLocation];
}
}
- (void)longPressDetectedPhoto:(UILongPressGestureRecognizer *)sender {
if ([self longPressDetected:sender]) {
[self promptForPhoto];
}
}
Considering you're trying to imitate a button click, I'm assuming you'd want the view to revert to its original state after the touch ends. To do this, you'll want to use a UILongPressGestureRecognizer instead of a UITapGestureRecognizer.
With a tap gesture, the recognizer isn't detected until the touch ends, so you'd effectively be highlighting the view as soon as you lift your finger. To get around this, use the long press gesture its minimumPressDuration property set to 0.0. Then in its selector, check the state of the sending gesture; If it has just begun, change the background color, and if it has ended revert back to the original color.
Here's an example:
- (void)viewDidLoad {
[super viewDidLoad];
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
[myView setBackgroundColor:[UIColor redColor]];
[self.view addSubview:myView];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressDetected:)];
[longPress setAllowableMovement:50.0f];
[longPress setMinimumPressDuration:0.0];
[myView addGestureRecognizer:longPress];
}
- (void)longPressDetected:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
[sender.view setBackgroundColor:[UIColor blueColor]];
}else if (sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed) {
[sender.view setBackgroundColor:[UIColor redColor]];
}
NSLog(#"%d",sender.state);
}
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tappedMethod:)];
[locationView addGestureRecognizer:gr];
This is method
-(void)tappedMethod:(UIGestureRecognizer *)ge
{
// write relavent code here;
locationView.backgroundColor = [UIColor blueColor];
}

Resources