2
Q
檢測標註的標註
A
回答
4
回答你的問題有點晚,但我最近處理的是同樣的問題,並通過我自己的試驗和錯誤來解決我的問題。也許我可以幫助處理同樣問題的人。
你也可以使用一些自定義註釋和標註視圖類,這裏有很多例子。 但是,還有一種簡單的方法可以在不使用複雜的外部類的情況下解決這個問題。
問題定義: 我希望能夠通過觸摸標註視圖來觸發某些方法。 我不想使用右側或左側的配件按鈕。 但是當我觸摸標註視圖時,視圖將立即消失。
解決方案的簡短說明: 只需使用自定義的「MKPinAnnotationView」和「hittest」來檢測標註視圖中的觸摸。
你也可以在帖子末尾找到github項目鏈接。
touchableCallOutsViewController.h
//
// touchableCallOutsViewController.h
// touchableCallOuts
//
// Created by yasin turkoglu on 20.11.2012.
// Copyright (c) 2012 yasin turkoglu. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@class myCustomPinAnnotationClass;
@interface touchableCallOutsViewController : UIViewController <MKMapViewDelegate> {
MKMapView *myMapView;
int pinCounter;
myCustomPinAnnotationClass *myAnnotation;
CLLocationCoordinate2D selectedPinCoordinate;
int selectedPinNumber;
}
@property (strong, nonatomic) MKMapView *myMapView;
@property (strong, nonatomic) myCustomPinAnnotationClass *myAnnotation;
@end
touchableCallOutsViewController.m
//
// touchableCallOutsViewController.m
// touchableCallOuts
//
// Created by yasin turkoglu on 20.11.2012.
// Copyright (c) 2012 yasin turkoglu. All rights reserved.
//
#import "touchableCallOutsViewController.h"
#import "myCustomPinAnnotationClass.h"
@interface touchableCallOutsViewController()
@end
@implementation touchableCallOutsViewController
@synthesize myMapView;
@synthesize myAnnotation;
- (void)viewDidLoad
{
//first we create mapview and add pin annotation
myMapView = [[MKMapView alloc]initWithFrame:self.view.frame];
myMapView.delegate = self;
MKCoordinateRegion region = {{0,0},{1.0,1.0}};
region.center.latitude = 41.036651; //user defined
region.center.longitude = 28.983870;//user defined
[myMapView setRegion:region animated:YES];
[self.view addSubview:myMapView];
//we define long press recognizer for 2 seconds and add our map view to add new pin when you press 2 seconds on map view
UILongPressGestureRecognizer *lngPrs = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleMyLongPress:)];
lngPrs.minimumPressDuration = 2.0;
[myMapView addGestureRecognizer:lngPrs];
pinCounter = 1; //this variable hold pin numbers and increment 1 when new pin added.
myAnnotation = [[myCustomPinAnnotationClass alloc]initWithName:[NSString stringWithFormat:@"Pin %i",pinCounter] description:@"touch here to see pin coordinates" pinNum:pinCounter coordinate:region.center];
[myMapView addAnnotation:myAnnotation];
}
- (void)handleMyLongPress:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan) {
}else{
//when we press more than 2 seconds on map view UILongPressGestureRecognizer triggered this method and call our custom MKPinAnnotationView class and add annotation.
CGPoint touchPoint = [gestureRecognizer locationInView:myMapView];
CLLocationCoordinate2D touchMapCoordinate = [myMapView convertPoint:touchPoint toCoordinateFromView:myMapView];
pinCounter++;
myAnnotation = [[myCustomPinAnnotationClass alloc]initWithName:[NSString stringWithFormat:@"Pin %i",pinCounter] description:@"touch here to see pin coordinates" pinNum:pinCounter coordinate:touchMapCoordinate];
[myMapView addAnnotation:myAnnotation];
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
//when new annotation added by us, new annotation property will set here
static NSString *identifier = @"myPins";
if ([annotation isKindOfClass:[myCustomPinAnnotationClass class]]) {
myCustomPinAnnotationClass *annotationView = (myCustomPinAnnotationClass *) [self.myMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[myCustomPinAnnotationClass alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
myAnnotation = (myCustomPinAnnotationClass *)annotation;
annotationView.pinColor = MKPinAnnotationColorGreen;
annotationView.enabled = YES;
annotationView.draggable = YES;
annotationView.canShowCallout = YES;
[annotationView setSelected:YES animated:YES];
return annotationView;
}
return nil;
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
//if you select any annotation to show their callout sellected annotation pin number and coordinate setted and call findcallot method
myAnnotation = (myCustomPinAnnotationClass *)view.annotation;
selectedPinCoordinate = myAnnotation.coordinate;
selectedPinNumber = myAnnotation.pinNum;
[self findCallOut:myMapView];
}
- (void)findCallOut:(UIView *)node
{
//this method dig our mapview with for loop until find callout view class named "UICalloutView"
if([node isKindOfClass:[NSClassFromString(@"UICalloutView") class]]){
//this method trigered together with callout open animation.
//in UICalloutView we have callout bubble image
//we dig it with for loop to find this image height
float buubleHeight = 0.0;
for(UIImageView *bubbleComponents in node.subviews){
//when we find callout bubble image take height to set our touchable area height
buubleHeight = bubbleComponents.frame.size.height;
break;
}
//this method triger with callout open animation as I said before
//ant this bouncing open animation distort actual size of callout view
//so when this happens we also get transform value of callout view and make proportion to find exact sizes.
CGFloat nodeTransformRatio = node.transform.a;
CGFloat calculatedWidth = roundf(node.frame.size.width/nodeTransformRatio);
CGFloat calculatedHeight = roundf(buubleHeight/nodeTransformRatio);
//now create a new UIView and sized according to callout view.
UIView *touchableView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, calculatedWidth, calculatedHeight)];
touchableView.userInteractionEnabled = YES;
//we add new single tap gesture recognizer to triger desired method when users touching to the callout
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething)];
[touchableView addGestureRecognizer:singleTap];
//and finaly we add this newly created view in callout view to receive touches.
[node addSubview:touchableView];
}else{
//loop self until find a "UICalloutView"
for(UIView *child in node.subviews){
[self findCallOut:child];
}
}
}
- (void)doSomething
{
//this method call allert view our preseted variables when users touch callout view.
UIAlertView *alertHolder = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"You're touched the Pin %i CallOut",selectedPinNumber] message:[NSString stringWithFormat:@"lat : %f\nlong : %f",selectedPinCoordinate.latitude,selectedPinCoordinate.longitude] delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok",nil];
[alertHolder show];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
myCustomPinAnnotationClass.h
//
// myCustomPinAnnotationClass.h
// touchableCallOuts
//
// Created by yasin turkoglu on 20.11.2012.
// Copyright (c) 2012 yasin turkoglu. All rights reserved.
//
#import <MapKit/MapKit.h>
@interface myCustomPinAnnotationClass : MKPinAnnotationView <MKAnnotation> {
NSString *_name;
NSString *_description;
int _pinNum;
CLLocationCoordinate2D _coordinate;
}
@property (copy) NSString *name;
@property (copy) NSString *description;
@property (nonatomic, readonly) int pinNum;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithName:(NSString*)header description:(NSString*)description pinNum:(int)pinNum coordinate:(CLLocationCoordinate2D)coordinate;
@end
myCustomPinAnnotationClass.m
//
// myCustomPinAnnotationClass.m
// touchableCallOuts
//
// Created by yasin turkoglu on 20.11.2012.
// Copyright (c) 2012 yasin turkoglu. All rights reserved.
//
#import "myCustomPinAnnotationClass.h"
@implementation myCustomPinAnnotationClass
@synthesize name = _name;
@synthesize description = _description;
@synthesize pinNum = _pinNum;
@synthesize coordinate = _coordinate;
- (id)initWithName:(NSString*)header description:(NSString*)description pinNum:(int)pinNum coordinate:(CLLocationCoordinate2D)coordinate
{
self = [super init];
if (self) {
_name = [header copy];
_description = [description copy];
_pinNum = pinNum;
_coordinate = coordinate;
}
return self;
}
- (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate
{
_coordinate = newCoordinate;
}
- (NSString *)title {
return _name;
}
- (NSString *)subtitle {
return _description;
}
- (int)tag {
return _pinNum;
}
-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
//test touched point in map view
//when hit test return nil callout close immediately by default
UIView* hitView = [super hitTest:point withEvent:event];
// if hittest return nil test touch point
if (hitView == nil){
//dig view to find custom touchable view lately added by us
for(UIView *firstView in self.subviews){
if([firstView isKindOfClass:[NSClassFromString(@"UICalloutView") class]]){
for(UIView *touchableView in firstView.subviews){
if([touchableView isKindOfClass:[UIView class]]){ //this is our touchable view class
//define touchable area
CGRect touchableArea = CGRectMake(firstView.frame.origin.x, firstView.frame.origin.y, touchableView.frame.size.width, touchableView.frame.size.height);
//test touch point if in touchable area
if (CGRectContainsPoint(touchableArea, point)){
//if touch point is in touchable area return touchable view as a touched view
hitView = touchableView;
}
}
}
}
}
}
return hitView;
}
@end
在這裏,您可以下載完整的項目源代碼https://github.com/ytur/touchableCallOutsForIOSMaps
相關問題
- 1. 標註上方的標註
- 2. 如何檢測註解的標註顯示在mapview上?
- 3. 檢測註銷
- 4. 註釋標註標題不變
- 5. 檢測SQL注入
- 6. 如何在使用OpenCV的紙張上檢測註冊標記?
- 7. 標註圖像
- 8. 註釋標記
- 9. @Reference標註爲
- 10. 標註MapView Android
- 11. 上標註
- 12. UITableView中的標註
- 13. 檢測註冊的HttpListeners
- 14. 檢測新註冊的MBean
- 15. Salesforce Apex:測試尚未發出標註
- 16. 在Scintilla NET中檢測遊標超過註釋或字符串
- 17. 在MK ANNOTATION視圖標註氣泡上檢測到水龍頭
- 18. 如何檢索地圖註記座標?
- 19. Android GCM:檢索設備註冊標識
- 20. 檢查哪個註釋標註正在打開
- 21. Mapbox標註圖片
- 22. 箭頭標註matplotlib
- 23. 定製MKAnnotationView標註
- 24. 標註了在Django
- 25. Microsoft CRM 4.0標註
- 26. Mapbox標註附件
- 27. 通過注入DeadLock檢測
- 28. CSS側欄腳註檢測
- 29. 圖像標註和註釋工具
- 30. 註釋標註不起作用Swift
你好@ytur我有同樣的問題,我的自定義詳圖索引視圖上市。我已經實現了'hitTest:withEvent:',但'[super hitTest:withEvent:]'永遠不會返回'nil'。當我點擊標註視圖時 - 它消失了,但是當我點擊標註視圖上的按鈕時 - 它沒有。有任何想法嗎? – k06a
這裏是我的完整問題:http://stackoverflow.com/questions/17449775/custom-map-callout-view-hides-on-tap – k06a