【问题标题】:Disable multiple taps on uitableviewcell禁用 uitableviewcell 上的多次点击
【发布时间】:2013-07-12 22:41:10
【问题描述】:

我有一个 uitableview,它在点击单元格时实现弹出框 (PopoverView),然后弹出框将在屏幕上的任何其他点击时消失。问题是,如果用户要双击或重复点击单元格,它将导致显示多个弹出视图实例,然后应用程序将崩溃。我正在寻找一种方法来禁用双击单元格和/ 或一般的UITableView 或者有没有办法延迟对UITableViewCell 的任何想法?

我已经尝试过this,但它不适用于我的情况。 另一种方法是检查 PopoverView 是否已经存在,如果存在则不允许另一个实例化。我尝试了thisthis,但都不适用于我的情况。

这是我在didSelectRowAtIndexpath 上调用弹出视图的代码:

- (void)tableView:(UITableView *)TableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
   UITableViewCell *cell = [TableView cellForRowAtIndexPath:indexPath];
sti = [[SelectedTeamsInfo alloc] init];
MyLeagueStandings *info = [fetchedResultsController objectAtIndexPath:indexPath];
[sti getAllScheduleForTeam:info.urlforteam];
NSString *title = info.teamname;

// If title length is greater then 32 truncate it to fit.
if (title.length > 32) {
    title = [info.teamname substringToIndex:29];
    title = [title stringByAppendingString:@"..."];
}


[PopoverView showPopoverAtPoint:cell.center inView:self.view withTitle:title withContentView:sti.view delegate:self];
}

解决方案

在接口类中:

 BOOL PopoverYN;

在实现类中:

- (void)tableView:(UITableView *)TableView 
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // If the popover is not available then display it else do nothing since one is already displayed.
        if (PopoverYN == NO) {
            PopoverYN = YES;
            UITableViewCell *cell = [TableView cellForRowAtIndexPath:indexPath];
            sti = [[SelectedTeamsInfo alloc] init];
            MyLeagueStandings *info = [fetchedResultsController objectAtIndexPath:indexPath];
            [sti getAllScheduleForTeam:info.urlforteam];
            NSString *title = info.teamname;

            // If title length is greater then 32 truncate it to fit.
            if (title.length > 32) {
                title = [info.teamname substringToIndex:29];
                title = [title stringByAppendingString:@"..."];
            }
            [PopoverView showPopoverAtPoint:cell.center inView:self.view withTitle:title withContentView:sti.view delegate:self];
        }

}

#pragma mark - popover methods.
- (void)popoverViewDidDismiss:(PopoverView *)popoverView;
{
    PopoverYN = NO;
}

【问题讨论】:

  • 这是我无法回答的问题之一,因为我有很多答案。你将不得不告诉一个变量你的弹出框被调用并忽略其他任何东西,直到你回来。基本上将您的 didselectrowatIndexPath 方法中的内容包装在一个 if 语句中,该语句检查一个 BOOL,当视图返回时您将重置该 BOOL
  • 您的评论也非常有帮助,谢谢。
  • 很高兴来到这里并感谢您的反馈。

标签: iphone cocoa-touch uitableview


【解决方案1】:

我还有一个解决方案。希望这会对某人有所帮助。如果您想检测第二次点击并使用它,那么就是这样,这对我有用。我在单击时加载 Web 视图,如果连续两次单击,则该错误正在获取 NSURLErrorCancelled 事件并导致 webview 上出现白色闪屏。我可以在网络视图级别处理它,但我应该从根目录解决问题。

NSTimer *avoidDoubleTapTimer;

- (void) onTimer {  
    NSLog(@"Timer out");
    avoidDoubleTapTimer = nil;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(avoidDoubleTapTimer == nil) {
        avoidDoubleTapTimer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(onTimer) userInfo:nil repeats:NO];
    } else {
        NSLog(@"Double Tap Detected");
        return;
    }
// do you stuff on single tap
}

【讨论】:

  • 这行得通,是迄今为止找到的最佳答案!我不得不将其设置为 1 秒。谢谢:)
【解决方案2】:

将弹出框附加到该视图上的属性。清除它何时被解除(通过委托方法)。在didSelectRowAtIndexPath 中,如果第一个尚未关闭,则不要创建另一个弹出框。

【讨论】:

  • 非常感谢!委托方法和属性就是诀窍。
【解决方案3】:

这是 @mask answer 的 Swift 版本,但我的 withTimeInterval 持续时间在 2 秒而不是 1 秒时效果更好。

应该注意的是,即使这个计时器没有重复,它在我点击一个单元格后引起了问题,新的 vc 被推送,我返回到父级(有计时器的那个),然后切换选项卡.标签被冻结。在多次尝试注释和取消注释计时器后,我意识到这是计时器。

为了解决这个问题,我刚刚取消了viewWillDisappear 中的计时器:

var avoidDoubleTapTimer: Timer?

@objc func cancelDoubleTapTimer() {
    avoidDoubleTapTimer = nil
}

// use it for a cell
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if avoidDoubleTapTimer == nil {

        avoidDoubleTapTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { [weak self](_) in
            self?.cancelDoubleTapTimer()
        })
    } else {

        return
    }

    // run your code, do whatever ...
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    cancelDoubleTapTimer()
}

// or use it for a tapGestureRecognizer

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(labelWasTapped))
yourLabel.addGestureRecognizer(tapGesture)

@objc func labelWasTapped() {

    if avoidDoubleTapTimer == nil {

        avoidDoubleTapTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { [weak self](_) in
            self?.cancelDoubleTapTimer()
        })

    } else {

        return
    }

    // run your code, do whatever ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多