从Firebase加载的UICollectionView实现图片长按保存遇手势错误
解决长按手势报错及实现图片保存到相册功能
你遇到的这个NSInvalidArgumentException错误,本质是Swift版本带来的Selector语法问题,再加上手势逻辑的小疏漏,咱们一步步来修复:
1. 先搞定未识别选择器的核心错误
在Swift 4及以后的版本中,已经不再支持用字符串直接指定Selector了,你原来的代码里:
let photoLngPrs = UILongPressGestureRecognizer(target: self, action: "handleLongPress")
这种写法已经失效,必须改成Swift官方推荐的#selector语法,同时要匹配方法的参数签名:
let photoLngPrs = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
另外,如果你的handleLongPress方法后续改成私有方法,记得给它加上@objc标记,确保系统能通过Selector找到它。
2. 修复长按手势的逻辑bug
你当前的handleLongPress方法里,第一行就判断gestureRecognizer.state == .began然后直接return,这等于长按刚触发就直接终止了,根本不会执行后续的获取indexPath和保存逻辑!咱们调整一下逻辑,只在手势开始时处理一次(避免重复触发):
@objc func handleLongPress(gestureRecognizer : UILongPressGestureRecognizer) { // 只在手势开始阶段处理一次,防止重复触发 guard gestureRecognizer.state == .began else { return } let point = gestureRecognizer.location(in: self.galleryCollectionView) if let indexPath = galleryCollectionView.indexPathForItem(at: point) { // 获取对应的图片数据 let targetImageModel = images[indexPath.row] // 获取cell上已经加载好的图片 if let cell = galleryCollectionView.cellForItem(at: indexPath) as? GalleryCollectionViewCell, let imageToSave = cell.galleryView.image { // 调用系统方法保存到相册 UIImageWriteToSavedPhotosAlbum(imageToSave, self, #selector(imageSaveCompletion(_:didFinishSavingWithError:contextInfo:)), nil) } } else { print("Could not find Index Path") } }
3. 添加保存结果的回调方法
保存图片到相册是异步操作,咱们需要一个回调方法来告知用户保存结果,记得加上@objc标记:
@objc func imageSaveCompletion(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) { let alert: UIAlertController if let error = error { alert = UIAlertController(title: "保存失败", message: error.localizedDescription, preferredStyle: .alert) } else { alert = UIAlertController(title: "保存成功", message: "图片已经成功保存到相册啦", preferredStyle: .alert) } alert.addAction(UIAlertAction(title: "好的", style: .default)) present(alert, animated: true) }
4. 别忘了配置相册权限
iOS 10及以后,访问相册必须申请权限,你需要在项目的Info.plist文件中添加NSPhotoLibraryAddUsageDescription键,值填写权限申请的说明(比如"需要访问您的相册来保存图片"),否则保存操作会直接失败。
最后再检查两个小细节
- 你代码里已经设置了
cell.galleryView.isUserInteractionEnabled = true,这点很重要,确保图片能接收手势事件 - 确保
handleLongPress方法的访问级别不是private(如果非要设为private,记得加上@objc)
这样修改后,你的长按手势就能正常工作,并且顺利实现保存图片到相册的功能了。
内容的提问来源于stack exchange,提问作者Adrian Navarro
相关产品推荐
相关产品推荐

