I'm having some trouble getting my UILongPressGestureRecognizer to only call itself once. I have a button that I longpress down for the duration of a recording and then upon release, it's supposed to stop the recording. For some reason when I hold down the button, it calls UIGestureRecognizerBegan, then UIGestureRecognizerEnded twice. Basically, there are two recordings. One on the longpress and then on the release, it ends, but calls it again thus creating two recordings. I have one button that has multiple protocols firing at the same time and I'm curious if this is a problem. I took a look at this link:
UILongPressGestureRecognizer gets called twice when pressing down
but I'm not getting the results I want.
The button also zooms when the longpressstate begins and it goes back to it's regular size when the longpressstate ends so I have some animation code below as well that's happening all at the same time.
ButtonView.m
- initWithFrame
[self.recordButton addTarget:self action:@selector(longPress:) forControlEvents:(UIControlEventTouchDown)];
[self addSubview:self.recordButton];
self.longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
self.longPressGesture.allowableMovement = 100.0;
self.longPressGesture.numberOfTouchesRequired = 1;
[self.recordButton addGestureRecognizer:self.longPressGesture];
}
- (void)longPress:(UILongPressGestureRecognizer *)gr {
if ([self.delegate respondsToSelector:@selector(buttonView:didTryToZoom:)]) {
[self.delegate buttonView:self didTryToZoom:self.recordButton];
}
if ([self.delegate respondsToSelector:@selector(buttonView:didTryToShake:)]) {
[self.delegate buttonView:self didTryToShake:self.recordButton];
}
if ([self.delegate respondsToSelector:@selector(recordButtonPressedWithGesture:)]) {
[self.delegate recordButtonPressedWithGesture:(UIGestureRecognizerStateBegan)];
}
if ([self.delegate respondsToSelector:@selector(recordButtonReleasedWithGesture:)]) {
[self.delegate recordButtonReleasedWithGesture: (UIGestureRecognizerStateEnded)];
}
}
In my view controller, I'm calling my delegates from my ButtonView class and adapting to the protocols by calling it in -viewDidLoad.
Here are my delegate methods that I'm calling from my ButtonView class:
ViewController.m
- (void)recordButtonReleasedWithGesture:(UIGestureRecognizerState)state {
if (state == UIGestureRecognizerStateEnded) {
[self audioRecorderDidFinishRecording:self.recorder successfully:YES];
NSData *data = [NSData dataWithContentsOfURL:self.recorder.url];
[data writeToFile:[NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"%@", [[AudioController sharedInstance] filePath]]] atomically:YES];
[[RecordingController sharedInstance] addRecordingWithURL:[[AudioController sharedInstance] filePath]
andIDNumber:[[AudioController sharedInstance] randomIDNumber]
andDateCreated:[[AudioController sharedInstance] createdAtDate]
andFetchDate:[[AudioController sharedInstance] fetchDate]
andSimpleDate:[[AudioController sharedInstance] simpleDateString]
andGroupName:[[AudioController sharedInstance] groupName]];
[[RecordingController sharedInstance] save];
}
}
- (void)recordButtonPressedWithGesture:(UIGestureRecognizerState)state {
if (state == UIGestureRecognizerStateBegan) {
self.buttonView.playButton.enabled = NO;
self.recorder.delegate = self;
self.recorder = [[AudioController sharedInstance] recordAudioToDirectory];
}
}
- (void)buttonView:(ButtonView *)view didTryToShake:(UIButton *)button {
if (self.containerView.state == ButtonStateNone) {
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
[animation setDuration:0.1];
[animation setRepeatCount:3];
[animation setAutoreverses:YES];
[animation setFromValue:[NSValue valueWithCGPoint:
CGPointMake([self.buttonView.recordButton center].x + 20, [self.buttonView.recordButton center].y)]];
[animation setToValue:[NSValue valueWithCGPoint:
CGPointMake([self.buttonView.recordButton center].x - 20, [self.buttonView.recordButton center].y)]];
[[self.buttonView.recordButton layer] addAnimation:animation forKey:@"position"];
}
}
- (void)buttonView:(ButtonView *)view didTryToZoom:(UIButton *)button {
if (self.containerView.state == ENUMS) {
if (view.longPressGesture.state == UIGestureRecognizerStateBegan) {
[UIView animateWithDuration:.5f
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
self.containerView.hidden = YES;
self.buttonView.recordButton.transform = CGAffineTransformScale(self.buttonView.recordButton.transform, 3, 3);
self.buttonView.recordButton.alpha = .7;
} completion:nil];
}
if (view.longPressGesture.state == UIGestureRecognizerStateEnded) {
[UIView animateWithDuration:.25
delay:0
options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut
animations:^{
self.buttonView.recordButton.transform = CGAffineTransformScale(CGAffineTransformIdentity, .7, .7);
self.buttonView.recordButton.alpha = 1;
} completion:^(BOOL finished) {
[UIView animateWithDuration:.15
delay:0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.buttonView.recordCompleteLabel.hidden = NO;
[NSTimer scheduledTimerWithTimeInterval:.65
target:self
selector:@selector(hideLabel)
userInfo:nil
repeats:NO];
self.buttonView.recordButton.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
self.containerView.hidden = NO;
//[self.containerView setState:ButtonStateNone];
[self noneState:ButtonStateNone];
self.buttonView.recordButton.backgroundColor = [UIColor blueColor];
I'm positive I'm missing something really silly and I'm just not seeing it. Are there any more seasoned developers that can identify why the long press is getting called twice? I'd greatly appreciate any help.