UIKit Swift:上下文菜单关闭后阴影延迟显示问题求助
问题:关闭上下文菜单后,CollectionView单元格阴影延迟显示
我有一个带阴影的CollectionView单元格,给它添加了上下文菜单。关闭菜单后,单元格及其内部元素的阴影会有大约0.5秒的延迟才显示出来,不清楚问题出在哪里。相关代码如下:
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { if collectionView == foodOnTheShelf { let config = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { _ in let edit = UIAction(title: "Изменить", image: UIImage(systemName: "pencil"), identifier: nil, discoverabilityTitle: nil, state: .off) { _ in self.alert.showAlert(viewController: self, image: UIImage(named: test[indexPath.row].name)!, food: test[indexPath.row], picker: self.picker, consumePicker: self.consumePicker, unit: self.unit, currentWeigt: test[indexPath.row].weight, currentProductDate: test[indexPath.row].productionDate, currentExperationDate: test[indexPath.row].expirationDate, searchController: nil) } let delete = UIAction(title: "Удалить", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in test.remove(at: indexPath.row) self.viewDidAppear(true) } return UIMenu(title: "", image: nil, identifier: nil, options: UIMenu.Options.displayInline , children: [edit, delete]) } return config } return nil }
解决方案
这个延迟问题大概率和上下文菜单关闭后的动画冲突,或是单元格阴影的渲染未及时触发更新,可从以下几个方向修复:
禁止手动调用生命周期方法
你在删除操作里直接调用viewDidAppear(true),这是错误的用法——生命周期方法不应手动触发。正确的做法是用CollectionView的专用更新方法,避免干扰视图渲染流程:let delete = UIAction(title: "Удалить", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in test.remove(at: indexPath.row) self.foodOnTheShelf.deleteItems(at: [indexPath]) }监听菜单关闭事件,强制刷新单元格
通过UIContextMenuInteractionDelegate的方法监听菜单关闭,然后触发对应单元格的图层重绘,确保阴影及时显示:func contextMenuInteractionDidEnd(_ interaction: UIContextMenuInteraction) { guard let indexPath = foodOnTheShelf.indexPathsForSelectedItems?.first else { return } if let cell = foodOnTheShelf.cellForItem(at: indexPath) { cell.layer.setNeedsDisplay() cell.layoutIfNeeded() } }检查单元格阴影的设置逻辑
确保阴影设置在单元格的主图层而非contentView上,同时可开启光栅化优化渲染性能,避免层级导致的延迟:// 在单元格初始化方法中配置阴影 override init(frame: CGRect) { super.init(frame: frame) setupShadow() } private func setupShadow() { layer.shadowColor = UIColor.black.cgColor layer.shadowOpacity = 0.2 layer.shadowOffset = CGSize(width: 0, height: 2) layer.shadowRadius = 4 layer.masksToBounds = false // 可选:开启光栅化提升重复渲染性能 layer.shouldRasterize = true layer.rasterizationScale = UIScreen.main.scale }菜单关闭后立即触发布局刷新
如果以上方法无效,可以在菜单创建时,通过异步队列触发CollectionView的布局失效,强制更新视图:let config = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in // ... 菜单操作定义 let menu = UIMenu(title: "", image: nil, identifier: nil, options: .displayInline , children: [edit, delete]) DispatchQueue.main.async { self?.foodOnTheShelf.collectionViewLayout.invalidateLayout() } return menu }
内容的提问来源于stack exchange,提问作者himynameisartem
相关产品推荐
相关产品推荐

