简体   繁体   中英

Can I handle the double tap in UITabbarController

I need to handle the double tap action to get back from a navigation path represented with a custom view.

Usually the double tap dismisses the nested topmost controller in the navigation controller's stack. I'd like to handle this action and do something else.

Placing code in (BOOL)tabBarController:shouldSelectViewController: does not help as there is no difference between the single and double tap.

Thanks.

I rewrite Vladimír Slovak's answer in Swift 2, in case anyone need it

var tapCounter : Int = 0
var previousVC = UIViewController()

func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) -> Bool {

    self.tapCounter++
    let hasTappedTwice = self.previousVC == viewController
    self.previousVC = viewController

    if self.tapCounter == 2 && hasTappedTwice {
        self.tapCounter = 0
        print ("Double Tapped!")
    }
    if self.tapCounter == 1 {
        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.3 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue(), {
            self.tapCounter = 0
        })
    }

    return true
}

I had to add a tapCounter in the tabBarController:shouldSelectViewController: implementation:

self.tapCounter++;


// rule out possibility when the user taps on two different tabs very fast
BOOL hasTappedTwiceOnOneTab = NO;

if(self.previousHandledViewController == viewController) {

    hasTappedTwiceOnOneTab = YES;
}

self.previousHandledViewController = viewController;


// this code is called in the case when the user tapped twice faster then tapTimeRange
CGFloat tapTimeRange = 0.3;



        if(self.tapCounter == 2 && hasTappedTwiceOnOneTab) {


            // do something when tapped twice 

            self.tapCounter = 0;
            return NO; // or YES when you want the default engine process the event

        } else if(self.tapCounter == 1) {

            __block BOOL isSameViewControllerSelected = self.selectedViewController == viewController;
            if(isSameViewControllerSelected) {
                // do something when tapped once
            }

            dispatch_after_delay_on_main_queue(tapTimeRange, ^{

                self.tapCounter = 0; // reset the counter in case there is a single tap followed with another one, but with longer time then tapTimeRange
            });

            return NO; // or YES when you want the default engine process the event 
        }

This works nicely without any private api calls. But I'd like to know if there is a better and a less complicated way.

try this:

@property (nonatomic, assign) NSTimeInterval tapTime;
@property (nonatomic, weak) UIViewController *prevVC;

- viewDidLoad {
    self.tabBarController.delegate = self;
}

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
    NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
    NSTimeInterval duration = currentTime - self.tapTime;
    self.tapTime = currentTime;
    if (viewController == self.prevVC) {
        if (duration < 0.35) {
            // double tap detected! write your code here
            self.tapTime = 0;
        }
    }
    self.prevVC = viewController; 
}

I believe you need to use a touch even...

check out a similar stack overflow below:

Objective-c: How to detect double tap on view?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM