移除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
相关产品推荐
相关产品推荐

