在uitableviewcell上禁用多次点击

时间:2013-07-12 22:41:11

标签: iphone cocoa-touch uitableview

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

我已经尝试this,但在我的情况下不起作用。 另一种方法是检查PopoverView是否已经存在,如果是,那么不要让另一个实例化。我尝试了thisthis,但两者都不适用于我的情况。

以下是我在didSelectRowAtIndexpath上调用popover视图的代码:

- (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;
}

3 个答案:

答案 0 :(得分:4)

我还有一个解决方案。希望这会对某人有所帮助。如果你想检测第二次点击并消耗它,那就是它,这对我有用。我在单击时加载了网页视图,如果连续两次点击,则该错误导致NSURLErrorCancelled事件,并导致webview上的白色闪屏。我可以在网络视图级别处理它,但我应该在root用户处理问题。

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 :(得分:0)

将popover附加到该视图上的属性。当它被解雇时(通过委托方法)清除它。在didSelectRowAtIndexPath中,如果第一个没有被解雇,则不要创建另一个弹出窗口。

答案 2 :(得分:0)

这是@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 ...
}