我正在尝试在MKMapView
上捕捉点击事件,这样我就可以在用户点按的位置放置MKPinAnnotation
。基本上我有一个覆盖着MKOverlayViews
的地图(显示建筑物的叠加层),我想通过删除MKPinAnnotaion
并在其中显示更多信息来向用户提供有关该叠加的更多信息。大喊。
谢谢。
答案 0 :(得分:59)
您可以使用UIGestureRecognizer
来检测地图视图上的触摸。
然而,我建议您选择双击(UITapGestureRecognizer
)或长按(UILongPressGestureRecognizer
),而不是单击。单击可能会干扰用户尝试单击引脚或标注本身。
在您设置地图视图的位置(例如,在viewDidLoad
中),将手势识别器附加到地图视图中:
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleGesture:)];
tgr.numberOfTapsRequired = 2;
tgr.numberOfTouchesRequired = 1;
[mapView addGestureRecognizer:tgr];
[tgr release];
或使用长按:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(handleGesture:)];
lpgr.minimumPressDuration = 2.0; //user must press for 2 seconds
[mapView addGestureRecognizer:lpgr];
[lpgr release];
在handleGesture:
方法中:
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateEnded)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:mapView];
CLLocationCoordinate2D touchMapCoordinate =
[mapView convertPoint:touchPoint toCoordinateFromView:mapView];
MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
pa.coordinate = touchMapCoordinate;
pa.title = @"Hello";
[mapView addAnnotation:pa];
[pa release];
}
答案 1 :(得分:5)
我在UILongPressGestureRecognizer
设置了一个长按(viewDidLoad:
),但它只检测到第一个触摸的唯一触摸。
我可以在哪里设置长按以检测所有触摸?(这意味着每次等待用户触摸屏幕推针时都准备好了地图)
viewDidLoad:
方法!
- (void)viewDidLoad {
[super viewDidLoad];mapView.mapType = MKMapTypeStandard;
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)];
[self.mapView addGestureRecognizer:longPressGesture];
[longPressGesture release];
mapAnnotations = [[NSMutableArray alloc] init];
MyLocation *location = [[MyLocation alloc] init];
[mapAnnotations addObject:location];
[self gotoLocation];
[self.mapView addAnnotations:self.mapAnnotations];
}
和handleLongPressGesture
方法:
-(void)handleLongPressGesture:(UIGestureRecognizer*)sender {
// This is important if you only want to receive one tap and hold event
if (sender.state == UIGestureRecognizerStateEnded)
{NSLog(@"Released!");
[self.mapView removeGestureRecognizer:sender];
}
else
{
// Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map
CGPoint point = [sender locationInView:self.mapView];
CLLocationCoordinate2D locCoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView];
// Then all you have to do is create the annotation and add it to the map
MyLocation *dropPin = [[MyLocation alloc] init];
dropPin.latitude = [NSNumber numberWithDouble:locCoord.latitude];
dropPin.longitude = [NSNumber numberWithDouble:locCoord.longitude];
// [self.mapView addAnnotation:dropPin];
[mapAnnotations addObject:dropPin];
[dropPin release];
NSLog(@"Hold!!");
NSLog(@"Count: %d", [mapAnnotations count]);
}
}
答案 2 :(得分:2)
如果您想在地图视图中使用单击/点击,这里是我正在使用的一段代码。 (可可和斯威夫特)
let gr = NSClickGestureRecognizer(target: self, action: "createPoint:")
gr.numberOfClicksRequired = 1
gr.delaysPrimaryMouseButtonEvents = false // allows +/- button press
gr.delegate = self
map.addGestureRecognizer(gr)
在手势委托方法中,一个简单的测试,更喜欢双击手势...
func gestureRecognizer(gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOfGestureRecognizer otherGestureRecognizer: NSGestureRecognizer) -> Bool {
let other = otherGestureRecognizer as? NSClickGestureRecognizer
if (other?.numberOfClicksRequired > 1) {
return true; // allows double click
}
return false
}
如果您希望Map处于各种“状态”,您也可以在其他委托方法中过滤手势,其中一个允许单击/单击
答案 3 :(得分:0)
由于某种原因,UIGestureRecognizer在Swift中对我不起作用。当我使用UIGestureRecognizer的方式时。当我使用touchesEnded方法时,它返回一个MKNewAnnotationContainerView。似乎此MKNewAnnotationContainerView阻止了我的MKMapView。幸运的是,它是MKMapView的子视图。因此,我遍历了MKNewAnnotationContainerView的超级视图,直到self.view都获得了MKMapView。而且我设法通过点击来固定mapView。
Swift 4.1
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let t = touches.first
print(t?.location(in: self.view) as Any)
print(t?.view?.superview?.superview.self as Any)
print(mapView.self as Any)
var tempView = t?.view
while tempView != self.view {
if tempView != mapView {
tempView = tempView?.superview!
}else if tempView == mapView{
break
}
}
let convertedCoor = mapView.convert((t?.location(in: mapView))!, toCoordinateFrom: mapView)
let pin = MKPointAnnotation()
pin.coordinate = convertedCoor
mapView.addAnnotation(pin)
}