Search code examples
iosuitableviewdrag-and-dropipadosuiscene

Context Menu blocks Drag and Drop into new window


This iPadOS/iOS 13 app implements both multiple windows and drag and drop. In almost every case, both work perfectly.

We encounter our only problem in a table view that implements the context menu methods of UITableViewDelegate.

- tableView:contextMenuConfigurationForRowAtIndexPath:point:Beta
- tableView:willPerformPreviewActionForMenuWithConfiguration:animator:Beta

If we initiate the drag before the Context Menu appears, then we can successfully drag the item into a new window (UIScene) by moving it to the edge of the screen. However, if we initiate the drag after the Context Menu has appeared, it is not possible to drag the item into a new window or scene.

Does anyone know what the source of the problem is?

Here are two contrasting videos showcasing the problem:

Failure

This is the drag and drop failing.

Success

This is the drag and drop succeeding.


Solution

  • The Identified Problem

    In viewDidAppear: we were executing the following:

    UISceneActivationConditions *conditions = self.view.window.windowScene.activationConditions;
    conditions.prefersToActivateForTargetContentIdentifierPredicate = [NSPredicate predicateWithFormat:@"self == %@", self.note.noteID];
    conditions.canActivateForTargetContentIdentifierPredicate = [NSPredicate predicateWithFormat:@"self == %@", self.note.noteID];
    

    When a Context Menu was displayed, viewDidAppear: was called and the .activationConditions were applied to the current UIScene.

    Note that the Context Menu's previewing view controller shares the NSUserActivity details with the drag + drop item, and so the .targetContentIdentifier of the NSUserActivity we were trying to drag was matching the .activationConditions predicate of the current UIScene. Consequently, when displaying the Context Menu's previewing view controller, we were telling the system that the current UIScene is the optimal recipient of the drag event, preventing other, new windows from receiving it (at least, that's my supposition).

    (While I disagree with that behavior, it seems to be how UIScene Activation Conditions are being interpreted in this iOS 13.1.3.)

    The Solution

    To fix it I simply prevented the configuration of .activationConditions when displaying the view controller within a Context Menu.

    Here's an updated video showing successful drag + drop, even with the Context Menu being displayed: Successfully using drag and drop with Context Menu