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