Search code examples
rubymotion

Image not working in custom MKOverlayRenderer (RubyMotion)


I have a RubyMotion app with a MKMapView in a controller that I am trying to add an image overlay to.

I'm adding the overlay here (the delegate of the MKMapView instance is set to the controller itself):

image = UIImage.imageNamed("map").CGImage 
lowerLeft = CLLocationCoordinate2DMake(21.652538062803, -127.620375523875420)
upperRight = CLLocationCoordinate2DMake(50.406626367301044, -66.517937876818)

overlay = ImageOverlay.alloc.initWithImageData image, withLowerLeftCoordinate:lowerLeft,   withUpperRightCoordinate:upperRight
self.view.addOverlay overlay

Here's my custom overlay:

class ImageOverlay
  attr_accessor :imageData
  attr_accessor :mapRect

  def initWithImageData imageData, withLowerLeftCoordinate:lowerLeftCoordinate, withUpperRightCoordinate:upperRightCoordinate
    self.imageData = imageData

    lowerLeft = MKMapPointForCoordinate(lowerLeftCoordinate)
    upperRight = MKMapPointForCoordinate(upperRightCoordinate)

    self.mapRect = MKMapRectMake(lowerLeft.x, upperRight.y, upperRight.x - lowerLeft.x, lowerLeft.y - upperRight.y)

    return self
  end

  def coordinate
    return MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMidX(self.mapRect), MKMapRectGetMidY(self.mapRect)))
  end

  def boundingMapRect
    return self.mapRect
  end
end

And here is the custom MKOverlayRenderer:

class ImageOverlayRenderer < MKOverlayRenderer

  def drawMapRect mapRect, zoomScale:zoomScale, inContext:context

    puts "drawMapRect"

    theMapRect = self.overlay.boundingMapRect
    theRect = self.rectForMapRect(theMapRect)

    CGContextScaleCTM(context, 1.0, -1.0)
    CGContextTranslateCTM(context, 0.0, -theRect.size.height)

    CGContextDrawImage(context, theRect, self.overlay.imageData)
  end
end

And in my view controller I am overriding the mapView:rendererForOverlay method:

def mapView mapView, rendererForOverlay:overlay

  if overlay.isKindOfClass(ImageOverlay)
    renderer = ImageOverlayRenderer.alloc.initWithOverlay overlay
    return renderer
  end

  return nil
end

The problem is that drawMapRect is never called and the app crashes with no error except stating a crash report may have been generated, which contains this:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000000

Everything else seems to work up until that point, mapView:rendererForOverlay is invoked and I am returning the renderer. I even override canDrawMapRect and it was being invoked.

Any ideas on how to get this working?


Solution

  • The problem was related to bug in RubyMotion which has been fixed and will be made available in the next release:

    http://hipbyte.myjetbrains.com/youtrack/issue/RM-533

    Update: The fix has been released in RubyMotion 2.31 and I have verified it resolves my issue.