LongPressGesture 与自定义代表被调用两次。是因为我的代表吗?

Posted

技术标签:

【中文标题】LongPressGesture 与自定义代表被调用两次。是因为我的代表吗?【英文标题】:LongPressGesture with custom delegates being called twice. Is it because of my delegates? 【发布时间】:2015-04-03 02:17:29 【问题描述】:

我无法让我的 UILongPressGestureRecognizer 只调用一次自己。我有一个按钮,我在录制期间长按它,然后在释放时,它应该停止录制。出于某种原因,当我按住按钮时,它会调用 UIGestureRecognizerBegan,然后调用 UIGestureRecognizerEnded 两次。基本上,有两个录音。一个在长按上,然后在发布上,它结束,但再次调用它,从而创建了两个录音。我有一个按钮可以同时触发多个协议,我很好奇这是否是一个问题。我看了一下这个链接:

UILongPressGestureRecognizer gets called twice when pressing down

但我没有得到我想要的结果。

当长按状态开始时,按钮也会缩放,当长按状态结束时,它会恢复到正常大小,所以我在下面还有一些动画代码,这些都是同时发生的。

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 类调用我的委托,并通过在 -viewDidLoad 中调用它来适应协议。

这是我从 ButtonView 类调用的委托方法:

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

我很肯定我错过了一些非常愚蠢的东西,我只是没有看到它。是否有更多经验丰富的开发人员可以确定为什么长按会被调用两次?我将不胜感激任何帮助。

【问题讨论】:

你的initWithFrame方法是不是超类的initWithFrame方法被你覆盖了? 尝试调试并检查是否只调用了一次 initWithFrame。手势regcog。可能会添加到按钮 2 次并导致调用 longPress 方法两次。 哇!你完全正确。它被调用了两次。这太奇怪了。是不是因为我在 ViewController 的 viewDidLoad 中设置了子类 UIView 的框架? 您是否将视图放在情节提要中并在代码中再次调用 initWithFrame? 啊,我想通了。我通过初始化 ButtonView 类为我的另一个视图设置了一个属性。我还有一些问题需要修补,但你让我走上了正确的轨道。谢谢 Suttikeat! 【参考方案1】:

我发现我一直在 UIView 的另一个子类中调用它。但是,我仍然在创建重复录音时遇到问题。我深入一点,我意识到我有一个调用 AVAudioRecorder 的单例控制器,并且我还通过在 ViewController 中创建 AVAudioRecorder 的属性并将其设置为单例控制器的 AVAudioRecorder 来实例化另一个 AVAudioRecorder 实例。非常感谢 Suttikeat。

【讨论】:

以上是关于LongPressGesture 与自定义代表被调用两次。是因为我的代表吗?的主要内容,如果未能解决你的问题,请参考以下文章

释放 LongPressGesture SwiftUI 时触发动作

如何取消 LongPressGesture 以便 PanGesture 可以识别

DragGesture 正在取消 SwiftUI 中的 LongPressGesture

SwiftUI - 当手指移动一点时让 LongPressGesture 保持不变?

在 UICollectionView 中使用 LongPressGesture 检索 UICollectionViewCell 的 NSIndexPath 和部分

NSMutableArray 与自定义对象?