Ios 客户端应用程序错误-UITargetedPreview的视图或容器当前都不在窗口中
我在试图修复的Xcode控制台中请求有关UIKit警告的帮助: 客户端应用程序错误-UITargetedPreview的视图或容器当前都不在窗口中。这违反了UIDraginInteraction API合同,可能会导致严重的视觉问题。 我有一个Ios 客户端应用程序错误-UITargetedPreview的视图或容器当前都不在窗口中,ios,swift,uikit,Ios,Swift,Uikit,我在试图修复的Xcode控制台中请求有关UIKit警告的帮助: 客户端应用程序错误-UITargetedPreview的视图或容器当前都不在窗口中。这违反了UIDraginInteraction API合同,可能会导致严重的视觉问题。 我有一个UITableView的拖动源,它实现了UITableViewDragDelegate。表视图位于拆分视图主视图中,目标位于拆分视图控制器中。拖放交互非常有效。问题是来自Xcode的相当可怕的错误 UIDragItem由以下内容生成: extension
UITableView
的拖动源,它实现了UITableViewDragDelegate
。表视图位于拆分视图主视图中,目标位于拆分视图控制器中。拖放交互非常有效。问题是来自Xcode的相当可怕的错误
UIDragItem
由以下内容生成:
extension Store: NSItemProviderWriting {
var dragItem: UIDragItem {
let dragItem = UIDragItem(itemProvider: NSItemProvider(object: self))
dragItem.localObject = self
dragItem.previewProvider = {
let image = UIImageView(image: self.imageFront)
image.frame = CGRect(x: 0, y: 0, width: 40, height: 40) // magic number for store preview size
return UIDragPreview(view: image)
}
return dragItem
}
}
我尝试中断所有的UIDragDelegate
方法,但是在生成预览时会出现警告,这似乎是在过程的后面
我将发布我的拖动方法,以查看是否缺少任何内容
提前谢谢
// MARK: - Table view drag delegate
extension StoresTableViewController: UITableViewDragDelegate {
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
return [stores[indexPath.row].dragItem]
}
func tableView(_ tableView: UITableView, dragSessionWillBegin session: UIDragSession) {
guard let draggedStore = session.items.first?.localObject as? Store else { return }
if draggedStore.maxSimilarStores > session.items.count {
tableView.performBatchUpdates({
let index = stores.firstIndex(of: draggedStore)!
stores.remove(at: index)
stores.insert(draggedStore.copy() as! Store, at: index)
tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .fade)
}, completion: nil)
}
}
func tableView(_ tableView: UITableView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem] {
guard let draggedStore = session.items.first?.localObject as? Store else { return [] }
let tableStore = stores[indexPath.row]
if draggedStore.name == tableStore.name && draggedStore.maxSimilarStores > session.items.count {
return [tableStore.dragItem]
} else {
return []
}
}
func tableView(_ tableView: UITableView, dragPreviewParametersForRowAt indexPath: IndexPath) -> UIDragPreviewParameters? {
guard let cell = tableView.cellForRow(at: indexPath) as? StoreTableViewCell else { return nil }
let parameters = UIDragPreviewParameters()
parameters.visiblePath = UIBezierPath(rect: cell.storeImageView.frame)
return parameters
}
}
我已经创建了一个调试项目来复制:
谢谢我的解决方案是放弃
UITableViewDragDelegate
并从自定义的UITableViewCell
实现拖动交互。我不确定这是否是正确的方法,但它已清除了错误
对于一个简单的拖放演示,我发现这个答案非常有用。显然,苹果公司的文件
我的线索是错误本身,抱怨缺少UITargetedPreview
的视图或容器。从我所看到的UITargetedPreview
不是UITableViewDelegate
系统的一部分,我假设是因为UITableViewDelegate
系统纯粹是为在UITableView
本身内部绘制和放置而设计的
我的用途不同,我试图从UITableView
拖动到任何地方
TLDR强>
新的UITableView
删除所有UITableViewDragDelegate
方法,并添加所需的自定义单元格初始值设定项:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StoreCell", for: indexPath) as! StoreTableViewCell
let dragInteraction = UIDragInteraction(delegate: cell)
cell.addInteraction(dragInteraction)
cell.store = stores[indexPath.row]
{...}
return cell
}
自定义UITableViewCell
为:
class StoreTableViewCell: UITableViewCell {
var store: Store?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
{...}
}
extension StoreTableViewCell: UIDragInteractionDelegate {
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
if let dragItem = store?.dragItem {
return [dragItem]
}
return []
}
func dragInteraction(_ interaction: UIDragInteraction, previewForLifting item: UIDragItem, session: UIDragSession) -> UITargetedDragPreview? {
if let store = store, let frontImage = store.imageFront {
let imageView = UIImageView(image: frontImage)
imageView.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let target = UIPreviewTarget(container: storeImageView, center: session.location(in: storeImageView))
let parameters = UIPreviewParameters()
parameters.backgroundColor = .clear
let preview = UITargetedDragPreview(view: imageView, parameters: parameters, target: target)
return preview
}
return nil
}
}
请注意,
UIPreviewTarget
是自定义UITableViewCell
中的图像(尽管我希望这可以是任何视图)我从UIDragSession
中心设置预览中心。我的解决方案是放弃UITableViewDragDelegate
,并从自定义的UITableViewCell
实现拖动交互。我不确定这是否是正确的方法,但它已清除了错误
对于一个简单的拖放演示,我发现这个答案非常有用。显然,苹果公司的文件
我的线索是错误本身,抱怨缺少UITargetedPreview
的视图或容器。从我所看到的UITargetedPreview
不是UITableViewDelegate
系统的一部分,我假设是因为UITableViewDelegate
系统纯粹是为在UITableView
本身内部绘制和放置而设计的
我的用途不同,我试图从UITableView
拖动到任何地方
TLDR强>
新的UITableView
删除所有UITableViewDragDelegate
方法,并添加所需的自定义单元格初始值设定项:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "StoreCell", for: indexPath) as! StoreTableViewCell
let dragInteraction = UIDragInteraction(delegate: cell)
cell.addInteraction(dragInteraction)
cell.store = stores[indexPath.row]
{...}
return cell
}
自定义UITableViewCell
为:
class StoreTableViewCell: UITableViewCell {
var store: Store?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
{...}
}
extension StoreTableViewCell: UIDragInteractionDelegate {
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
if let dragItem = store?.dragItem {
return [dragItem]
}
return []
}
func dragInteraction(_ interaction: UIDragInteraction, previewForLifting item: UIDragItem, session: UIDragSession) -> UITargetedDragPreview? {
if let store = store, let frontImage = store.imageFront {
let imageView = UIImageView(image: frontImage)
imageView.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
let target = UIPreviewTarget(container: storeImageView, center: session.location(in: storeImageView))
let parameters = UIPreviewParameters()
parameters.backgroundColor = .clear
let preview = UITargetedDragPreview(view: imageView, parameters: parameters, target: target)
return preview
}
return nil
}
}
请注意,UIPreviewTarget
是自定义UITableViewCell
中的图像(尽管我希望这可以是任何视图),我从UIDragSession
中心设置预览中心