Zoomable UIScrollView with UIButtons capturing touches

I have a UIScrollView and I'm implementing the viewForZoomingInScrollView: delegate method which returns a UIImage which the user can zoom and pan. I've also got some UIButtons as sub views of the UIScrollView which I'm using as annotations, like Google Maps.

The problem I'm having is that a lot of the UIImage can be obscured by the UIButtons when zoomed right out. When trying to pinch to zoom the UIButtons are receiving the touch event instead and the zoom is not happening. You end up having to carefully place your fingers in clear space to zoom.

I note the Google Maps app seems to work ok when there are lots of annotation views, you can still pinch.

I guess I need to priorities the touches, the UIScrollView needs to respond to pinches and pans, while the buttons just taps.

Anyone have experience of this?


I had this exact issue, and it was kind of weird. It wasn't due to any gesture recognizer on the button, it was the UIScrollView's pinch gesture recognizer that was being forwarded to the UIButton for some reason. Also, the UIButton was responding to certain UIGestureRecognizerDelegate calls (like -gestureRecognizerShouldBegin:) but not others (like -gestureRecognizer:shouldReceiveTouch:). It's like the UIScrollView was selectively forwarding some delegate calls to the UIButton and some not.

I finally found a very easy way to solve this issue:

yourScrollView.pinchGestureRecognizer.delaysTouchesBegan = YES;
yourScrollView.pinchGestureRecognizer.delaysTouchesEnded = YES;

Luckily, the default pinch gesture recognizer on UIScrollView's are publicly accessible, and the two delaysTouches property are NO by default. When you set them to YES, if the gesture recognizer could possibly or does recognize a pinch gesture even when it starts on top of a UIButton, it won't forward those touches to the UIButton, and the UIButtons will no longer interfere with the UIScrollView's zooming.


try this

 UIGestureRecognizer* tapRecognizer = nil;    
for (UIGestureRecognizer* recognizer in yourButton) {
    if ( ![recognizer isKindOfClass:[UITapGestureRecognizer class]] ) {
        [yourButton removeGestureRecognizer:recognizer];
        break;
    }
}

so you remove all the gesture recognizers from the button different from UITapGestureRecognizer


take a look at UIView's hitTest:withEvent: method. Inside that method youll need to check for which view you want to return. The view you return will be the one recieving the touches. for example, you can subclass the button and override that method to return the ImageView for your particular scenario.

链接地址: http://www.djcxy.com/p/40532.html

上一篇: iOS UIScrollView取消滚动上的UIButton触摸

下一篇: 可缩放的UIScrollView与UIButtons捕捉触摸