带有自定义委托的 LongPressGesture 被调用两次。是因为我的代表吗?
LongPressGesture with custom delegates being called twice. Is it because of my delegates?
我在让我的 UILongPressGestureRecognizer 只调用自己一次时遇到了一些问题。我有一个按钮,我在录音期间长按该按钮,然后在松开时,它应该会停止录音。出于某种原因,当我按住按钮时,它会调用 UIGestureRecognizerBegan,然后调用 UIGestureRecognizerEnded 两次。基本上,有两个录音。一个在长按上,然后在释放上,它结束,但再次调用它,从而创建两个录音。我有一个按钮同时触发多个协议,我很好奇这是否是个问题。我看了一下这个link:
UILongPressGestureRecognizer gets called twice when pressing down
但我没有得到我想要的结果。
当 longpressstate 开始时,按钮也会缩放,当 longpressstate 结束时,它会恢复到正常大小,所以我在下面也有一些动画代码,它们是同时发生的。
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)];
}
}
在我的视图控制器中,我从 ButtonView class 调用我的委托,并通过在 -viewDidLoad 中调用它来适应协议。
这是我从 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];
我很肯定我错过了一些非常愚蠢的东西,我只是没有看到它。是否有更多经验丰富的开发人员可以确定为什么长按被调用两次?我将不胜感激任何帮助。
我发现我一直在UIView的另一个子类中调用它。但是,我在创建重复录音时仍然遇到问题。我深入一点,我意识到我有一个调用 AVAudioRecorder 的单例控制器,我还通过在 ViewController 内创建 AVAudioRecorder 的 属性 并将其设置为来实例化 AVAudioRecorder 的另一个实例单例控制器的 AVAudioRecorder。非常感谢 Suttikeat。
我在让我的 UILongPressGestureRecognizer 只调用自己一次时遇到了一些问题。我有一个按钮,我在录音期间长按该按钮,然后在松开时,它应该会停止录音。出于某种原因,当我按住按钮时,它会调用 UIGestureRecognizerBegan,然后调用 UIGestureRecognizerEnded 两次。基本上,有两个录音。一个在长按上,然后在释放上,它结束,但再次调用它,从而创建两个录音。我有一个按钮同时触发多个协议,我很好奇这是否是个问题。我看了一下这个link:
UILongPressGestureRecognizer gets called twice when pressing down
但我没有得到我想要的结果。
当 longpressstate 开始时,按钮也会缩放,当 longpressstate 结束时,它会恢复到正常大小,所以我在下面也有一些动画代码,它们是同时发生的。
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)];
}
}
在我的视图控制器中,我从 ButtonView class 调用我的委托,并通过在 -viewDidLoad 中调用它来适应协议。
这是我从 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];
我很肯定我错过了一些非常愚蠢的东西,我只是没有看到它。是否有更多经验丰富的开发人员可以确定为什么长按被调用两次?我将不胜感激任何帮助。
我发现我一直在UIView的另一个子类中调用它。但是,我在创建重复录音时仍然遇到问题。我深入一点,我意识到我有一个调用 AVAudioRecorder 的单例控制器,我还通过在 ViewController 内创建 AVAudioRecorder 的 属性 并将其设置为来实例化 AVAudioRecorder 的另一个实例单例控制器的 AVAudioRecorder。非常感谢 Suttikeat。