How to move UIView by longPress on button and then dragging? - ios

I want to move some UIView by button inside this view.
I can it, in that way:
- (void)viewDidLoad
{
[button addTarget:self action:#selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown];
[button addTarget:self action:#selector(dragMoving:withEvent:) forControlEvents: UIControlEventTouchDragInside];
[button addTarget:self action:#selector(dragEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
}
.
- (void)dragBegan:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
}
- (void)dragMoving:(UIControl *)c withEvent:ev {
UITouch *touch = [[ev allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
//This is moving view to touchPoint
SimpleView.center = touchPoint;
}
- (void)dragEnded:(UIControl *)c withEvent:ev {
}
How can i move it only then, if I do longPress on that button?

Try using this code. I've used this in a card game i developed. moving cards around using long press gestures. Hope i helps.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(addLongpressGesture:)];
[longPress setDelegate:self];
[YOUR_VIEW addGestureRecognizer:longPress];
- (void)addLongpressGesture:(UILongPressGestureRecognizer *)sender {
UIView *view = sender.view;
CGPoint point = [sender locationInView:view.superview];
if (sender.state == UIGestureRecognizerStateBegan){
// GESTURE STATE BEGAN
}
else if (sender.state == UIGestureRecognizerStateChanged){
//GESTURE STATE CHANGED/ MOVED
CGPoint center = view.center;
center.x += point.x - _priorPoint.x;
center.y += point.y - _priorPoint.y;
view.center = center;
// This is how i drag my views
}
else if (sender.state == UIGestureRecognizerStateEnded){
//GESTURE ENDED
}

I would use this link provided by #Coder404 to detect whether or not the player used a long touch. Then, add an #property BOOL performedLongTouch and set that to YES in the selector passed into the UILongPressGestureRecognizer
Then, in your dragBegan and dragMoving functions, add a check for performedLongTouch and in your dragEnded function, set its value to NO
I know that seem pretty straight forward, but is that what you were looking for?

Related

How to move array of UIImageViews smoothly?

Am working on kind of seating arrangement application. Where the app allows the admin to arrange the seatings by click and move the each seat and then save the seating arrangement with frame sizes of each seat. I tried by loading 5 UIImageView on custom view and move the imageview but, only one imageview is getting moved. Rest of the imageviews not getting moved. Can you please help me on this?
- (void) addSeatsToTheView {
for (int i=0; i<5; i++) {
self.hotelImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 50, 50)];
self.hotelImage.image = [UIImage imageNamed:#"DiningIcon"];
self.hotelImage.userInteractionEnabled = YES;
[self.hotelImage setUserInteractionEnabled:YES];
self.hotelImage.tag = i;
[self.hotelView addSubview:self.hotelImage];
}
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if (touch.view == self.hotelImage) {
CGPoint location = [touch locationInView:self.hotelView];
NSLog(#"Begen Touch Location: %#", NSStringFromCGPoint(location));
self.hotelImage.frame=CGRectMake(location.x, location.y, 50, 50);
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if (touch.view == self.hotelImage) {
CGPoint location = [touch locationInView:self.hotelView];
NSLog(#"Begen Touch Location: %#", NSStringFromCGPoint(location));
self.hotelImage.frame=CGRectMake(location.x, location.y, 50, 50);
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
if (touch.view == self.hotelImage) {
CGPoint location = [touch locationInView:self.hotelView];
NSLog(#"Begen Touch Location: %#", NSStringFromCGPoint(location));
self.hotelImage.frame=CGRectMake(location.x, location.y, 50, 50);
}
}
Once the admin arranged the seatings we have to save all the visible uiimageview framesizes. Thanks.
Edited:
I tried the using UIPanGestureRecognizer but, only one imageview getting moved. Don't know where am doing wrong? Can you please help me? Thanks.
- (void) addSeatsToTheView {
for (int i=0; i<5; i++) {
self.hotelImage = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 50, 50)];
self.hotelImage.image = [UIImage imageNamed:#"DiningIcon"];
self.hotelImage.userInteractionEnabled = YES;
[self.hotelImage setUserInteractionEnabled:YES];
self.hotelImage.tag = i;
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(gestureRecognizerMethod:)];
[self.hotelImage addGestureRecognizer:panGestureRecognizer];
[self.hotelView addSubview:self.hotelImage];
}
}
- (void)gestureRecognizerMethod:(UIPanGestureRecognizer *)recogniser
{
if (recogniser.state == UIGestureRecognizerStateBegan || recogniser.state == UIGestureRecognizerStateChanged)
{
CGPoint touchLocation = [recogniser locationInView:self.hotelView];
self.hotelImage.frame = CGRectMake(touchLocation.x, touchLocation.y, 50, 50);
}
}
Don't use touches methods for this; you'll go insane. Make each image view user-interactive and give it a UIPanGestureRecognizer. There is standard code for the pan gesture recognizer's action handler for following a finger, i.e. making the view draggable.
Once you've done that, everything stems from your misuse of self.hotelImage. Get rid of it entirely. In your for loop, just use a local variable, UIImageView* hotelImage = .... In the gesture recognizer method, use [recogniser view] to refer to the image view to which this gesture recognizer is attached. Everything will sort itself out after that!

Trying to move UIImageView, moving whole Screen View

I want my UIViewImages to be movable with touch. I'm trying to use code implemented in my ViewController:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count]==1) {
UITouch *touch = [touches anyObject];
CGPoint p0 = [touch previousLocationInView:self.view];
CGPoint p1 = [touch locationInView:self.view];
CGPoint center = self.view.center;
center.x += p1.x - p0.x;
center.y += p1.y - p0.y;
self.view.center = center;
}
}
When I try to drag an UIImageView, I'm dragging whole screen, which is incorrect.
Need help!
Karol
You create a gesture recognizer and add it to a view like this:
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(gestureRecognizerMethod:)];
[self.imageView addGestureRecognizer:panGestureRecognizer];
you can adjust the position of the image view
- (void)gestureRecognizerMethod:(UIPanGestureRecognizer *)recogniser
{
if (recognizer.state == UIGestureRecognizerStateBegan || recognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint touchLocation = [recognizer locationInView:self.view];
self.imageView.center = touchLocation;
}
}
read this article.
If I read your code right self.view actually IS the whole screen.
Maybe you mean self.yourImageView instead?

Is it possible to get the x and y coordinates of a touch?

is it possible to get the x and y coordinates of a touch? If so could someone please provide a very simple example where the coordinates are just logged to the console.
Using touchesBegan Event
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchPoint = [touch locationInView:self.view];
NSLog(#"Touch x : %f y : %f", touchPoint.x, touchPoint.y);
}
This event is triggered when touch starts.
Using Gesture
Register your UITapGestureRecognizer in viewDidLoad: Method
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureRecognizer:)];
[self.view setUserInteractionEnabled:YES];
[self.view addGestureRecognizer:tapGesture];
}
Setting up the tapGestureRecognizer function
// Tap GestureRecognizer function
- (void)tapGestureRecognizer:(UIGestureRecognizer *)recognizer {
CGPoint tappedPoint = [recognizer locationInView:self.view];
CGFloat xCoordinate = tappedPoint.x;
CGFloat yCoordinate = tappedPoint.y;
NSLog(#"Touch Using UITapGestureRecognizer x : %f y : %f", xCoordinate, yCoordinate);
}
Sample Project
First you need to add a gesture recognizer to the view you want.
UITapGestureRecognizer *myTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myTapRecognizer:)];
[self.myView setUserInteractionEnabled:YES];
[self.myView addGestureRecognizer:myTap];
Then in the gesture recognizer method you make a call to locationInView:
- (void)myTapRecognizer:(UIGestureRecognizer *)recognizer
{
CGPoint tappedPoint = [recognizer locationInView:self.myView];
CGFloat xCoordinate = tappedPoint.x;
CGFloat yCoordinate = tappedPoint.y;
}
You may want to take a look at apple's UIGestureRecognizer Class Reference
Here's a very basic example (place it inside your view controller):
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
NSLog(#"%#", NSStringFromCGPoint(currentPoint));
}
This triggers every time the touch moves. You can also use touchesBegan:withEvent: which triggers when a touch starts, and touchesEnded:withEvent: which triggers when a touch ends (i.e. a finger is lifted).
You can also do this using a UIGestureRecognizer, which in many cases is more practical.

Dragging Multiple Images

I am trying to develop an analysing app that determines if you are "clever"
What this involves doing is taking a picture of yourself and dragging points onto your face, where the nose, mouth and eyes are. However, The code I have tried does not work:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if ([touch view] == eye1)
{
eye1.center = location;
}
else if ([touch view] == eye2)
{
eye2.center = location;
}
else if ([touch view] == nose)
{
nose.center = location;
}
else if ([touch view] == chin)
{
chin.center = location;
}
else if ([touch view] == lip1)
{
lip1.center = location;
}
else if ([touch view] ==lip2)
{
lip2.center = location;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[self touchesBegan:touches withEvent:event];
}
What is happening, because when I just have a single image, it works, but is not helpful for me. What can I do to make it work? The spots start at the bottom of the screen in a "Toolbar" and then the user drags them onto the face. I kinda want the finished result to look like:
There are two basic approaches:
You can use the various touches methods (e.g. touchesBegan, touchesMoved, etc.) in your controller or the main view, or you can use a single gesture recognizer on the main view. In this situation, you'd use touchesBegan or, if using a gesture recognizer, a state of UIGestureRecognizerStateBegan, determine locationInView of the superview, and then test whether the touch is over one of your views by testing CGRectContainsPoint, using the frame of the various views as the first parameter, and by using the location as the second parameter.
Having identified the view that the gesture began, then in touchesMoved or, if in a gesture recognizer, a state of UIGestureRecognizerStateChanged, and move the view based upon the translationInView.
Alternatively (and easier IMHO), you can create individual gesture recognizers that you attach to each of the subviews. This latter approach might look like the following. For example, you first add your gesture recognizers:
NSArray *views = #[eye1, eye2, lip1, lip2, chin, nose];
for (UIView *view in views)
{
view.userInteractionEnabled = YES;
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[view addGestureRecognizer:pan];
}
Then you implement a handlePanGesture method:
- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture
{
CGPoint translation = [gesture translationInView:gesture.view];
if (gesture.state == UIGestureRecognizerStateChanged)
{
gesture.view.transform = CGAffineTransformMakeTranslation(translation.x, translation.y);
[gesture.view.superview bringSubviewToFront:gesture.view];
}
else if (gesture.state == UIGestureRecognizerStateEnded)
{
gesture.view.transform = CGAffineTransformIdentity;
gesture.view.center = CGPointMake(gesture.view.center.x + translation.x, gesture.view.center.y + translation.y);
}
}

Make a swipe button

I want to make a swipe button, so when user swipe the button from right to left the button also draw towards right to left and at the end it will push the another view, can anybody give sample code for it.
// make button
UIButton*btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(50, 50, 50, 50)];
[btn addTarget:self action:#selector(wasDragged:withEvent:)
forControlEvents:UIControlEventTouchDragInside];
[self.view addSubview:btn];
// here swipe buttons
- (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event
{
// get the touch
UITouch *touch = [[event touchesForView:button] anyObject];
// get delta
CGPoint previousLocation = [touch previousLocationInView:button];
CGPoint location = [touch locationInView:button];
CGFloat delta_x = location.x - previousLocation.x;
CGFloat delta_y = location.y - previousLocation.y;
// move button
CGPoint moveBtnCenter = CGPointMake(button.center.x + delta_x,
button.center.y + delta_y);
button.center = moveBtnCenter;
NSArray* allSubViews = [self.view subviews];
for (UIView*subView in allSubViews)
{
if ([subView isKindOfClass:[UIButton class]])
{
CGPoint subViewCenter = subView.center;
if (CGPointEqualToPoint(moveBtnCenter, subViewCenter))
{
subView.center = previousLocation;
}
}
}
}

Resources