MKAnnotationView 子视图
MKAnnotationView Subviews
目前,我的项目在实现具有多个自定义 UIImageView 的自定义 MKAnnotationView 时遇到问题。因此,这些自定义 UIImageViews 在其顶部有一个清晰的按钮,无需添加手势识别器。
如您所见,实际点击 MKAnnotationView 子视图并进行一些操作会很有帮助。
我为 MKAnnotationView 实现了一个协议,其中 MKAnnotationView 中的每个图像子视图都会回调到作为 MKMapView 所有者的控制器...这是代码...
PHProfileImageView *image = [[PHProfileImageView alloc] initWithFrame:CGRectMake(newX - radius / 5.0f, newY - radius / 5.0f, width, height)];
[image setFile:[object objectForKey:kPHEventPictureKey]];
[image.layer setCornerRadius:image.frame.size.height/2];
[image.layer setBorderColor:[[UIColor whiteColor] CGColor]];
[image.layer setBorderWidth:2.0f];
[image.layer setMasksToBounds:YES];
[image.profileButton setTag:i];
[image.profileButton addTarget:self action:@selector(didTapEvent:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:image];
- (void)didTapEvent:(UIButton *)button
{
NSLog(@"%@", [self.pins objectAtIndex:button.tag]);
if (self.delegate && [self.delegate respondsToSelector:@selector(didTapEvent:)]) {
[self.delegate JSClusterAnnotationView:self didTapEvent:[self.pins objectAtIndex:button.tag]];
}
}
如您所见,我已经尝试记录点击图像的结果,但什么也没有:(。我实现这个的方式不是正确的方法吗?我应该有 CAShapeLayers 还是什么?目前不太确定。有人有任何想法吗?
编辑
我想我可能必须实施自定义标注视图。由于标注视图实际上在其视图中添加了按钮并且可以响应触摸事件......但不完全确定,因为标注仅在点击注释视图后才会显示。在这种情况下,ACTUAL 注释视图是中间标签
所以我将 mkannotationview 的框架调整为更大的框架,显然所有子视图实际上都不在 MKAnnotationView 的范围内,因此子视图实际上没有被点击。现在我正在考虑这个解决方案,它可能不是最好的解决方案。
如果有人有任何建议而不是向 MKAnnotationView 添加子视图来创建我当前拥有的视图,那就太好了!
对于带有可点击按钮的自定义 AnnotationView,您必须在项目中创建自定义 AnnotationView 子类。为此创建一个新文件。
并将这两个方法添加到实现文件中。
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
UIView* hitView = [super hitTest:point withEvent:event];
if (hitView != nil)
{
[self.superview bringSubviewToFront:self];
}
return hitView;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
CGRect rect = self.bounds;
BOOL isInside = CGRectContainsPoint(rect, point);
if(!isInside)
{
for (UIView *view in self.subviews)
{
isInside = CGRectContainsPoint(view.frame, point);
if(isInside)
break;
}
}
return isInside;
}
然后再次进入ViewController.m文件,将viewDidLoad方法修改成这样。
- (void)viewDidLoad {
[super viewDidLoad];
self.mapKit.delegate = self;
//Set Default location to zoom
CLLocationCoordinate2D noLocation = CLLocationCoordinate2DMake(51.900708, -2.083160); //Create the CLLocation from user cordinates
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 50000, 50000); //Set zooming level
MKCoordinateRegion adjustedRegion = [self.mapKit regionThatFits:viewRegion]; //add location to map
[self.mapKit setRegion:adjustedRegion animated:YES]; // create animation zooming
// Place Annotation Point
MKPointAnnotation *annotation1 = [[MKPointAnnotation alloc] init]; //Setting Sample location Annotation
[annotation1 setCoordinate:CLLocationCoordinate2DMake(51.900708, -2.083160)]; //Add cordinates
[self.mapKit addAnnotation:annotation1];
}
现在将该自定义视图添加到 ViewController.xib。
现在创建如下委托方法。
#pragma mark : MKMapKit Delegate
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
AnnotationView *pinView = nil; //create MKAnnotationView Property
static NSString *defaultPinID = @"com.invasivecode.pin"; //Get the ID to change the pin
pinView = (AnnotationView *)[self.mapKit dequeueReusableAnnotationViewWithIdentifier:defaultPinID]; //Setting custom MKAnnotationView to the ID
if ( pinView == nil )
pinView = [[AnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID]; // init pinView with ID
[pinView addSubview:self.customView];
addSubview:self.customView.center = CGPointMake(self.customView.bounds.size.width*0.1f, -self.customView.bounds.size.height*0.5f);
pinView.image = [UIImage imageNamed:@"Pin"]; //Set the image to pinView
return pinView;
}
我几个月前也从 Whosebug 上的某人那里得到了这个答案。我根据需要将其修改为我的项目。希望这会完成你的工作。
目前,我的项目在实现具有多个自定义 UIImageView 的自定义 MKAnnotationView 时遇到问题。因此,这些自定义 UIImageViews 在其顶部有一个清晰的按钮,无需添加手势识别器。
如您所见,实际点击 MKAnnotationView 子视图并进行一些操作会很有帮助。
我为 MKAnnotationView 实现了一个协议,其中 MKAnnotationView 中的每个图像子视图都会回调到作为 MKMapView 所有者的控制器...这是代码...
PHProfileImageView *image = [[PHProfileImageView alloc] initWithFrame:CGRectMake(newX - radius / 5.0f, newY - radius / 5.0f, width, height)];
[image setFile:[object objectForKey:kPHEventPictureKey]];
[image.layer setCornerRadius:image.frame.size.height/2];
[image.layer setBorderColor:[[UIColor whiteColor] CGColor]];
[image.layer setBorderWidth:2.0f];
[image.layer setMasksToBounds:YES];
[image.profileButton setTag:i];
[image.profileButton addTarget:self action:@selector(didTapEvent:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:image];
- (void)didTapEvent:(UIButton *)button
{
NSLog(@"%@", [self.pins objectAtIndex:button.tag]);
if (self.delegate && [self.delegate respondsToSelector:@selector(didTapEvent:)]) {
[self.delegate JSClusterAnnotationView:self didTapEvent:[self.pins objectAtIndex:button.tag]];
}
}
如您所见,我已经尝试记录点击图像的结果,但什么也没有:(。我实现这个的方式不是正确的方法吗?我应该有 CAShapeLayers 还是什么?目前不太确定。有人有任何想法吗?
编辑
我想我可能必须实施自定义标注视图。由于标注视图实际上在其视图中添加了按钮并且可以响应触摸事件......但不完全确定,因为标注仅在点击注释视图后才会显示。在这种情况下,ACTUAL 注释视图是中间标签
所以我将 mkannotationview 的框架调整为更大的框架,显然所有子视图实际上都不在 MKAnnotationView 的范围内,因此子视图实际上没有被点击。现在我正在考虑这个解决方案,它可能不是最好的解决方案。
如果有人有任何建议而不是向 MKAnnotationView 添加子视图来创建我当前拥有的视图,那就太好了!
对于带有可点击按钮的自定义 AnnotationView,您必须在项目中创建自定义 AnnotationView 子类。为此创建一个新文件。
并将这两个方法添加到实现文件中。
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
UIView* hitView = [super hitTest:point withEvent:event];
if (hitView != nil)
{
[self.superview bringSubviewToFront:self];
}
return hitView;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
{
CGRect rect = self.bounds;
BOOL isInside = CGRectContainsPoint(rect, point);
if(!isInside)
{
for (UIView *view in self.subviews)
{
isInside = CGRectContainsPoint(view.frame, point);
if(isInside)
break;
}
}
return isInside;
}
然后再次进入ViewController.m文件,将viewDidLoad方法修改成这样。
- (void)viewDidLoad {
[super viewDidLoad];
self.mapKit.delegate = self;
//Set Default location to zoom
CLLocationCoordinate2D noLocation = CLLocationCoordinate2DMake(51.900708, -2.083160); //Create the CLLocation from user cordinates
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 50000, 50000); //Set zooming level
MKCoordinateRegion adjustedRegion = [self.mapKit regionThatFits:viewRegion]; //add location to map
[self.mapKit setRegion:adjustedRegion animated:YES]; // create animation zooming
// Place Annotation Point
MKPointAnnotation *annotation1 = [[MKPointAnnotation alloc] init]; //Setting Sample location Annotation
[annotation1 setCoordinate:CLLocationCoordinate2DMake(51.900708, -2.083160)]; //Add cordinates
[self.mapKit addAnnotation:annotation1];
}
现在将该自定义视图添加到 ViewController.xib。
现在创建如下委托方法。
#pragma mark : MKMapKit Delegate
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
AnnotationView *pinView = nil; //create MKAnnotationView Property
static NSString *defaultPinID = @"com.invasivecode.pin"; //Get the ID to change the pin
pinView = (AnnotationView *)[self.mapKit dequeueReusableAnnotationViewWithIdentifier:defaultPinID]; //Setting custom MKAnnotationView to the ID
if ( pinView == nil )
pinView = [[AnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:defaultPinID]; // init pinView with ID
[pinView addSubview:self.customView];
addSubview:self.customView.center = CGPointMake(self.customView.bounds.size.width*0.1f, -self.customView.bounds.size.height*0.5f);
pinView.image = [UIImage imageNamed:@"Pin"]; //Set the image to pinView
return pinView;
}
我几个月前也从 Whosebug 上的某人那里得到了这个答案。我根据需要将其修改为我的项目。希望这会完成你的工作。