有没有在3.0 SDK禁用实时缩放和拦截针对的MKMapView缩放手势的错误吗? 我有一些真正简单的代码,所以我可以检测到点击事件,但有两个问题:
- 放大手势总是被解释为一个缩小
- 无缩放手势更新地图的实时视图。
在则hitTest,如果我返回“图”视图中,功能性的MKMapView的伟大工程,但我没有得到机会拦截事件。
有任何想法吗?
MyMapView.h:
@interface MyMapView : MKMapView
{
UIView *map;
}
MyMapView.m:
- (id)initWithFrame:(CGRect)frame
{
if (![super initWithFrame:frame])
return nil;
self.multipleTouchEnabled = true;
return self;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"Hit Test");
map = [super hitTest:point withEvent:event];
return self;
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"%s", __FUNCTION__);
[map touchesCancelled:touches withEvent:event];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event
{
NSLog(@"%s", __FUNCTION__);
[map touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
NSLog(@"%s, %x", __FUNCTION__, mViewTouched);
[map touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
NSLog(@"%s, %x", __FUNCTION__, mViewTouched);
[map touchesEnded:touches withEvent:event];
}
Answer 1:
我已经找到了实现这一目标的最好方法是使用手势识别。 如果你想自己承认缩放事件或当用户缩放/平移只是检测目前还不清楚。
我不需要侦测到地图上平移或缩放 - 我只关心用户是否在的MKMapView把手指在任何地方。 如果您需要检测缩放或100%的召回率和准确平移,这可能是比这更复杂。 我们真正需要的是的MKMapView的一个开源实现,所以我们可以将它添加到委托,许多其他特征。
下面是我做的:实现不能阻止一个手势识别,并不能阻止其他手势识别。 将它添加到地图视图和相关触摸事件处理,你的愿望。
如何检测的MKMapView内的任何水龙头(SANS技巧)
WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init];
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) {
self.lockedOnUserLocation = NO;
};
[mapView addGestureRecognizer:tapInterceptor];
WildcardGestureRecognizer.h
//
// WildcardGestureRecognizer.h
// Copyright 2010 Floatopian LLC. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^TouchesEventBlock)(NSSet * touches, UIEvent * event);
@interface WildcardGestureRecognizer : UIGestureRecognizer {
TouchesEventBlock touchesBeganCallback;
}
@property(copy) TouchesEventBlock touchesBeganCallback;
@end
WildcardGestureRecognizer.m
//
// WildcardGestureRecognizer.m
// Created by Raymond Daly on 10/31/10.
// Copyright 2010 Floatopian LLC. All rights reserved.
//
#import "WildcardGestureRecognizer.h"
@implementation WildcardGestureRecognizer
@synthesize touchesBeganCallback;
-(id) init{
if (self = [super init])
{
self.cancelsTouchesInView = NO;
}
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (touchesBeganCallback)
touchesBeganCallback(touches, event);
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
}
- (void)reset
{
}
- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event
{
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer
{
return NO;
}
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer
{
return NO;
}
@end
Answer 2:
我有同样的问题 - 我想画上的地图视图顶部的比例尺。 为了做到这一点,我不得不拦截触摸事件,然后送他们回地图视图。 不幸的是,当的MKMapView不是事件的原始接收器,一些顺利平移和缩放动画不工作了。
不过,我已经找到了解决这个问题 - 有点哈克但工作原理:1.我已经把我的MapScales的UIView上的MKMapView的顶部,并关闭接收它的事件,让底层的MKMapView默认收到的事件。 2.我已经子类的UIWindow与MyMainWindow类,并在它我已经重写的方法:
- (void) sendEvent:(UIEvent*)event {
[super sendEvent:event];
[self send_the_event_also_to_my_MapScales_component_with_use_of_listener_design_pattern];
}
- 我已经作出了应用程序的主窗口MyMainWindow的instasnce。
这样我MapScales组件接收并能应对所有的触摸事件,并在同一时间它不是破坏底层的MKMapView :)
Answer 3:
#import <UIKit/UIKit.h>
#import "UIViewTouch.h"
#import <MapKit/MapKit.h>
@interface MapTouchAppDelegate : NSObject <UIApplicationDelegate>
{
UIViewTouch *viewTouch;
MKMapView *mapView;
UIWindow *window;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UIViewTouch *viewTouch;
@property (nonatomic, retain) MKMapView *mapView;
@end
#import "MapTouchAppDelegate.h"
@implementation MapTouchAppDelegate
@synthesize window;
@synthesize viewTouch;
@synthesize mapView;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
//We create a view wich will catch Events as they occured and Log them in the Console
viewTouch = [[UIViewTouch alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
//Next we create the MKMapView object, which will be added as a subview of viewTouch
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[viewTouch addSubview:mapView];
//And we display everything!
[window addSubview:viewTouch];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)dealloc {
[window release];
[super dealloc];
}
#import <UIKit/UIKit.h>
@interface UIViewTouch : UIView
{
UIView *viewTouched;
}
@property (nonatomic, retain) UIView * viewTouched;
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
#import "UIViewTouch.h"
@implementation UIViewTouch
@synthesize viewTouched;
//The basic idea here is to intercept the view which is sent back as the firstresponder in hitTest.
//We keep it preciously in the property viewTouched and we return our view as the firstresponder.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"Hit Test");
self.multipleTouchEnabled = true;
viewTouched = [super hitTest:point withEvent:event];
return self;
}
//Then, when an event is fired, we log this one and then send it back to the viewTouched we kept, and voilà!!! :)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touch Began");
[viewTouched touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touch Moved");
[viewTouched touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touch Ended");
[viewTouched touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touch Cancelled");
}
@end
此代码将检测触摸以及缩放。
Answer 4:
尝试
[super touchesEnded:touches withEvent:event];
代替
[map touchesEnded:touches withEvent:event];
并运用这种思想的所有的触摸事件的方法。 这样一来,倒是应该向下行进响应链,和平将得到恢复。
Answer 5:
为了延长了对@ chomasek的答案,为了只处理那些触摸的地图视图,我做到以下几点:
- 给地图查看标签,像99
- 当我触摸,穿越了接收视图的视图层次,寻找与上述标签的视图。
下面是代码:
// this is in the view controller containing the map view
// kICTagForMapView is just a constant
_mapView.tag = kICTagForMapView;
然后在sendEvent:
// this does into the UIWindow subclass
BOOL isMapView = NO;
UIView* superView = touch.view.superview;
while(superView)
{
//Debug(@"superView = %@", superView);
if (superView.tag == kICTagForMapView)
{
isMapView = YES;
break;
}
superView = superView.superview;
}
if (isMapView == NO) return;
// do stuff here
Answer 6:
的MKMapView不响应上面列出的触摸方法...
文章来源: Intercepting/Hijacking iPhone Touch Events for MKMapView