Reputation: 7227
An UIButton
is set to the rightCalloutAccessoryView
of the MKPinAnnotationView
, and it fires btnClicked:
method. In iOS6, the layout relation between MKAnnotationView
and its rightCalloutAccessoryView
can be easily used to find the MKPinAnnotationView
through MKPinAnnotationView *pin = (MKPinAnnotationView *)[[button superview] superview];
. But in iOS7, the layout relation does not exist anymore.
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation{
...
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:tripStartAddrAnnotationIdentifier];
if (!pinView)
{
MKPinAnnotationView *customPinView = [[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:tripStartAddrAnnotationIdentifier];
customPinView.animatesDrop = NO;
customPinView.canShowCallout = YES;
UIButton* rightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 32, 32)];
[rightButton setImage:[UIImage imageNamed:@"disclosureUpMap.png"] forState:UIControlStateNormal];
[rightButton setImage:[UIImage imageNamed:@"disclosureDownMap.png"] forState:UIControlStateNormal];
[rightButton addTarget:self
action:@selector(btnClicked:)
forControlEvents:UIControlEventTouchUpInside];
customPinView.rightCalloutAccessoryView = rightButton;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
...
}
-(void)btnClicked:(id)sender{
NSLog(@"superview 1 :%@",[sender superview]);
NSLog(@"superview 2 :%@",[[sender superview] superview]);
NSLog(@"superview 3 :%@",[[[sender superview] superview] superview]);
NSLog(@"superview 4 :%@",[[[[sender superview] superview] superview] superview]);
MKPinAnnotationView *pin = (MKPinAnnotationView *)[[sender superview] superview];
// the information contains in pin.annotation is necessary for the pushed view controller
...
}
Log for iOS6:
2013-09-30 01:21:11.851 MyApp[6113:c07] superview 1 :<UICalloutView: 0x1e3df250; frame = (-246 -60; 320 70); clipsToBounds = YES; layer = <CALayer: 0x1e3e0140>>
2013-09-30 01:21:11.851 MyApp[6113:c07] superview 2 :<MKPinAnnotationView: 0x1b649510; frame = (526 223; 32 39); layer = <MKLayer: 0x1b649570>> visible:1 +33.19910200, +120.45132100
2013-09-30 01:21:11.852 MyApp[6113:c07] superview 3 :<MKAnnotationContainerView: 0xb68b380; frame = (0 0; 640 640); autoresizesSubviews = NO; layer = <CALayer: 0xb68b410>>
2013-09-30 01:21:11.852 MyApp[6113:c07] superview 4 :<MKScrollContainerView: 0xb68c8f0; frame = (-280 -72.5; 640 640); autoresizesSubviews = NO; layer = <CALayer: 0xb68c980>>
Log for iOS7:
2013-09-30 01:44:22.835 MyApp[6226:a0b] superview 1 :<_MKSmallCalloutContainerView: 0xdbe5120; frame = (0 0; 222 44); clipsToBounds = YES; layer = <CALayer: 0xdbe1f30>>
2013-09-30 01:44:22.836 MyApp[6226:a0b] superview 2 :<MKSmallCalloutView: 0x1c53a380; frame = (0 0; 222 57); layer = <CALayer: 0x1c546440>>
2013-09-30 01:44:22.837 MyApp[6226:a0b] superview 3 :<UIView: 0xdb14770; frame = (0 0; 222 57); clipsToBounds = YES; layer = <CALayer: 0xdb147d0>>
2013-09-30 01:44:22.837 MyApp[6226:a0b] superview 4 :<_UIPopoverView: 0xdbfa4c0; frame = (-27 -57; 222 57); layer = <CALayer: 0xdbfa5a0>>
Any help will be appreciated.
Upvotes: 5
Views: 1230
Reputation:
This is a great reason to use the map view's own delegate method calloutAccessoryControlTapped
instead of a custom method.
Even if the superview approach works in iOS 6 or earlier, it is generally a bad idea to rely on a specific view hierarchy.
The delegate method conveniently provides a reference to the annotation view from which you can get the annotation via view.annotation
(no guessing or hoping or assumptions).
Remove the addTarget and replace the custom method with the delegate method.
If you must use a custom method instead of the delegate method, it's much more reliable to get the selected annotation from the map view's selectedAnnotations
property instead of looking for superviews.
Upvotes: 4