Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Neither the view or container of the UITargetedPreview is currently in a window

The complete error states:

CLIENT APP ERROR - Neither the view or container of the UITargetedPreview is currently in a window. This is in violation of UIDragInteraction API contract and can cause a severe visual glich. THIS IS A CLIENT APP BUG and will soon be a hard assert. PLEASE FIX ME

This nice little warning came up since a day when I upgraded my Xcode to 11.4.1 Before, this warning never popped up in my console.

So I drag from a UIView into another UIView, no UITableViews or UICollectionViews are involved. I set a draginteraction in a UIView and a dropinteraction on the receiving UIViews.

This is the code from the UIDragInteraction delegate

- (UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id<UIDragSession>)session {
    UIView *view = interaction.view;
    CGPoint point = [session locationInView:interaction.view];
    UIDragPreviewTarget *target = [[UIDragPreviewTarget alloc] initWithContainer:view center:point];

    UIView *previewView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.elementDimension, self.elementDimension)];
    [previewView setBackgroundColor:[UIColor colorWithRed:0.98 green:0.97 blue:0.89 alpha:1.00]];
    //I've removed the filling of previewView because it has nothing to see with the question

    if (@available(iOS 13.0, *)) {
        UIPreviewParameters *previewParameters = [[UIPreviewParameters alloc] init];
        [previewParameters setBackgroundColor:[UIColor clearColor]];

        return [[UITargetedDragPreview alloc] initWithView:previewView
                                                parameters:previewParameters
                                                    target:target];
    } else {
        // Fallback on auto generated versions
        return nil;
    }
}

I don't understand what is meant by:

  • the view
  • the window

in the error message in the console. Should I add previewView to the view hierarchy before init'ing the UITargetedDragPreview?

Thanks!

like image 440
Martijn Avatar asked Oct 25 '25 07:10

Martijn


1 Answers

I've been struggling with this for a long time now ... what I did was to add my custom preview (your previewView) to the collection view when the drag begins as shown below

- ( NSArray < UIDragItem * > * ) collectionView:( UICollectionView   * ) collectionView
                   itemsForBeginningDragSession:( id < UIDragSession > ) session
                                    atIndexPath:( NSIndexPath        * ) indexPath

{
  // ... make preview

  // add to collection view
  [collectionView addSubview:preview];

  // retain pointer
  self.preview = preview;

  // ...
}

and then to retain a (weak) pointer to it and remove it again as follows

- ( void ) collectionView:( UICollectionView   * ) collectionView
        dragSessionDidEnd:( id < UIDragSession > ) session
{
    // overkill I know but whatever
    if ( self.preview )
    {
        self.preview.removeFromSuperview;
        self.preview = nil;
    }
}

This seems to work and you will see the view being added and later removed from the collection view. To get rid of that I tried set it to hidden but that did not work, so I ended up doing something like

  preview.frame = CGRectMake( -1000, -1000, preview.frame.size.width, preview.frame.size.height );

Quite hacky but so far so good. Although mine is for a collection view, I think it would be easy to transfer to your environment.

like image 87
skaak Avatar answered Oct 26 '25 21:10

skaak