Search code examples
touchmkmapviewuitouchuiresponder

Touches landing in MKMapView are not sent to the UIApplication instance


I am intercepting all events (for debugging purposes) in my custom UIApplication subclass:

[super sendEvent:event];
if(event.type == UIEventTypeTouches){
    if(event.allTouches.anyObject.phase == UITouchPhaseBegan){
    //    NSLog(@"Touch began on view %@", event.allTouches.anyObject.view);
    }
}

It is working for any touch, regardless of the view, gesture recognizers, user interaction etc.

However, I've got a MKMapView that isn't receiving any touches (user interaction is enabled) and not even forwarding touches to the application instance. In other words, when I touch that specific MKMapView, sendEvent: isn't called on application.

How is this even possible? As far as I know, no matter what I do, UIApplication should always receive a touch at the sendEvent: method.

Am I missing something? (I am on iOS 11.4)


Solution

  • I've finally solved the problem.

    I was constantly animating the map according to the user's orientation (compass, tilt etc.) to create a 3D effect even if the device was tilted/moved a single bit, which seems to happen continuously:

    ...
    motionManager = [[CMMotionManager alloc] init];
    motionManager.deviceMotionUpdateInterval = 0.033;
    [motionManager startDeviceMotionUpdatesUsingReferenceFrame:frame
                                                       toQueue:motionQueue
                                                   withHandler:
     ^(CMDeviceMotion* motion, NSError* error){
         //update map
     }];
    ...
    

    In the map update method, I was animating the map to the new camera data to smooth out the update visually:

    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveLinear
    animations:block completion:nil];
    

    Because of the constant animation, the view was ignoring touch input.

    I've added UIViewAnimationOptionAllowUserInteraction to my animation options, which solved the issue:

    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveLinear 
    | UIViewAnimationOptionAllowUserInteraction animations:block completion:nil];