How to Programmatically Remove A UIImageView By touchGesture - ios

Ok, so I have been looking forever on how to use UITouchGestures with UIImageViews to remove the View, but everything either didn't make sense or didn't work so I finally decided to ask the question. How do you use A UITapGestureRecognizer to remove a UIImageView when it is tapped?
This is my .m:
- (void)viewDidLoad
{
[super viewDidLoad];
//this makes a zombie/person
UIImageView *ZombieView =[[UIImageView alloc] initWithFrame: CGRectMake(135 , -100, 50, 75)];
UIImage *Zombie=[UIImage imageNamed:#"free-vector-stick-figure-clip-art_105575_Stick_Figure_clip_art_hight.png"];
[ZombieView setImage:Zombie];
//[self.view addSubview:ZombieView];
[self.view insertSubview:ZombieView belowSubview:_Railing];
[ZombieView setUserInteractionEnabled:TRUE];
// double tap gesture recognizer
UITapGestureRecognizer *Touch2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped2:)];
[Touch2 setDelegate: self];
[Touch2 setNumberOfTapsRequired: 2];
[_ZombieView addGestureRecognizer:Touch2];
UITapGestureRecognizer *Touch = [[UITapGestureRecognizer alloc] initWithTarget:ZombieView action:#selector(tapped:)];
[Touch setDelegate:self];
[Touch setNumberOfTapsRequired: 1];
[Touch requireGestureRecognizerToFail: Touch2];
[_ZombieView addGestureRecognizer:Touch];
//This makes the Person move down until he is behind the railing
[UIView animateWithDuration:7.5
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
CGAffineTransform trans = CGAffineTransformTranslate(ZombieView.transform, 0, 420);
ZombieView.transform=trans;
}
completion:nil];}
-(void) tapped:(UITapGestureRecognizer *)recognizer{
[_ZombieView removeFromSuperview];
}
-(void) tapped2:(UITapGestureRecognizer *)recognizer{
}
-(void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I know it must be a disaster, but I am fairly new to this so please keep this in mind. I just need know how to use the Tap Recognizers and how to delete a UIImageView, but other tips are appreciated. Thank you!
This is my edited code:
#interface AbcViewController ()
#end
#implementation AbcViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//this makes a zombie/person
UIImageView *zombieView =[[UIImageView alloc] initWithFrame: CGRectMake(135 , -100, 50, 75)];
UIImage *zombie=[UIImage imageNamed:#"free-vector-stick-figure-clip-art_105575_Stick_Figure_clip_art_hight.png"];
[zombieView setImage:zombie];
//[self.view addSubview:zombieView];
[self.view insertSubview:zombieView belowSubview:_Railing];
[zombieView setUserInteractionEnabled:TRUE];
//This makes the Person move down until he is behind the railing
[UIView animateWithDuration:7.5
delay:0.0
options: UIViewAnimationOptionCurveLinear
animations:^{
CGAffineTransform trans = CGAffineTransformTranslate(zombieView.transform, 0, 420);
zombieView.transform=trans;
}
completion:nil];
// double tap gesture recognizer
UITapGestureRecognizer *touch2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped2:)];
[touch2 setDelegate: self];
[touch2 setNumberOfTapsRequired: 2];
[zombieView addGestureRecognizer:touch2];
UITapGestureRecognizer *touch = [[UITapGestureRecognizer alloc] initWithTarget:zombieView action:#selector(tapped:)];
[touch setDelegate:self];
[touch setNumberOfTapsRequired: 1];
[touch requireGestureRecognizerToFail: touch2];
[zombieView addGestureRecognizer:touch];
}
-(void) tapped:(UITapGestureRecognizer *)recognizer{
[recognizer.view removeFromSuperview];
}
-(void) tapped2:(UITapGestureRecognizer *)recognizer{
[recognizer.view removeFromSuperview];
}
-(void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

A tap gesture recognizer has a view property that points to the view it's attached to. So, in the action method for the recognizer, use it to remove itself from its superview,
-(void) tapped:(UITapGestureRecognizer *)recognizer{
[recognizer.view removeFromSuperview];
}
It's hard to tell why your method isn't working. It could be because _ZombieView is nil (I don't see anywhere you actually create _ZombieView as opposed to ZombieView which you do create). BTW, you should start your property and variable names with a lowercase letter to conform to the usual objective-c naming conventions.

Related

Keyboard Down in IOS

I have some textfield in which when i click it shows me keyboard , but when i click anywhere on the page the keyboard do not disappears . This is my code for resign of first responder. Whats wrong in my code.
Add this code:
-(void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapReceived:)];
[tapGestureRecognizer setDelegate:self];
[self.view addGestureRecognizer:tapGestureRecognizer];
}
-(void)tapReceived:(UITapGestureRecognizer *)tapGestureRecognizer
{
[textField resignFirstResponder];
}
Create iVar for UIGestureRecognizer
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
Dismiss what ever is currently editing:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Try this code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
[aTextField resignFirstResponder];
}
}
Or
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
[self.view endEditing:YES];
}
}
- (void)viewDidLoad {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
-(void)dismissKeyboard {
[yourtextfield resignFirstResponder];
}
Add Tap Gesture on your Top View
you you havn't any subview which may hide your Root view
than only use self.view
if you are using ScrollView than add TapGesture on your ScrollView
-(void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDissmiss:)];
[self.view addGestureRecognizer: tap];
}
Handle Tap Gesture
-(void)tapDissmiss:(UITapGestureRecognizer *)tapGestureRecognizer
{
[self.view endEditing:YES];
}
Create one UITapGestureRecognizer as a class variable.
#interface ViewController() {
UITapGestureRecognizer *tapGesture;
}
- (void)viewDidLoad {
[super viewDidLoad]
tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(dismissKeyboard)];
}
Add gesture on textfield delegates textFieldDidBeginEditing, And remove it on textFieldDidEndEditing.
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self.view addGestureRecognizer:_tapGesture];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[self.view removeGestureRecognizer:_tapGesture];
}
Implement tap gesture selection
- (void)dismissKeyboard {
[self.view endEditing:YES];
}

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

Zoom with touches in a custom view in a scrollView. touchesMoved not called

I have a custom view that will pinch zoom, but I'd like to also slide it around in any direction. The zoom works well, and the moving works well, but so far it's just one or the other. The touchesMoved method never gets called.
The scrollView has a subView which the user will touch and move. It will function like a little map. On the subView are several custom labels. I have a tap Gesture recognizer on the labels, which works fine now, and will still need to work when the zoom and moving is corrected.
I also tried [scrollView setScrollEnabled:NO]; and other things, but that didn't allow both to work. How can touches Moved be called? What will I need to do to allow both to work?
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view setUserInteractionEnabled:YES];
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[scrollView setMinimumZoomScale:.7];
[scrollView setMaximumZoomScale:1.5];
[scrollView setAutoresizesSubviews:YES];
[scrollView setUserInteractionEnabled:YES];
scrollView.delegate = self;
[self.view addSubview:scrollView];
CGRect mapFrame = CGRectMake(0, 0, 300, 300);//temp numbers
subView = [[UIView alloc]initWithFrame:mapFrame];
subView.userInteractionEnabled=YES;
subView.autoresizesSubviews=YES;
[scrollView addSubview:subView];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touchesMoved");
touch = [touches anyObject];
CGPoint location = [touch locationInView:subView];
CGPoint prevLoc = [touch previousLocationInView:subView];
CGPoint origin = subView.frame.origin;
origin.x += (location.x - prevLoc.x);
origin.y += (location.y - prevLoc.y);
CGRect newFrame = subView.frame;
newFrame.origin = origin;
subView.frame = newFrame;
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return subView;
}
//label sample
newCity =[[MyCustomClass alloc] initWithFrame:CGRectMake(x, y, 95, 40)];
newCity.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(touchUp:)];
[newCity addGestureRecognizer:tapGesture];
[subView addSubview:newCity];
I'm also getting this in the log and don't know why. "Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] since gesture recognizer is not active.
" I removed the pan gesture recognizer, after that didn't work. I'm using Xcode 4.5.2
My header is
#interface CitiesViewController : UIViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
{
UIView *subView;
}
#property(nonatomic, strong) UIView *subView;
#property(nonatomic, strong) UIScrollView *scrollView;
To solve this I removed the TouchesMoved entirely and used a panGestureRecognizer instead. Hopefully it helps someone.
I added this to my subView:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[pan setDelegate:self];
[subView addGestureRecognizer:pan];
Add this method:
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:subView];
subView.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
}
I never did figure out why that message Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] is still occurring, but this seems to work.

Stop and start an animation by touch. Objective C

I have made an animation that moves across the screen, my animation loops continuously. How can I stop the animation when you tap the animated image, Then let the animation continue when you lift the touch?
I know how to use TouchesMoved to move a specified button like this:
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
But getting it to work with my animation. I would like the animation to continue after I touch it.
SelectedCellViewController.h
// SelectedCellViewController.h
#import <Accounts/Accounts.h>
#import <QuartzCore/QuartzCore.h>
#interface SelectedCellViewController : UIViewController {
IBOutlet UIImageView *imageView;
UIImageView *rocket;
}
#end
viewControllertoShow.m
#import "SelectedCellViewController.h"
#interface SelectedCellViewController ()
#end
#implementation SelectedCellViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:#selector(imageSpawn:) withObject:nil afterDelay:3];
}
- (void) imageSpawn:(id) sender
{
UIImage* image = [UIImage imageNamed:#"ae"];
rocket = [[UIImageView alloc] initWithImage:image];
rocket.frame = CGRectMake(-25, 200, 25, 40);
[UIView animateWithDuration:5
delay:0.2f
options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^(){rocket.frame=CGRectMake(345, 200, 25, 40);}
completion:^(BOOL fin) {
}];
[self.view addSubview:rocket];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(ballTapped:)];
tapped.numberOfTapsRequired = 1;
[rocket addGestureRecognizer:tapped];
[rocket setUserInteractionEnabled:YES];
}
-(void)ballTapped:(UIGestureRecognizer *)gesture
{
CGPoint location = [gesture locationInView:gesture.view];
//then write code to remove the animation
[self.view.layer removeAllAnimations];
NSLog(#"Tag = %d", gesture.view.tag);
rocket.frame = CGRectMake(location.x,location.y,25,40);
}
- (void)dismissView {
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (void)viewDidUnload {
}
#end
As you had already stated in your question ,you can get the touched point using
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
Then check check whether this point lies inside the coordinates of the animated UIImageview and then stop animation.
But if you are using scrollview, you won't be able to use this because scrollview will not return any UIView touch events.
As your image view is animating, a better choice will be adding a UITapGestureRecogniser to the image view when you add it s subview, like this
- (void) imageSpawn:(id) sender
{
UIImage* image = [UIImage imageNamed:#"ae"];
UIImageView *rocket = [[UIImageView alloc] initWithImage:image];
rocket.frame = CGRectMake(-25, 200, 25, 40);
[UIView animateWithDuration:5
delay:0.2f
options:UIViewAnimationCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
animations:^(){rocket.frame=CGRectMake(345, 200, 25, 40);}
completion:^(BOOL fin) {
}];
[myScrollView addSubview:rocket];
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(ballTapped:)];
tapped.numberOfTapsRequired = 1;
[self.rocket addGestureRecognizer:tapped];
[rocket setUserInteractionEnabled:YES];
}
And in the target function write code to stop the animation:
-(void)ballTapped:(UIGestureRecognizer *)gesture
{
//here also you can get the tapped point if you need
CGPoint location = [gesture locationInView:gesture.view];
//then write code to remove the animation
[self.view.layer removeAllAnimations];
}
EDIT:
If you are trying to stop the image view at the touched point, you can add this to ballTapped event:
rocket.frame = CGRectMake(location.x,location.y,25,40);
But for this you have to declare UIImageView *rocket outside this particular method, i.e. declare to in your header file.
Another way is to add this to the parent view of the animation -
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
self.animating = NO;
return [super hitTest:point withEvent:event];
}
use an (atomic) property, then check the property in the animation to see if it should be stopped. We use this to stop a photo gallery which is running so that the user can manually move the photos. You could also check in here if the point is in a specific area if necessary. This method runs before any touch methods are called.
try like this may be it helps you, in the middle of the animation if you touch on the imageview then animation removes from the view .
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [[event allTouches] anyObject];
CGPoint lastLocation = [touch locationInView: self.view];
if([[touch view] isKindOfClass:[UIImageView class]]){
[youImageView.layer removeAllAnimations];
youImageView.center=lastLocation;//assign your image view center when the animation removes from the view.
}
}
and add #import <QuartzCore/QuartzCore.h> framework.

Attach GestureRecogniser to multiple imageviews

Something strange I encountered today while attaching same gesture recogniser to multiple image views. It gets attached to only the last one, in other words, it can be attached to only one view!
I had to create multiple gesture recognisers to meet my requirements.
Following is what I have done. Am I doing correct? Is that's the only way to attach recognisers to the multiple imageviews?
Please note that I don't want to use UITableView or UIVIew and put all imageviews in it and attach gesture recogniser to only UITableView or UIVIew. I have all image scattered and I have to detect which image is being dragged. Thanks.
[imgView1 setUserInteractionEnabled:YES];
[imgView1 setMultipleTouchEnabled:YES];
[imgView2 setUserInteractionEnabled:YES];
[imgView2 setMultipleTouchEnabled:YES];
[imgView3 setUserInteractionEnabled:YES];
[imgView3 setMultipleTouchEnabled:YES];
[imgView4 setUserInteractionEnabled:YES];
[imgView4 setMultipleTouchEnabled:YES];
[imgView5 setUserInteractionEnabled:YES];
[imgView5 setMultipleTouchEnabled:YES];
[imgView6 setUserInteractionEnabled:YES];
[imgView6 setMultipleTouchEnabled:YES];
//Attach gesture recognizer to each imagviews
gestureRecognizer1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer1.delegate = self;
gestureRecognizer2 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer2.delegate = self;
gestureRecognizer3 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer3.delegate = self;
gestureRecognizer4 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer4.delegate = self;
gestureRecognizer5 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer5.delegate = self;
gestureRecognizer6 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
gestureRecognizer6.delegate = self;
[imgView1 addGestureRecognizer:gestureRecognizer1];
[imgView2 addGestureRecognizer:gestureRecognizer2];
[imgView3 addGestureRecognizer:gestureRecognizer3];
[imgView4 addGestureRecognizer:gestureRecognizer4];
[imgView5 addGestureRecognizer:gestureRecognizer5];
[imgView6 addGestureRecognizer:gestureRecognizer6];
Yes, one view per gesture recognizer. So if you want only one recognizer, put it on the superview, e.g.:
UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
[self.view addGestureRecognizer:gestureRecognizer];
And then, in your handler, you can:
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender
{
CGPoint location = [sender locationInView:self.view];
if (sender.state == UIGestureRecognizerStateBegan)
{
for (UIView *view in self.view.subviews)
{
if ([view isKindOfClass:[UIImageView class]] && CGRectContainsPoint(view.frame, location))
{
UIImageView *image = (UIImageView *) view;
// ok, now you know which image you received your long press for
// do whatever you wanted on it at this point
return;
}
}
}
}
By the way, if you do that, you don't need to worry about enabling user interaction on the images, either.
Finally, you don't need to worry about specifying your gesture recognizer's delegate unless you're going to conform to UIGestureRecognizerDelegate, which this isn't. Also note that I'm using a local var for my recognizer because there's no reason to hang onto it.
Update:
While the above code works fine, perhaps even better would be a custom long press gesture recognizer that would fail if the long press didn't take place over an image (this way it's more likely to play well in case you have other gesture recognizers taking place in your view). So:
#import <UIKit/UIGestureRecognizerSubclass.h>
#interface ImageLongPressGestureRecognizer : UILongPressGestureRecognizer
#property (nonatomic, weak) UIImageView *imageview;
#end
#implementation ImageLongPressGestureRecognizer
#synthesize imageview = _imageview;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
self.imageview = nil;
[super touchesBegan:touches withEvent:event];
CGPoint location = [self locationInView:self.view];
for (UIView *view in self.view.subviews)
{
if ([view isKindOfClass:[UIImageView class]] && CGRectContainsPoint(view.frame, location))
{
self.imageview = (UIImageView *)view;
return;
}
}
self.state = UIGestureRecognizerStateFailed;
}
#end
then create your gesture recognizer accordingly, using this new subclass:
ImageLongPressGestureRecognizer *gestureRecognizer = [[ImageLongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleLongPress:)];
[self.view addGestureRecognizer:gestureRecognizer];
and then, as a nice little benefit of this subclassing, your main gesture recognizer is simplified, namely:
- (void)handleLongPress:(ImageLongPressGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan)
{
// you can now do whatever you want with sender.imageview, e.g. this makes it blink for you:
[UIView animateWithDuration:0.5
animations:^{
sender.imageview.alpha = 0.0;
} completion:^(BOOL finished){
[UIView animateWithDuration:0.5
animations:^{
sender.imageview.alpha = 1.0;
}
completion:nil];
}];
}
}
You can't attach a gesture recognizer to more than one object (as you discovered). One solution to what you are doing might be to subclass UIImageView and have setup code in that class so each view creates its recognizer, etc.
I guess, first of all, you should make an array of views and array of recognizers (mutable array, if needed) and then populate it. It will help you to use cycles to avoid code duplication.
As for multiple view with one recognizer - no, it's not possible, answered here.

Resources