I'm working on an app in which you add different images from gallery to the view you can drag them around and if you press long on an image it should delete it. The new imported image is placed in a CGRect and then the functionality of drag and longpress is applied to it.
My question is from my delete code, deletion is working but it only delete the last inserted image.
self.myImageView = [[Draggable alloc]initWithFrame:cellRectangle];
[self.myImageView setImage:self.myImage];
[self.myImageView setUserInteractionEnabled:YES];
[self.myImageView setTranslatesAutoresizingMaskIntoConstraints:YES];
[self.myImageView setPreservesSuperviewLayoutMargins:YES];
[self.customCam addSubview:self.myImageView];
This code is allocating draggable class to a UIImageView which is used to drag the image around the screen. Below is the long press gesture code:
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(activateDeletionMode:)];
longPress.delegate = self;
longPress.minimumPressDuration = 1.0;
[self.myImageView addGestureRecognizer:longPress];
and activateDeletionMode code is below
- (void)activateDeletionMode:(UILongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan)
{
[self.myImageView removeFromSuperview];
NSLog(#"This Runs");
}
}
With only one image inserted it works fine. But if I insert 2 images at the same time it delete the latest inserted image and didn't perform the removeFromSuperviewon second image.
You should add a new longpress gesture for every imageView.
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]];
}
i want to show up images in my view and add the tap gesture to do some stuff.
My code looks like this for the image creation
for(int i = 0; i < 5; i++) {
UIImageView *imageToMove =
[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"icon1.png"]];
imageToMove.frame = CGRectMake(((float)rand() / RAND_MAX) * 1024, ((float)rand() / RAND_MAX) * 768 , 95, 95);
[imageToMove setUserInteractionEnabled:YES];
[imageToMove addGestureRecognizer:singleTap];
[self.view addSubview:imageToMove];
}
and this simple function to get some feedback when a image is tapped
- (void)tapDetected {
NSLog(#"single Tap on imageview");
}
My Problem is, only one (IMHO the last one added) image is touchable. The other images "behind" can't be accessed.
Is there a possibility to solve this?
It is not entirely clear what you would like to do when tapping on stacked images (I mean, the natural thing would be that the image you touch can move, and this is should be accomplished by your code); in any case, try with:
singleTap.cancelsTouchesInView = NO;
This will make your gesture recognizers not cancel the tap they handle, so the holding view will also receive the events. If this does not help, have a look at the UIGestureRecognizerDelegate protocol and specifically at the method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer
which should allow to fine-control how your gesture recognizers co-exist.
using: objective-C
I have a tableView with rows. I want that user can move cell a little aside and additional action shown to him.
What was done:
Currently create separately table in xib file and cell in xib file.
Cell is very simple
I want to move viewWIthLabel.
In cell class file for using animation I use next code
- (void)awakeFromNib
{
UISwipeGestureRecognizer * leftGestrudeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeLeft:)];
leftGestrudeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer * rightGestrudeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeRight:)];
rightGestrudeRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:rightGestrudeRecognizer];
[self addGestureRecognizer:leftGestrudeRecognizer];
}
and actions:
- (IBAction)swipeLeft:(id)sender{
NSLog(#"swipeL");
[UIView animateWithDuration:0.5 animations:^{
self.viewWIthLabel.frame = CGRectMake(-100, 0, self.viewWIthLabel.frame.size.width, self.viewWIthLabel.frame.size.height);
} ];
}
- (IBAction)swipeRight:(id)sender{
NSLog(#"swipeR");
[UIView animateWithDuration:.5 animations:^{
self.viewWIthLabel.frame = CGRectMake(0, 0, self.viewWIthLabel.frame.size.width, self.viewWIthLabel.frame.size.height);
}];
}
So idea to swipe the cell and move it with animation for some distance to show a hidden button.
Result of this code - almoust like I want:
But if you start to scroll the tableView you can get duplicates of "swiped cells" in random (depending on scrolling speed) positions:
Any idea why it happened?
You might have to clear/reset the swiped state of the cell in – tableView:cellForRowAtIndexPath:. Since the cells get re-used (I am assuming you are doing that as would be required for good performance of the tableview). Probably something like this -
self.viewWIthLabel.frame = CGRectMake(0, 0, self.viewWIthLabel.frame.size.width, self.viewWIthLabel.frame.size.height);
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
I have an ImageView with a png and I want to do this: when someone touch this imageview it's alpha change to 0.0, is it possible? (all without buttons)
you can use UITapGestureRecognizer added to the UIImageView via addGestureRecognizer
snippets:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageTaped:)];
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[iv addGestureRecognizer:singleTap];
[iv setUserInteractionEnabled:YES];
and
- (void)imageTaped:(UIGestureRecognizer *)gestureRecognizer {
[UIView animateWithDuration:0.5 animations:^(void){
imageView.alpha = 0.0f;
}];
}
Yes, it is possible. For example you can do that with following steps:
set image view's userInteractionEnabled property to YES - so it will receive touch events
add UITapGestureRecongnizer to it
in gesture handler set view's alpha to 0.0, you can do that with animation as well:
[UIView animateWithDuration:0.5 animations:^(void){
imageView.alpha = 0.0f;
}];
There are already lots of questions like this. Searching with google gave me the following:
touches event handler for UIImageView
UIImageView Touch Event
how can i detect the touch event of an UIImageView
The code in Swift
In my case I implemented the tap gesture for an image click
1 - Link the image with the ViewController, by drag and drop
#IBOutlet weak var imgCapa: UIImageView!
2 - Instance the UITapGestureRecognizer in ViewDidLoad method:
override func viewDidLoad() {
super.viewDidLoad()
//instance the UITapGestureRecognizer and inform the method for the action "imageTapped"
var tap = UITapGestureRecognizer(target: self, action: "imageTapped")
//define quantity of taps
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
//set the image to the gesture
imgCapa.addGestureRecognizer(tap)
}
3 - Create the method to do what do you want when the image clicked
func imageTapped(){
//write your specific code for what do you want
//in my case I want to show other page by specific segue
let sumario = self.storyboard?.instantiateViewControllerWithIdentifier("sumarioViewController") as SumarioViewController
self.performSegueWithIdentifier("segueSumarioViewController", sender: sumario)
}
In recent Xcode, this is pretty easy. Go into the storyboard, in the object library search for "gesture", drag the one you want onto the image view. You can then treat the gesture object in the view hierarchy as the thing being tapped, i.e. control-drag from there to your view controller to connect the event handler.
Once there you can set the alpha as you like, although if you're trying to essentially remove the image view, you should set imageView.hidden = true / imageView.hidden = YES instead, because that will stop it receiving events.