You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除UICollectionView拖拽时UIDragPreview的阴影

解决UICollectionView拖拽单元格时的阴影隐藏问题

我在开发UICollectionView组件时遇到一个问题:拖拽单元格时会出现默认阴影,需要将其隐藏。尝试通过实现collectionView(_:dragPreviewParametersForItemAt:)代理方法来配置UIDragPreviewParameters,但没有达到预期效果,初始代码如下:

func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        let item = self.itemList[indexPath.row]
        var dragItem: UIDragItem!
        if let path = item.icon {
            let itemProvider = NSItemProvider(object: path as NSString)
            dragItem = UIDragItem(itemProvider: itemProvider)
            dragItem.localObject = item
            
            dragItem.previewProvider  = { () -> UIDragPreview? in
                let previewImageView = UIImageView(image: UIImage(named: "test"))
                previewImageView.frame =  CGRect(x: 0, y: 0, width: 90, height: 90)
                
                let dragPreview = UIDragPreview(view: previewImageView)
                return dragPreview
            }
        }
        
        return [dragItem]
    }
    
func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters? {
        let previewParameters = UIDragPreviewParameters()
        previewParameters.backgroundColor = .clear
        if #available(iOS 14.0, *) {
            previewParameters.shadowPath = UIBezierPath(rect: .zero)
        }
                
        return previewParameters
    }

解决方案

问题的核心是:当自定义previewProvider返回自己的UIDragPreview时,代理方法返回的UIDragPreviewParameters不会被应用到这个自定义预览上。正确的做法是在创建UIDragPreview时,直接将配置好的UIDragPreviewParameters作为参数传入,这样背景和阴影就能消失。

修改后的代码如下:

func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
        let mood = self.moodList[indexPath.row]
        var dragItem: UIDragItem!
        if let path = mood.icon {
            let itemProvider = NSItemProvider(object: path as NSString)
            dragItem = UIDragItem(itemProvider: itemProvider)
            dragItem.localObject = mood
            
            guard let cell = collectionView.cellForItem(at: indexPath) else {return [dragItem]}
            let cellInsetContents = cell.contentView.bounds.insetBy(dx: 0, dy: 0)
            
            dragItem.previewProvider  = { () -> UIDragPreview? in
                let previewImageView = UIImageView(image: UIImage(named: "test"))
                previewImageView.frame =  CGRect(x: 0, y: 0, width: 90, height: 90)
                
                let dragPreviewParams = UIDragPreviewParameters()
                dragPreviewParams.backgroundColor = .clear
                if #available(iOS 14.0, *) {
                    dragPreviewParams.shadowPath = UIBezierPath(rect: .zero)
                } else {
                    // Fallback on earlier versions
                }

                dragPreviewParams.visiblePath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: 90, height: 90), cornerRadius: 0)
                
                let dragPreview = UIDragPreview(view: previewImageView, parameters: dragPreviewParams)
                return dragPreview
            }
        }
        
        return [dragItem]
    }

关键改动:

  • 在previewProvider闭包内直接创建并配置UIDragPreviewParameters
  • 设置backgroundColor为.clear移除预览背景
  • iOS14+版本设置shadowPath为零矩形,彻底隐藏阴影
  • 指定visiblePath确保预览区域与自定义视图匹配
  • 使用带参数的UIDragPreview初始化方法,将配置参数传入

内容的提问来源于stack exchange,提问作者Uğur Uğurlu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 16:25:35