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:
in the error message in the console. Should I add previewView to the view hierarchy before init'ing the UITargetedDragPreview?
Thanks!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With