I am facing problem with UIPanGestureRecognizer. suppose i am adding 10 button dynamicaly using diffrent tags when i add first button the try to drag it to other place then its works fine. and then if i add other button then try to drag that second button then even its works fine but if then i would lyk to drag first button then it not being draged and. and message shown in log is Ignoring call to [UIPanGestureRecognizer setTranslation:inView:] since gesture recognizer is not active.
gesture is working only on recently added button. below is the code that i am using
Here is code to add buttons
NSUInteger counter = 1;
if([ButtonArray count] !=0 ){
NSLog(#"%d",[ButtonArray count]);
NSLog(#"hi");
counter = [ButtonArray count] + 1;
}
[ButtonArray addObject:[NSString stringWithFormat:#"%d",counter]];
NSLog(#"%d",1);
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setTag:counter];
btn.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
//[btn addTarget:self action:#selector(Dragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
//[self.view addSubview:btn];
btn.userInteractionEnabled = YES;
gesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:#selector(labelDragged:)];
[btn addGestureRecognizer:gesture];
// add it
[self.view addSubview:btn];
here is code for gesture
UIButton *button = (UIButton *)gesture.view;
CGPoint translation = [gesture translationInView:button];
// move button
button.center = CGPointMake(button.center.x + translation.x,
button.center.y + translation.y);
// reset translation
[gesture setTranslation:CGPointZero inView:button];
I suspect the problem comes down to this:
gesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:#selector(labelDragged:)];
I tend to think from your code that gesture is some property in your class. In this case you are constantly overriding the old gesture when you create a new one. That would also explain the behavior you describe.
EDIT:
you do not strictly need to store your gesture recognizers in a property; it would be enough to do:
UIPanGestureRecognizer* localgesture = [[UIPanGestureRecognizer alloc]
initWithTarget:self
action:#selector(labelDragged:)];
[btn addGestureRecognizer:localgesture];
then, when the labelDragged method is called, you can use its recognizer argument to know which gesture recognizers fired:
- (void)labelDragged:(UIGestureRecognizer *)gestureRecognizer;
Related
I have a UIButton on which I attached an UIControlEventTouchUpInside action. This button is inserted in a UIScrollView.
My problem is: touch events won't work until I hold on the button for a certain time. If I tap on it directly, or just click on it in the simulator, it won't work.
The thing is: when I just click on it, pointInside:withEvent: is actually triggered and returns YES. What could possibly prevent the event from being fired?
Try setting the delaysContentTouches property of your scrollView to NO.
It should work so you can check the following eg.:
1) make sure that you button is properly added to scrollview. For example like this:
...
myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
myScrollView.bounces = NO;
[myScrollView setScrollEnabled:YES];
myScrollView.showsHorizontalScrollIndicator = NO;
myScrollView.delegate = self;
myScrollView.pagingEnabled = YES;
[self.view addSubview:myScrollView];
myScrollView.contentSize = CGSizeMake(320*5, 480);
...
UIButton *mybutton = [UIButton buttonWithType:UIButtonTypeCustom];
mybutton.frame = CGRectMake(0,0,100,100);
mybutton.tag = 1
[mybutton addTarget:self action:#selector(pressedmybutton:)
forControlEvents:UIControlEventTouchUpInside];
[myScrollView addSubview:bu];
2) make sure that button is top of the view stack. For testing purpose add at the end of the view init code [mybutton bringSubviewToFront];
3) test it on device and not just in Simulator. I experienced different scrolling/button pressing behavior in Simulator than on real device (which is the better for testing this out).
i have 2 uibutton and 1 label and longpressgesture is bounded to these control. when longpress is taken place on any control then how to get the object on which longpress is taken place below is the code that i have written.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[btn addTarget:self action:#selector(wasDragged:withEvent:) forControlEvents:UIControlEventTouchDragInside];
//[self.view addSubview:btn];
btn.userInteractionEnabled = YES;
// add it
[self.view addSubview:btn];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = 1.0;
[btn addGestureRecognizer:longPress];
below is function that is called on longpress
-(void)handleLongPress:(id)sender{
}
if i printing description of sender then i get
<UILongPressGestureRecognizer: 0x6aa4480; state = Began; view = <UIRoundedRectButton 0x6aa9570>; target= <(action=handleLongPress:, target=<ViewController 0x6a8cc60>)>>
from it how can i get the refrence of object on whcih longpress event takes place
i mean how do i know whether i preessed UiLabel or Uibutton?
Just check the UIGestureRecognizer's (the parent class) view property:
#property(nonatomic, readonly) UIView *view
The view the gesture recognizer is attached to. (read-only)
#property(nonatomic, readonly) UIView *view
Discussion
You attach (or add) a gesture recognizer to a UIView object using the addGestureRecognizer: method.
-(void)handleLongPress:(UILongPressGestureRecognizer *)sender{
if ([sender.view isKindOfClass:[UIButton class]]) {
UIButton *myButton = (UIButton *)sender.view; // here is your sender object or Tapped button
if (myButton.tag == 1) {
//sender is first Button. Because we assigned 1 as Button1 Tag when created.
}
else if (myButton.tag == 2){
//sender is second Button. Because we assigned 2 as Button2 Tag when created.
}
}
if ([sender.view isKindOfClass:[UILabel class]]) {
UILabel *myLabel = (UILabel *)sender.view; // here is your sender object or Tapped label.
}
}
I have implemented UITapGestureRecognizer on UIImageView, It is working on first tap. On First Tap, I am hiding that image and starting animation. Once the animations are completed, i am showing the image again. But After setting setHidden:FALSE, I am not getting the Tap event of that UIImageView.
Following is the code I am using :
- (void)viewDidLoad{
[super viewDidLoad];
defaultDogView= [[UIImageView alloc] initWithFrame:CGRectMake(3, 270, 110, 210)];
[defaultDogView setImage:[UIImage imageNamed:#"dog1.png"]];
defaultDogView.userInteractionEnabled = YES;
[self addGestureRecognizersToPiece:defaultDogView];
[self.view addSubview:defaultDogView];
}
- (void)addGestureRecognizersToPiece:(UIImageView *)piece
{
NSLog(#"in Gesture");
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapPiece:)];
[tapGesture setDelegate:self];
[piece addGestureRecognizer:tapGesture];
[tapGesture release];
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressPiece:)];
[piece addGestureRecognizer:longPressGesture];
[longPressGesture release];
NSLog(#"%#", [piece gestureRecognizers]);
}
- (void)singleTapPiece:(UITapGestureRecognizer *)gestureRecognizer
{
NSLog(#"Image Tapped");
/** Hide the default Image and start the animation ***/
[defaultDogView setHidden:TRUE];
/***Animating the Dog***/
[dogArray addObject:[SpriteHelpers setupAnimatedDog:self.view numFrames:69 withFilePrefix:#"dog" withDuration:(12) ofType:#"png" withValue:0]];
dogView = [dogArray objectAtIndex:0];
//[self addGestureRecognizersToPiece:dogView];
[self performSelector:#selector(callBubbleUpdater) withObject:nil afterDelay:5.5];
}
-(void)showDogFrame{
NSLog(#"%#",[defaultDogView gestureRecognizers]);
[defaultDogView setHidden:FALSE];
defaultDogView.userInteractionEnabled = YES;
}
When view is hidden or its alpha component is zero that view won't receive any UIGestureRecognizers.
I can suggest to use next approach if you need to hide some view (let's name it touchableView) but want it to respond to gestures:
Create backgroundView with the same frame as touchableView:
UIView *backgroundView = [[UIView alloc] initWithFrame:touchableView.frame];
Set background color of backgroundView to clearColor:
backgroundView.backgroundColor = [UIColor clearColor];
Reset position of touchableView:
CGRect frame = touchableView.frame;
frame.origin.x = 0;
frame.origin.y = 0;
Disable user interaction of touchableView:
touchableView.userInteractionEnabled = NO;
Add touchableView as subview to backgroundView:
[backgroundView addSubview:touchableView];
Add appropriate gesture recognizers to backgroundView.
Add backgroundView to view that you want.
Now you can hide touchableView but you will still receive gesture recognizers.
I don't test this but I think it should work.
sure
when UIImageView is hidden. it does not receive any touch events
set alpha zero for uiimageview
I'm dynamically adding image buttons to some scrollview. They all point at one longPressHandler. Now, how do I get which button was pressed? The [sender tag] gives me the tag of longGestureRecognizer that I added to button and I can't manually set that tag.
for (...) {
UIButton *button = [[UIButton alloc] init];
button.tag = w + h * 3;
[button addTarget:self action:#selector(imageButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *gest = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(imageButtonLongPress:)];
gest.minimumPressDuration = 1;
gest.delegate = self;
[button addGestureRecognizer:gest];
[gest release];
[scrollView addSubview:button];
[button release];
}
- (void) imageButtonLongPress:(id)sender {
// how to get button tag here?
}
There is a view property in the UIGestureRecognizer which returns the view that recognizer is attached to. I think that is your best bet.
- (void) imageButtonLongPress:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender;
int tag = recognizer.view.tag;
}
In your action you have to type cast your sender in gesture and then type cast its view to a button then get button's tag as -
UILongPressGestureRecognizer *gest = (UILongPressGestureRecognizer *)sender;
UIButton *button = (UIButton*)[gest view];
NSLog(#"%d",[button tag]);
is there any way to hide an UIButton until the UIImageView is pressed??
When the picture is pressed I need to show the back Button, like it works at the Photo App on the iPhone???
Here is the code of my UIButton:
- (void)viewDidLoad {
[super viewDidLoad];
[self ladeImage];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(10, 10, 40, 40);
[btn addTarget:self action:#selector(goToViewA) forControlEvents:UIControlEventTouchUpInside];
[btn setTitle:#"<<" forState:UIControlStateNormal];
[self.view addSubview:btn];
}
First step : btn.hidden = YES
Then you have to subclass the UIImageView to react to its touchesEnded: event and change the hidden property of your button there. For that, the proper way is to create a protocol (with a viewTouched method). Implement that protocol in the viewController containing your button and you ImageView. Add a delegate propery to the subclassed ImageView (i.e. id<MyCustomProtocol> _delagate;) and assign the view controller to this propery.
btn.hidden = YES;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image name"]];
imageView.userInteractionEnabled = YES; // here to enable touch event
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGestureRecongizer:)]; // handleTapGestureRecongizer is method will call when tap even fire
[imageView addGestureRecognizer:tap]; // Add Tap gesture recognizer to image view
[tap release], tap = nil;
[self.view addSubview:imageView];
[imageView release], imageView = nil;
Method handlerTapGestureRecognizer:
- (void)handleTapGestureRecongizer:(UITapGestureRecognizer *)gestureRecognizer{
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
btn.hidden = NO;
}
}
have fun!