UIGestureRecognizer not recognizing - ios

I was trying to create a label that should be draggable. But the dragged event is not firing (checked with break point). Below is the code.
- (IBAction)InsertText:(UIBarButtonItem *)sender {
UILabel *lblWatermark = [[UILabel alloc] initWithFrame:currentImage.frame];
lblWatermark.text = #"Copyright";
lblWatermark.userInteractionEnabled = YES;
[lblWatermark sizeToFit];
UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:#selector(labelDragged:)];
[lblWatermark addGestureRecognizer:gesture];
[currentImage addSubview:lblWatermark];
}
- (void)labelDragged:(UIPanGestureRecognizer *)gesture
{
UILabel *label = (UILabel *)gesture.view;
CGPoint translation = [gesture translationInView:label];
// move label
label.center = CGPointMake(label.center.x + translation.x,
label.center.y + translation.y);
[gesture setTranslation:CGPointZero inView:label];
}
Thank you in advance,

Spotted the error. Actually I had also to make
userInteractionEnabled = YES
Not only for the label But also for the Imageview in which I am adding the label.

Make sure your ViewController is the delegate for UIGestureRecognizer with (.h file):
#interface View : UIView <UIGestureRecognizerDelegate>
And then set:
gesture.delegate = self;

Related

Xcode Application drag or move label

I want to drag my label in Application. I create new label when starting Application
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 100)];
myLabel.text = #"DRAG ME!!!";
[self.view addSubview:myLabel];
How can I drag this label? I can't find normal tutorial and i new in Xcode...
The following implementation may help you. Change your above label with this one and you can see that now your label is draggable.
#import "DraggableLabel.h"
#interface DraggableLabel()
{
CGPoint _previousLocation;
}
#end
#implementation DraggableLabel
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.userInteractionEnabled = YES;
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(handlePan:)];
self.gestureRecognizers = #[panRecognizer];
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.superview bringSubviewToFront:self];
_previousLocation = self.center;
}
- (void)handlePan:(UIPanGestureRecognizer *)panGestureRecognizer
{
CGPoint translation = [panGestureRecognizer translationInView:self.superview];
self.center = CGPointMake(_previousLocation.x + translation.x,
_previousLocation.y + translation.y);
}
#end

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!

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.

Changing the text of a uilabel then add new uilabel

I want to change the text of a label, then have the user move it to where they want it on the screen (which is currently working) (the user hits - "Add text").
Once they place it where they would like. I want the "Add text" button to create a new label that the user can move. I'm not sure how to create these on the fly an to make sure that the gesture recognizers function with the new label. Thanks for suggestions.
This is what I have now,,, doesn't work quite yet.
-(IBAction)addText:(id)sender
{
textView.hidden=YES;
labelShirt.text= textField.text;
[textField resignFirstResponder];
[self addTextButtonPressed];
}
-(void)addTextButtonPressed
{
// CGRect *textFrame =
// myInitialFrame is a CGRect you choose to place your label
UILabel *myNewLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,50,100,100)];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(labelMoved:)];
myNewLabel.text =textField.text;
[self.view addSubview:myNewLabel];
}
-(void)labelMoved:(UIPanGestureRecognizer *)sender
{
CGPoint translation = [sender translationInView:self.view];
sender.view.frame = CGRectOffset(sender.view.frame, translation.x, translation.y);
}
// The action that is added to your add text button
-(void)addTextButtonPressed
{
// myInitialFrame is a CGRect you choose to place your label
UILabel *myNewLabel = [[UILabel alloc] initWithFrame:myInitialFrame];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:#selector(labelMoved:)];
myNewLabel.text = #"My initial text";
// EDIT
[self.view addSubview:myNewLabel];
[myNewLabel addGestureRecognizer:panGestureRecognizer];
}
-(void)labelMoved:(UIPanGestureRecognizer *)sender
{
CGPoint translation = [sender translationInView:self.view];
sender.view.frame = CGRectOffset(sender.view.frame, translation.x, translation.y);
}
I don't know if that's enough to solve your problem, just comment if you still need more explanation.

Resources