MKMapView cacher la barre de navigation sur le robinet comme dans l'application photo sans perdre la fonctionnalité de MKMapView

StackOverflow https://stackoverflow.com/questions/7346451

Question

Je voudrais cacher et afficher la barre de navigation sur le robinet comme celui de l'application de photos Mais sans perdre la fonctionnalité du MKMapView. l'utilisateur doit toujours être en mesure de taper deux fois pour zoomer, pincer et zoomer et être en mesure de sélectionner des annotations.

Je l'ai essayé avec:

 UITapGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] 
                                  initWithTarget:self action:@selector(hideBar:)];
[self.myMKMapView addGestureRecognizer:tapRec];
[tapRec release];

Mais l'utilisateur ne peut sélectionner des annotations plus! Et elle a aussi des peaux double robinets.

Toutes les idées?

Était-ce utile?

La solution

Je sais, il est presque exactement un an trop tard, mais j'espère que quelqu'un peut faire un bon usage de celui-ci. Voici comment je l'ai fait, basé sur @ réponse de Cocoanetics:

BOOL                mapReceivedDoubleTap;

...

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapMap:)];
[tapGestureRecognizer setDelegate:self];
[_mapView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

...

// ignore annotations
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return (![[touch view] isKindOfClass:[MKAnnotationView class]]);
}

// take care of double taps for zoom
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer  shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    if([otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        UITapGestureRecognizer *tr = (UITapGestureRecognizer *)otherGestureRecognizer;
        if(tr.numberOfTapsRequired == 2)
            mapReceivedDoubleTap = YES;
    }

    return NO;
}

- (void)didTapMap:(UITapGestureRecognizer *)tapGestureRecognizer {

    mapReceivedDoubleTap = NO;

    // hide/show on delay
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, .2f * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        if(!mapReceivedDoubleTap)
            [self.navigationController setNavigationBarHidden:!self.navigationController.navigationBarHidden animated:YES];
    });
}

Swift

import MapKit

class MapViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var myMapView: MKMapView!

    var mapReceivedDoubleTap = false

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MapViewController.didTapMap(_:)))            
        tapGestureRecognizer.delegate = self            
        myMapView.addGestureRecognizer(tapGestureRecognizer)
    }

    // ignore annotations
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
        return !touch.isKindOfClass(MKAnnotationView)
    }

    // take care of double taps for zoom
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer,
                           shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {

        if otherGestureRecognizer.isKindOfClass(UITapGestureRecognizer) {
            let tr = otherGestureRecognizer as! UITapGestureRecognizer
            if tr.numberOfTapsRequired == 2 {
                mapReceivedDoubleTap = true
            }
        }

        return false
    }

    func didTapMap(gestureRecognizer: UIGestureRecognizer) {

        mapReceivedDoubleTap = false

        // hide/show on delay
        let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.2 * Double(NSEC_PER_SEC)))
        dispatch_after(popTime, dispatch_get_main_queue(), {
            if !self.mapReceivedDoubleTap {
                self.navigationController?.setNavigationBarHidden(!(self.navigationController?.navigationBarHidden)!, animated: true)
            }
        })
    }
}

Autres conseils

vous avez probablement besoin de mettre en œuvre la méthode de délégué pour ce geste de reconnaissance pour détecter simultanément que celui sur le MKMapView. Ensuite, vous devez effectuer votre masquer / afficher un retard et si une annotation vous obtient sélectionnée devez annuler cette opération.

Sinon, vous pouvez faire un hitTest dans la méthode déléguée qui vous permet d'éviter de toucher d'être livré à votre geste si la vue est un coup MKAnnotationView.

Vous pouvez dire à votre geste de reconnaissance pour déclencher que si chaque geste de reconnaissance de la carte échouent.

 UITapGestureRecognizer* tapRec = [[UITapGestureRecognizer alloc] 
                                  initWithTarget:self action:@selector(hideBar:)];
for (UIGestureRecognizer recognizer in self.myMKMapView.gestureRecognizers) {
    [tapRec requireGestureRecognizerToFail:recognizer];
}
[self.myMKMapView addGestureRecognizer:tapRec];
[tapRec release];

Je ne sais pas c'est un gestureRecognizer qui gère l'annotation cependant. Devinez vous devez essayer.

Vous pouvez empêcher un simple clic de reconnaissance geste de voler le double-clic l'un avec ce code:

self.singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
singleTap.numberOfTapsRequired = 1;
for (UIGestureRecognizer* recognizer in self.mapView.gestureRecognizers) {
    if([recognizer isKindOfClass: [UITapGestureRecognizer class]] && ((UITapGestureRecognizer*)recognizer).numberOfTapsRequired == 2) {
        [singleTap requireGestureRecognizerToFail:recognizer];
    }
}
[self.mapView addGestureRecognizer:self.singleTap];

Can peut l'empêcher de voler d'autres gestes de la même manière.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top