grgcombs / MultiRowCalloutAnnotationView

An iOS MapKit callout annotation view with independent cells and accessory actions.
Other
249 stars 53 forks source link

Invalid Coordinate crash #2

Closed kylebuttress closed 12 years ago

kylebuttress commented 12 years ago

Hi,

Occasionally I get a crash when the map is moved and the map centre is being re positioned.

with the crash notice

Invalid Coordinate -212.53626430, +486.04761195

Causing the following backtrace

2 CoreFoundation 0x31cf87d3 handleUncaughtException + 238 3 libobjc.A.dylib 0x34e3606b _objc_terminate + 102 4 libstdc++.6.dylib 0x3442be3d _ZN10cxxabiv111terminateEPFvvE + 52 5 libstdc++.6.dylib 0x3442be91 _ZSt9terminatev + 16 6 libstdc++.6.dylib 0x3442bf61 cxa_throw + 84 7 libobjc.A.dylib 0x34e34c8b objc_exception_throw + 70 8 CoreFoundation 0x31cf83cd -[NSException dealloc] + 0 9 MapKit 0x34781fe3 -[MKMapView setCenterCoordinate:animated:] + 230 10 odpn 0x00072ae1 -MultiRowCalloutAnnotationView adjustMapRegionIfNeeded 11 odpn 0x00071f8f -MultiRowCalloutAnnotationView didMoveToSuperview 12 UIKit 0x3726c377 -[UIView(Hierarchy) _postMovedFromSuperview:] + 178 13 UIKit 0x372605d7 -[UIView(Hierarchy) removeFromSuperview] + 334 14 MapKit 0x347665c1 -[MKAnnotationContainerView _removeAnnotationView:updateCollections:] + 240 15 MapKit 0x347664c9 -[MKAnnotationContainerView _removeAnnotationView:] + 16 16 MapKit 0x34766243 -[MKAnnotationContainerView removeAnnotation:] + 234 17 MapKit 0x34779517 -[MKMapView removeAnnotation:] + 30

This is the code near 468

//Calculate new center point, if needed if (xPixelShift || yPixelShift) { CGFloat pixelsPerDegreeLongitude = self.mapView.frame.size.width / self.mapView.region.span.longitudeDelta; CGFloat pixelsPerDegreeLatitude = self.mapView.frame.size.height / self.mapView.region.span.latitudeDelta;

    CLLocationDegrees longitudinalShift = -(xPixelShift / pixelsPerDegreeLongitude);
    CLLocationDegrees latitudinalShift = yPixelShift / pixelsPerDegreeLatitude;

    CLLocationCoordinate2D newCenterCoordinate = {self.mapView.region.center.latitude + latitudinalShift, self.mapView.region.center.longitude + longitudinalShift};

    [self.mapView setCenterCoordinate:newCenterCoordinate animated:YES];

    //fix for now next line 468
    self.frame = CGRectMake(self.frame.origin.x - xPixelShift, self.frame.origin.y - yPixelShift, self.frame.size.width, self.frame.size.height);
    //fix for later (after zoom or other action that resets the frame)
    self.centerOffset = CGPointMake(self.centerOffset.x - xPixelShift, self.centerOffset.y);
}

I'm looking to see if there is a way to over come this.

thanks

Kyle

grgcombs commented 12 years ago

What happens if you just check the validity of the coordinate before you set the center on the map view?

if (CLLocationCoordinate2DIsValid(newCenterCoordinate))
    [self.mapView setCenterCoordinate:newCenterCoordinate animated:YES];

Also, I don't think this annotation view class should retain a reference to the mapview in it's properties ... that's a good way to wind up in a retain/release cycle. I'm going to experiment with it as an assign instead. Nevertheless, I suspect there's something else going on that I haven't sussed out yet.

grgcombs commented 12 years ago

Looking more into the issue, I'm fairly dissatisfied with the hackish nature of adjustMapRegionIfNeeded() and the related animations. There has to be a more elegant approach to this.

grgcombs commented 12 years ago

Also, try this:

- (void)didMoveToSuperview {
    [super didMoveToSuperview];
    if (!self.mapView || !self.superview)
        return;  // superview can/will be nil during deallocation
    [self adjustMapRegionIfNeeded];
    [self animateIn];
    [self setNeedsLayout];
}
kylebuttress commented 12 years ago

Hi Greg,

Thanks for the fast reply, I'll make some changes when I get to the office, and will let you know how this works out.

thanks Kyle

kylebuttress commented 12 years ago

Hi Greg,

The check for valid coord trapped the issue as you mentioned I would occasionally get results like this 2012-01-06 08:53:53.707 odpn[3445:707] map region lat [ -27.445273 ] lon [ 153.027041 ] 2012-01-06 08:53:53.709 odpn[3445:707] lat shift [ -185.081039 ] lon shift [ 333.025330 ]

just prior to

CLLocationCoordinate2D newCenterCoordinate = {self.mapView.region.center.latitude + latitudinalShift, self.mapView.region.center.longitude + longitudinalShift};

checking for the valid coord would stop the crash,

however when I made the change to didMoveToSuperView

I could not reproduce the crash at all.

Now to figure out why when I change the map to satellite or hybrid the custom pins revert to the default ones.

thanks for your help.

Nice work on this customisation as well..

cheers

Kyle

grgcombs commented 12 years ago

Fixed in bcc5673