MKMapView 在点击时隐藏导航栏,就像在照片应用程序中一样,而不会丢失 MKMapView 的功能

发布于 2024-12-03 10:25:31 字数 392 浏览 1 评论 0原文

我想隐藏并显示点击时的导航栏,就像照片应用程序中的导航栏一样 但不会失去 MKMapView 的功能。用户仍然应该能够双击进行缩放、捏合和缩放,并能够选择注释。

我尝试过:

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

但是用户无法再选择注释!而且它也会在双击时隐藏。

有什么想法吗?

I would like to hide and show the navigation bar on tap like the one in the photos app
BUT without losing the functionality of the MKMapView. the user should still be able to double tap for zoom, pinch and zoom and be able to select annotations.

I tried it with:

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

But then the user can't select annotations anymore!And it also hides on double taps.

Any ideas ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橙幽之幻 2024-12-10 10:25:31

我知道,这几乎晚了一年,但我希望有人可以利用它。根据 @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)
            }
        })
    }
}

I know, it's almost exactly one year too late, but I hope somebody can make a use of it. Here's how I did it, based on @Cocoanetics's answer:

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)
            }
        })
    }
}
情丝乱 2024-12-10 10:25:31

您可能需要实现此手势识别器的委托方法,以便与 MKMapView 上的手势识别器同时检测。然后,您需要延迟执行隐藏/显示,如果选择了注释,则需要取消此操作。

或者,您可以在委托方法中执行 hitTest,如果命中视图是 MKAnnotationView,则可以防止触摸传递到您的手势。

you probably need to to implement the delegate method for this gesture recognizer to detect simultaneously as the one on the MKMapView. Then you need to perform your hiding/showing on a delay and if an annotation gets selected you need to cancel this.

Alternatively you can do a hitTest in the delegate method that allows you to prevent touches from being delivered to your gesture if the hit view is an MKAnnotationView.

蓝眼泪 2024-12-10 10:25:31

您可以告诉手势识别器仅在地图上的每个手势识别器都失败时才触发。

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

我不知道这是一个处理注释的gestureRecognizer。我猜你必须尝试一下。

You can tell your gesture recognizer to trigger only if every gesture recognizer from the map fail.

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

I don't know it is a gestureRecognizer that handles the annotation though. Guess you'll have to try.

猫腻 2024-12-10 10:25:31

您可以使用以下代码防止单击手势识别器窃取双击手势:

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

可以以相同的方式防止它窃取其他手势。

You can prevent a single click gesture recognizer from stealing the double click one with this 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 can prevent it from stealing other gestures in the same way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文