首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >客户端应用程序错误-- UITargetedPreview的视图或容器当前都不在窗口中

客户端应用程序错误-- UITargetedPreview的视图或容器当前都不在窗口中
EN

Stack Overflow用户
提问于 2020-05-15 22:37:03
回答 1查看 1.1K关注 0票数 1

我试图修复的Xcode控制台中的UIKit警告请求帮助:

客户端应用程序错误-- UITargetedPreview的视图或容器目前都不在窗口中。这违反了UIDragInteraction API协议,并可能导致严重的视觉glich.

我有一个UITableView的拖放源,它实现了UITableViewDragDelegate。表视图在拆分视图主视图中,目标位于拆分视图控制器中。拖放交互非常有效。问题是来自Xcode的相当可怕的错误!

UIDragItem是通过以下方式生成的:

代码语言:javascript
复制
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方法,但是当预览生成时出现警告,这似乎是在稍后的过程中出现的。

我将张贴我的拖曳方法,看看我是否遗漏了什么。

提前谢谢。

代码语言:javascript
复制
// 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  
    }  
} 

我创建了一个调试项目来再现:

调试

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-16 20:44:16

我的解决方案是放弃UITableViewDragDelegate,实现来自自定义UITableViewCell的拖动交互。我不确定这是否是正确的方法,但它已经清除了错误。

对于从Imanou 在UIView之间拖动UIViews拖放这个答案的简单演示,我发现它很有用。很明显苹果文档将视图设置为拖动源

对我来说,线索在于错误本身,抱怨UITargetedPreview缺乏视图或容器。从我所看到的情况来看,UITargetedPreview不是UITableViewDelegate系统的一部分,我假设是因为UITableViewDelegate系统纯粹是为了绘制和放入UITableView本身而设计的。

我的使用是不同的,我试图从一个UITableView拖到任何地方。

TLDR;

新的UITableView移除所有UITableViewDragDelegate方法并添加所需的自定义单元格初始化器:

代码语言:javascript
复制
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是:

代码语言:javascript
复制
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中心设置了预览中心。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61829440

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档