Xcode11.4.1升级后出现UITargetedPreview不在窗口的API警告求助
解决UITargetedDragPreview的"Neither the view or container is currently in a window"警告
我刚帮你定位到问题所在了——你遇到的这个警告,核心原因是你创建的previewView完全没有加入到应用的视图层级里,而UIDragInteraction的API明确要求,UITargetedDragPreview的预览视图或者它的target容器,必须当前处于应用的window中。
问题拆解
错误信息里的"视图不在窗口中",指的是你传给UITargetedDragPreview的两个关键对象之一(要么是预览用的previewView,要么是UIDragPreviewTarget里的container),没有被添加到任何能关联到window的视图链上。你之前的代码里,previewView是全新初始化的,既没被addSubview到任何已存在的视图,也没有和已在窗口中的视图产生关联,系统自然找不到它的window上下文,所以触发了这个警告。
修复方案
不需要把previewView手动加到视图层级里,更简洁的方法是基于已经在窗口中的源视图生成快照来作为预览视图,这样系统就能识别它的上下文了。修改后的代码如下:
- (UITargetedDragPreview *)dragInteraction:(UIDragInteraction *)interaction previewForLiftingItem:(UIDragItem *)item session:(id<UIDragSession>)session { UIView *sourceView = interaction.view; CGPoint point = [session locationInView:sourceView]; // 用源视图生成快照作为预览视图,确保预览视图关联到已在窗口的视图 UIView *previewView = [sourceView snapshotViewAfterScreenUpdates:YES]; previewView.frame = CGRectMake(0, 0, self.elementDimension, self.elementDimension); [previewView setBackgroundColor:[UIColor colorWithRed:0.98 green:0.97 blue:0.89 alpha:1.00]]; // 这里可以保留你原来对previewView的其他定制逻辑 if (@available(iOS 13.0, *)) { UIPreviewParameters *previewParameters = [[UIPreviewParameters alloc] init]; [previewParameters setBackgroundColor:[UIColor clearColor]]; // 确认container是已在窗口中的视图(这里用sourceView本身即可,前提是它已经被添加到视图层级) UIDragPreviewTarget *target = [[UIDragPreviewTarget alloc] initWithContainer:sourceView center:point]; return [[UITargetedDragPreview alloc] initWithView:previewView parameters:previewParameters target:target]; } else { // Fallback on auto generated versions return nil; } }
额外检查点
除了修改预览视图的创建方式,你还可以确认两个点:
- 确保触发拖拽时,
interaction.view(你的源UIView)已经完全加载并添加到window中——比如不要在viewDidLoad阶段就允许拖拽,最好等viewDidAppear之后再启用交互。 - 如果你更换了
UIDragPreviewTarget的container,也要保证这个container视图当前处于window的视图链里。
内容的提问来源于stack exchange,提问作者Martijn
相关产品推荐
相关产品推荐

