MKMapView скрыть панель навигации на кране, как в приложении для фотографий, не теряя функциональности MKMapView - PullRequest
1 голос
/ 08 сентября 2011

Я хотел бы скрыть и показать панель навигации при нажатии, как в приложении для фотографий, НО без потери функциональности MKMapView.пользователь все еще должен иметь возможность дважды нажимать для увеличения, уменьшения и увеличения и иметь возможность выбирать аннотации.

Я попробовал это сделать с помощью:

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

Но тогда пользователь не может выбратьаннотации больше! И это также скрывается на двойных нажатий.

Есть идеи?

Ответы [ 4 ]

5 голосов
/ 03 октября 2012

Я знаю, это почти точно на один год слишком поздно, но я надеюсь, что кто-то может использовать это. Вот как я это сделал, основываясь на ответе @ 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)
            }
        })
    }
}
2 голосов
/ 09 сентября 2011

вам, вероятно, нужно реализовать метод делегата, чтобы этот распознаватель жестов обнаруживал одновременно как тот, что в MKMapView. Затем вам нужно выполнить скрытие / показ с задержкой, и если аннотация выбрана, вам нужно отменить это.

В качестве альтернативы вы можете выполнить hitTest в методе делегата, который позволяет предотвратить доставку прикосновений к вашему жесту, если представлением попаданий является MKAnnotationView.

0 голосов
/ 01 декабря 2011

Вы можете предотвратить распознавание жестов двойным щелчком с помощью этого кода:

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

Может помешать ему украсть другие жесты таким же образом.

0 голосов
/ 09 сентября 2011

Вы можете настроить распознавание жестов на запуск только в случае сбоя каждого распознавателя жестов на карте.

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

Я не знаю, что это gestRecognizer, который обрабатывает аннотацию, хотя. Думаю, тебе придется попробовать.

...