How to achieve a continuous drag and drop menu effect?

I am trying to achieve a drag effect. I am not sure how to do this, maybe someone has experience with this exact effect.

Simply put, when a user touches a menu item, I want the graphic to appear at the point they were touched. Now their touch will control the panning of the graphics. After releasing the touch, the graphic element will sit in its place and accept full alpha.

I am already familiar with making gestures and instantiating. For now, I can create graphics in which I touched a menu item. The biggest problem is how I โ€œconveyโ€ the touch gesture, so this is a single and continuous movement.

Also, should the menu item be UIButton or UIImageView?

Any help appreciated. thanks enter image description here

+4
source share
2 answers

I had fun with this. The following code will capture the image from the button when touched, drag this image to alpha = 0.5 and drop it wherever your strokes end with alpha = 1.0. After that, it will continue to be dragged.

After importing QuartzCore, create a new file .. you should read:

#import <Foundation/Foundation.h> #import <QuartzCore/CAGradientLayer.h> #import <QuartzCore/CALayer.h> @interface DraggableImage : CAGradientLayer - (void)draw:(UIImage *)image; - (void)moveToFront; - (void)appearDraggable; - (void)appearNormal; @end 

a .m should read:

 #import "DraggableImage.h" @implementation DraggableImage - (void)draw:(UIImage *)image{ CGRect buttonFrame = self.bounds; int buttonWidth = buttonFrame.size.width; int buttonHeight = buttonFrame.size.height; UIGraphicsBeginImageContext( CGSizeMake(buttonWidth, buttonHeight) ); [image drawInRect:self.bounds]; UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); [newImage drawInRect:self.bounds]; } - (void)moveToFront { CALayer *superlayer = self.superlayer; [self removeFromSuperlayer]; [superlayer addSublayer:self]; } - (void)appearDraggable { self.opacity = 0.5; } - (void)appearNormal { self.opacity = 1.0; } @end 

Now in the main view controller add:

 #import <UIKit/UIKit.h> #import <QuartzCore/QuartzCore.h> #import "DraggableImage.h" @interface YourViewController : UIViewController{ DraggableImage *heldImage; DraggableImage *imageForFrame[5]; // or however many UIButton *buttonPressed; int imageCount; } @property (weak, nonatomic) IBOutlet UIButton *imageButton; -(IBAction)buildImageLayerForButton:(UIButton *)sender; - (void)moveHeldImageToPoint:(CGPoint)location; - (CALayer *)layerForTouch:(UITouch *)touch; 

imageButton in this case will be your Apple button. Now in your .m file add the following:

 @synthesize imageButton; #pragma - mark Touches -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ CALayer *hitLayer = [self layerForTouch:[touches anyObject]]; if ([hitLayer isKindOfClass:[DraggableImage class]]) { DraggableImage *image = (DraggableImage *)hitLayer; heldImage = image; [heldImage moveToFront]; } hitLayer = nil; [super touchesBegan:touches withEvent:event]; } -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ if (heldImage) { UITouch *touch = [touches anyObject]; UIView *view = self.view; CGPoint location = [touch locationInView:view]; [self moveHeldImageToPoint:location]; } } - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ if (heldImage) { [heldImage appearNormal]; heldImage = nil; } } - (void)dragBegan:(UIControl *)c withEvent:ev { } - (void)dragMoving:(UIControl *)c withEvent:ev { UITouch *touch = [[ev allTouches] anyObject]; CGPoint touchPoint = [touch locationInView:self.view]; [self moveHeldImageToPoint:touchPoint]; } - (void)dragEnded:(UIControl *)c withEvent:ev { UITouch *touch = [[ev allTouches] anyObject]; CGPoint touchPoint = [touch locationInView:self.view]; [self moveHeldImageToPoint:touchPoint]; [heldImage appearNormal]; heldImage = nil; } -(IBAction)buildImageLayerForButton:(UIButton *)sender{ DraggableImage *image = [[DraggableImage alloc] init]; buttonPressed = sender; CGRect buttonFrame = sender.bounds; int buttonWidth = buttonFrame.size.width; int buttonHeight = buttonFrame.size.height; image.frame = CGRectMake(120, 24, buttonWidth*3, buttonHeight*3); image.backgroundColor = [UIColor lightGrayColor].CGColor; image.delegate = self; imageForFrame[imageCount] = image; [self.view.layer addSublayer:image]; [image setNeedsDisplay]; [image moveToFront]; [image appearDraggable]; heldImage = image; [self moveHeldImageToPoint:sender.center]; imageCount++; } - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { UIGraphicsPushContext(ctx); DraggableImage *image = (DraggableImage *)layer; [image draw:[buttonPressed imageForState:UIControlStateNormal]]; UIGraphicsPopContext(); } - (void)moveHeldImageToPoint:(CGPoint)location { float dx = location.x; float dy = location.y; CGPoint newPosition = CGPointMake(dx, dy); [CATransaction begin]; [CATransaction setDisableActions:TRUE]; heldImage.position = newPosition; [CATransaction commit]; } - (CALayer *)layerForTouch:(UITouch *)touch { UIView *view = self.view; CGPoint location = [touch locationInView:view]; location = [view convertPoint:location toView:nil]; CALayer *hitPresentationLayer = [view.layer.presentationLayer hitTest:location]; if (hitPresentationLayer) { return hitPresentationLayer.modelLayer; } return nil; } -(void)viewDidLoad{ [imageButton addTarget:self action:@selector(dragBegan:withEvent:) forControlEvents: UIControlEventTouchDown]; [imageButton addTarget:self action:@selector(dragMoving:withEvent:) forControlEvents: UIControlEventTouchDragInside | UIControlEventTouchDragOutside]; [imageButton addTarget:self action:@selector(dragEnded:withEvent:) forControlEvents: UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; [super viewDidLoad]; } - (void)viewDidUnload { [self setImageButton:nil]; [super viewDidUnload]; } 

Et voila! Connect your button, set its image and drop copies all over the screen. :)

Note. I did not comment on anything, but I would be happy to answer any questions.

Hooray!

EDIT: fixed -(void)draw:(UIImage *)image{} so that it changes the image correctly.

+1
source

if you want to pass the touch function to the second graph (large), I think you can do something like this

on .h you have to declare the images you are going to drag and swim to remember the previous point of the button to move (I assume that you are using the iOS 5 SDK)

 @property(nonatomic, strong) UIImageView* myImage; @property float pointX; @property float pointY; 

then in .m you can do it

 myImage = [[UIImageView alloc]initWithImage:@"appleImage.jpg"]; myImage.alpha = 0; //default UIImageView interaction is disabled, so lets enabled it first myImage.userInteractionEnabled = YES; [button addTarget:self action:@selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside]; 

and then perform the drag and drop function

 - (void)wasDragged:(UIButton *)button withEvent:(UIEvent *)event { self.myImage.alpha = 0.5; UITouch *touch = [[event touchesForView:button] anyObject]; 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, to keep the dragging effect button.center = CGPointMake(button.center.x + delta_x, button.center.y + delta_y); // moving the image button.center = CGPointMake(button.center.x + delta_x, button.center.y + delta_y); self.pointX = previousLocation.x; self.pointY = previousLocation.y; [button addTarget:self action:@selector(dragRelease:withEvent:) forControlEvents:UIControlEventTouchUpInside]; } 

finally, make the dragRelease function, in which you return the button to its original place and set the alpha of the images to 1

 -(void)dragRelease:(UIButton *)button withEvent:(UIEvent *)event { self.myImage.alpha = 1; button.center = CGPointMake(pointX, pointY); } 

and you're done: 3

this is just the main idea, maybe this is not what you want, but I hope this helps

edit *: oh and do not forget to synthesize all the properties, also if you use the SDK below 5.0, you can change the "strong" property to "save"

0
source

Source: https://habr.com/ru/post/1390334/


All Articles