用Swift实现iOS相机及相册图片上传

xiaoxiao2021-02-27  441

最近要做一个iOS相机及相册图片上传,其中遇到了这些问题:1、图片增删在UICollectionView里的变化;2、获取相机拍摄的照片和相册的照片;3、将PHAsset对象转为UIImage对象;


具体实现过程: 首先整个控件结构如图所示: storyboard长这样: 拖动三个UIViewController如图所示,其中:AlbumImageCollectionViewController(id为ImageCollectionVC)中拖入一个UICollectionView、一个UIToolBar,UICollectionView中的cell(id为cell)拖入两个UIImageView;AlbumImagePickerViewController(id为imagePickerVC)中拖入一个UITableView,UITableView的cell(id为cell)拖入两个UILabel。


PhotoCollectionViewCell:

import UIKit // 已选择的图片缩略图cell class PhotoCollectionViewCell: UICollectionViewCell { // 已选择的图片 var imageView: UIImageView! // 删除按钮 var button = UIButton() // MARK: - 初始化方法 override init(frame: CGRect) { super.init(frame: frame) // 设置缩略图大小 imageView = UIImageView(frame: self.bounds) // 设置按钮属性 button = UIButton(type: UIButtonType.custom) button.setImage(UIImage.init(named: "delete"), for: UIControlState.normal) button.frame = CGRect(x: frame.size.width - 21, y: 1, width: 20, height: 20) self.addSubview(imageView) self.addSubview(button) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }

AlbumImagePickerTableViewCell:

import UIKit // 相簿列表单元格 class AlbumImagePickerTableViewCell: UITableViewCell { // 相簿名称标签 @IBOutlet weak var titleLabel: UILabel! // 照片数量标签 @IBOutlet weak var countLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() self.layoutMargins = UIEdgeInsets.zero } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) } }

AlbumImageCollectionViewCell:

import UIKit // 图片缩略图集合页单元格 class AlbumImageCollectionViewCell: UICollectionViewCell { // 显示缩略图 @IBOutlet weak var imageView: UIImageView! // 显示选中状态的图标 @IBOutlet weak var selectedIcon: UIImageView! // 设置是否选中 open override var isSelected: Bool { didSet{ if isSelected { selectedIcon.image = UIImage(named: "image_selected") }else{ selectedIcon.image = UIImage(named: "image_not_selected") } } } // 播放动画,是否选中的图标改变时使用 func playAnimate() { // 图标先缩小,再放大 UIView.animateKeyframes(withDuration: 0.4, delay: 0, options: .allowUserInteraction, animations: { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.2, animations: { self.selectedIcon.transform = CGAffineTransform(scaleX: 0.7, y: 0.7) }) UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.4, animations: { self.selectedIcon.transform = CGAffineTransform.identity }) }, completion: nil) } override func awakeFromNib() { super.awakeFromNib() imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true } }

AlbumImageCompleteButton:

import UIKit // 照片选择页下方工具栏的“完成”按钮 class AlbumImageCompleteButton: UIView { // 已选照片数量标签 var numLabel: UILabel! // 按钮标题标签“完成” var titleLabel: UILabel! // 按钮的默认尺寸 let defaultFrame = CGRect(x: 0, y: 0, width: 70, height: 20) // 文字颜色(同时也是数字背景颜色) let titleColor = UIColor(red: 0x09/255, green: 0xbb/255, blue: 0x07/255, alpha: 1) // 点击点击手势 var tapSingle: UITapGestureRecognizer? // 设置数量 var num:Int = 0{ didSet{ if num == 0{ numLabel.isHidden = true }else{ numLabel.isHidden = false numLabel.text = "\(num)" playAnimate() } } } //是否可用 var isEnabled:Bool = true { didSet{ if isEnabled { titleLabel.textColor = titleColor tapSingle?.isEnabled = true }else{ titleLabel.textColor = UIColor.gray tapSingle?.isEnabled = false } } } init(){ super.init(frame:defaultFrame) // 已选照片数量标签初始化 numLabel = UILabel(frame:CGRect(x: 0 , y: 0 , width: 20, height: 20)) numLabel.backgroundColor = titleColor numLabel.layer.cornerRadius = 10 numLabel.layer.masksToBounds = true numLabel.textAlignment = .center numLabel.font = UIFont.systemFont(ofSize: 15) numLabel.textColor = UIColor.white numLabel.isHidden = true self.addSubview(numLabel) // 按钮标题标签初始化 titleLabel = UILabel(frame:CGRect(x: 20 , y: 0 , width: defaultFrame.width - 20, height: 20)) titleLabel.text = "完成" titleLabel.textAlignment = .center titleLabel.font = UIFont.systemFont(ofSize: 15) titleLabel.textColor = titleColor self.addSubview(titleLabel) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 添加事件响应 func addTarget(target: Any?, action: Selector?) { // 单击监听 tapSingle = UITapGestureRecognizer(target:target,action:action) tapSingle!.numberOfTapsRequired = 1 tapSingle!.numberOfTouchesRequired = 1 self.addGestureRecognizer(tapSingle!) } // 用户数字改变时播放的动画 func playAnimate() { // 从小变大,且有弹性效果 self.numLabel.transform = CGAffineTransform(scaleX: 0.1, y: 0.1) UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: UIViewAnimationOptions(), animations: { self.numLabel.transform = CGAffineTransform.identity }, completion: nil) } }

AlbumImagePickerViewController:

import UIKit import Photos // 相簿列表项 struct AlbumItem { // 相簿名称 var title:String? // 相簿内的资源 var fetchResult:PHFetchResult<PHAsset> } // 相簿列表页控制器 class AlbumImagePickerViewController: UIViewController { // 显示相簿列表项的表格 @IBOutlet weak var tableView: UITableView! // 相簿列表项集合 var items: [AlbumItem] = [] // 每次最多可选择的照片数量 var maxSelected: Int = Int.max // 照片选择完毕后的回调 var completeHandler: ((_ assets:[PHAsset])->())? // 从xib或者storyboard加载完毕就会调用 override func awakeFromNib() { super.awakeFromNib() // 申请权限 PHPhotoLibrary.requestAuthorization({ (status) in if status != .authorized { return } // 列出所有系统的智能相册 let smartOptions = PHFetchOptions() let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options: smartOptions) self.convertCollection(collection: smartAlbums) // 列出所有用户创建的相册 let userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil) self.convertCollection(collection: userCollections as! PHFetchResult<PHAssetCollection>) // 相册按包含的照片数量排序(降序) self.items.sort { (item1, item2) -> Bool in return item1.fetchResult.count > item2.fetchResult.count } // 异步加载表格数据,需要在主线程中调用reloadData() 方法 DispatchQueue.main.async{ self.tableView?.reloadData() // 首次进来后直接进入第一个相册图片展示页面(相机胶卷) if let imageCollectionVC = self.storyboard? .instantiateViewController(withIdentifier: "ImageCollectionVC") as? AlbumImageCollectionViewController{ imageCollectionVC.title = self.items.first?.title imageCollectionVC.assetsFetchResults = self.items.first?.fetchResult imageCollectionVC.completeHandler = self.completeHandler imageCollectionVC.maxSelected = self.maxSelected self.navigationController?.pushViewController(imageCollectionVC, animated: false) } } }) } // 页面加载完毕 override func viewDidLoad() { super.viewDidLoad() // 设置标题 title = "相簿" // 设置表格相关样式属性 self.tableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) self.tableView.rowHeight = 55 // 添加导航栏右侧的取消按钮 let rightBarItem = UIBarButtonItem(title: "取消", style: .plain, target: self, action:#selector(cancelBtnClicked) ) self.navigationItem.rightBarButtonItem = rightBarItem self.tableView.delegate = self self.tableView.dataSource = self } // 转化处理获取到的相簿 private func convertCollection(collection:PHFetchResult<PHAssetCollection>){ for i in 0..<collection.count{ // 获取出但前相簿内的图片 let resultsOptions = PHFetchOptions() resultsOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] resultsOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue) let c = collection[i] let assetsFetchResult = PHAsset.fetchAssets(in: c , options: resultsOptions) // 没有图片的空相簿不显示 if assetsFetchResult.count > 0 { let title = titleOfAlbumForChinese(title: c.localizedTitle) items.append(AlbumItem(title: title, fetchResult: assetsFetchResult)) } } } // 由于系统返回的相册集名称为英文,我们需要转换为中文 private func titleOfAlbumForChinese(title:String?) -> String? { if title == "Slo-mo" { return "慢动作" } else if title == "Recently Added" { return "最近添加" } else if title == "Favorites" { return "个人收藏" } else if title == "Recently Deleted" { return "最近删除" } else if title == "Videos" { return "视频" } else if title == "All Photos" { return "所有照片" } else if title == "Selfies" { return "自拍" } else if title == "Screenshots" { return "屏幕快照" } else if title == "Camera Roll" { return "相机胶卷" } return title } // 取消按钮点击监听方法 func cancelBtnClicked() { // 退出当前vc self.dismiss(animated: true, completion: nil) } // 页面跳转 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 如果是跳转到展示相簿缩略图页面 if segue.identifier == "showImages"{ // 获取照片展示控制器 guard let imageCollectionVC = segue.destination as? AlbumImageCollectionViewController, let cell = sender as? AlbumImagePickerTableViewCell else{ return } // 设置回调函数 imageCollectionVC.completeHandler = completeHandler // 设置标题 imageCollectionVC.title = cell.titleLabel.text // 设置最多可选图片数量 imageCollectionVC.maxSelected = self.maxSelected guard let indexPath = self.tableView.indexPath(for: cell) else { return } // 获取选中的相簿信息 let fetchResult = self.items[indexPath.row].fetchResult // 传递相簿内的图片资源 imageCollectionVC.assetsFetchResults = fetchResult } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } // 相簿列表页控制器UITableViewDelegate,UITableViewDataSource协议方法的实现 extension AlbumImagePickerViewController: UITableViewDelegate, UITableViewDataSource { // 设置单元格内容 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // 同一形式的单元格重复使用,在声明时已注册 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AlbumImagePickerTableViewCell let item = self.items[indexPath.row] cell.titleLabel.text = "\(item.title ?? "") " cell.countLabel.text = "(\(item.fetchResult.count))" return cell } // 表格单元格数量 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.items.count } // 表格单元格选中 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) } } extension UIViewController { // AlbumImagePicker提供给外部调用的接口,同于显示图片选择页面 func presentAlbumImagePicker(maxSelected:Int = Int.max, completeHandler:((_ assets:[PHAsset])->())?) -> AlbumImagePickerViewController? { if let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "imagePickerVC") as? AlbumImagePickerViewController { //设置选择完毕后的回调 vc.completeHandler = completeHandler //设置图片最多选择的数量 vc.maxSelected = maxSelected //将图片选择视图控制器外添加个导航控制器,并显示 let nav = UINavigationController(rootViewController: vc) self.present(nav, animated: true, completion: nil) return vc } return nil } }

AlbumImageCollectionViewController:

import UIKit import Photos // 图片缩略图集合页控制器 class AlbumImageCollectionViewController: UIViewController { // 用于显示所有图片缩略图的collectionView @IBOutlet weak var collectionView: UICollectionView! // 下方工具栏 @IBOutlet weak var toolBar: UIToolbar! // 取得的资源结果,用了存放的PHAsset var assetsFetchResults: PHFetchResult<PHAsset>! // 带缓存的图片管理对象 var imageManager: PHCachingImageManager! // 缩略图大小 var assetGridThumbnailSize: CGSize! // 每次最多可选择的照片数量 var maxSelected: Int = Int.max // 照片选择完毕后的回调 var completeHandler: ((_ assets: [PHAsset])->())? // 完成按钮 var completeButton: AlbumImageCompleteButton! override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 根据单元格的尺寸计算我们需要的缩略图大小 let scale = UIScreen.main.scale let cellSize = (self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize assetGridThumbnailSize = CGSize(width: cellSize.width * scale, height: cellSize.height * scale) } override func viewDidLoad() { super.viewDidLoad() self.collectionView.dataSource = self self.collectionView.delegate = self // 背景色设置为白色(默认是黑色) self.collectionView.backgroundColor = UIColor.white // 初始化和重置缓存 self.imageManager = PHCachingImageManager() self.resetCachedAssets() // 设置单元格尺寸 let layout = (self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout) layout.itemSize = CGSize(width: UIScreen.main.bounds.size.width/4-1, height: UIScreen.main.bounds.size.width/4-1) // 允许多选 self.collectionView.allowsMultipleSelection = true // 添加导航栏右侧的取消按钮 let rightBarItem = UIBarButtonItem(title: "取消", style: .plain, target: self, action: #selector(cancel)) self.navigationItem.rightBarButtonItem = rightBarItem // 添加下方工具栏的完成按钮 completeButton = AlbumImageCompleteButton() completeButton.addTarget(target: self, action: #selector(finishSelect)) completeButton.center = CGPoint(x: UIScreen.main.bounds.width - 50, y: 22) completeButton.isEnabled = false toolBar.addSubview(completeButton) } // 重置缓存 func resetCachedAssets() { self.imageManager.stopCachingImagesForAllAssets() } // 取消按钮点击 func cancel() { // 退出当前视图控制器 self.navigationController?.dismiss(animated: true, completion: nil) } // 获取已选择个数 func selectedCount() -> Int { return self.collectionView.indexPathsForSelectedItems?.count ?? 0 } // 完成按钮点击 func finishSelect(){ // 取出已选择的图片资源 var assets:[PHAsset] = [] if let indexPaths = self.collectionView.indexPathsForSelectedItems{ for indexPath in indexPaths{ assets.append(assetsFetchResults[indexPath.row] ) } } // 调用回调函数 self.navigationController?.dismiss(animated: true, completion: { self.completeHandler?(assets) }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } // 图片缩略图集合页控制器UICollectionViewDataSource,UICollectionViewDelegate协议方法的实现 extension AlbumImageCollectionViewController: UICollectionViewDelegate, UICollectionViewDataSource { // CollectionView项目 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.assetsFetchResults.count } // 获取单元格 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // 获取storyboard里设计的单元格,不需要再动态添加界面元素 let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! AlbumImageCollectionViewCell let asset = self.assetsFetchResults[indexPath.row] // 获取缩略图 self.imageManager.requestImage(for: asset, targetSize: assetGridThumbnailSize, contentMode: .aspectFill, options: nil) { (image, _) in cell.imageView.image = image } return cell } // 单元格选中响应 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if let cell = collectionView.cellForItem(at: indexPath) as? AlbumImageCollectionViewCell { // 获取选中的数量 let count = self.selectedCount() // 如果选择的个数大于最大选择数 if count > self.maxSelected { // 设置为不选中状态 collectionView.deselectItem(at: indexPath, animated: false) // 弹出提示 let title = "你最多只能选择\(self.maxSelected)张照片" let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert) let cancelAction = UIAlertAction(title:"我知道了", style: .cancel, handler:nil) alertController.addAction(cancelAction) self.present(alertController, animated: true, completion: nil) } // 如果不超过最大选择数 else{ // 改变完成按钮数字,并播放动画 completeButton.num = count if count > 0 && !self.completeButton.isEnabled{ completeButton.isEnabled = true } cell.playAnimate() } } } // 单元格取消选中响应 func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { if let cell = collectionView.cellForItem(at: indexPath) as? AlbumImageCollectionViewCell { // 获取选中的数量 let count = self.selectedCount() completeButton.num = count // 改变完成按钮数字,并播放动画 if count == 0{ completeButton.isEnabled = false } cell.playAnimate() } } }

至此,可以在ViewController里使用这个选择图片的控件了:

import UIKit import Photos class ViewController: UIViewController, UIImagePickerControllerDelegate,UINavigationControllerDelegate { // 存放图片的数组 var imageArray = [UIImage]() // 存放图片等collectionview var collectionView: UICollectionView! // 最大图片张数 let maxImageCount = 9 // 添加图片按钮 var addButton: UIButton! // 选择上传图片方式弹窗 var addImageAlertViewController: UIAlertController! // 缩略图大小 var imageSize: CGSize! override func viewDidLoad() { super.viewDidLoad() // 设置背景色 self.view.backgroundColor = UIColor.groupTableViewBackground // 设置添加图片按钮相关属性 addButton = UIButton(type: UIButtonType.custom) addButton.setTitle("添加图片", for: UIControlState.normal) addButton.addTarget(self, action: #selector(addItem(_:)), for: UIControlEvents.touchUpInside) addButton.backgroundColor = UIColor.init(red: 164 / 255, green: 193 / 255, blue: 244 / 255, alpha: 1) addButton.frame = CGRect(x: 20, y: 35, width: 100, height: 25) addButton.layer.masksToBounds = true addButton.layer.cornerRadius = 8.0 // 设置collection的layout let layout = UICollectionViewFlowLayout() layout.itemSize = CGSize(width: 50, height: 50) // 列间距 layout.minimumInteritemSpacing = 10 // 行间距 layout.minimumLineSpacing = 10 // 偏移量 layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10) // 设置collectionview的大小、背景色、代理、数据源 collectionView = UICollectionView(frame: CGRect(x: 10, y: 60, width: 200, height: self.view.frame.size.height), collectionViewLayout: layout) collectionView.backgroundColor = UIColor.groupTableViewBackground collectionView.delegate = self collectionView.dataSource = self // 注册cell collectionView.register(PhotoCollectionViewCell.self, forCellWithReuseIdentifier: "photoCell") // 选择上传照片方式的弹窗设置 addImageAlertViewController = UIAlertController(title: "请选择上传方式", message: "相册或者相机", preferredStyle: UIAlertControllerStyle.actionSheet) let cancelAction = UIAlertAction(title: "取消", style: UIAlertActionStyle.cancel, handler: nil) let cameraAction = UIAlertAction(title: "拍照", style: UIAlertActionStyle.default, handler: { (action: UIAlertAction) in self.cameraAction() }) let albumAction = UIAlertAction(title: "从相册选择", style: UIAlertActionStyle.default, handler: { (action: UIAlertAction) in self.albumAction() }) self.addImageAlertViewController.addAction(cancelAction) self.addImageAlertViewController.addAction(cameraAction) self.addImageAlertViewController.addAction(albumAction) self.view.addSubview(addButton) self.view.addSubview(collectionView) } override func viewWillAppear(_ animated: Bool) { // 获取缩略图的大小 let cellSize = (self.collectionView.collectionViewLayout as! UICollectionViewFlowLayout).itemSize self.imageSize = cellSize } // MARK: - 删除图片按钮监听方法 func removeItem(_ button: UIButton) { // 数据变更 self.collectionView.performBatchUpdates({ self.imageArray.remove(at: button.tag) let indexPath = IndexPath(item: button.tag, section: 0) let arr = [indexPath] self.collectionView.deleteItems(at: arr) }, completion: {(completion) in self.collectionView.reloadData() }) // 判断是否使添加图片按钮生效 if imageArray.count < 9 { self.addButton.isEnabled = true self.addButton.backgroundColor = UIColor.init(red: 164 / 255, green: 193 / 255, blue: 244 / 255, alpha: 1) } } // MARK: - 添加图片按钮监听方法 func addItem(_ button: UIButton) { self.present(addImageAlertViewController, animated: true, completion: nil) } // MARK: - 拍照监听方法 func cameraAction() { if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.camera) { // 创建图片控制器 let picker = UIImagePickerController() // 设置代理 picker.delegate = self // 设置来源 picker.sourceType = UIImagePickerControllerSourceType.camera // 允许编辑 picker.allowsEditing = true // 打开相机 self.present(picker, animated: true, completion: { () -> Void in }) }else { // 弹出提示 let title = "找不到相机" let alertController = UIAlertController(title: title, message: nil, preferredStyle: .alert) let cancelAction = UIAlertAction(title:"我知道了", style: .cancel, handler:nil) alertController.addAction(cancelAction) self.present(alertController, animated: true, completion: nil) } } // MARK: - 相册监听方法 func albumAction() { // 可选照片数量 let count = maxImageCount - imageArray.count // 开始选择照片,最多允许选择count张 _ = self.presentAlbumImagePicker(maxSelected: count) { (assets) in // 结果处理 for asset in assets { // 从asset获取image let image = self.PHAssetToUIImage(asset: asset) // 数据变更 self.collectionView.performBatchUpdates({ let indexPath = IndexPath(item: self.imageArray.count, section: 0) let arr = [indexPath] self.collectionView.insertItems(at: arr) self.imageArray.append(image) }, completion: {(completion) in self.collectionView.reloadData() }) // 判断是否使添加图片按钮失效 if self.imageArray.count > 8 { self.addButton.isEnabled = false self.addButton.backgroundColor = UIColor.darkGray } } } } // MARK: - 将PHAsset对象转为UIImage对象 func PHAssetToUIImage(asset: PHAsset) -> UIImage { var image = UIImage() // 新建一个默认类型的图像管理器imageManager let imageManager = PHImageManager.default() // 新建一个PHImageRequestOptions对象 let imageRequestOption = PHImageRequestOptions() // PHImageRequestOptions是否有效 imageRequestOption.isSynchronous = true // 缩略图的压缩模式设置为无 imageRequestOption.resizeMode = .none // 缩略图的质量为高质量,不管加载时间花多少 imageRequestOption.deliveryMode = .highQualityFormat // 按照PHImageRequestOptions指定的规则取出图片 imageManager.requestImage(for: asset, targetSize: self.imageSize, contentMode: .aspectFill, options: imageRequestOption, resultHandler: { (result, _) -> Void in image = result! }) return image } // MARK: - 相机图片选择器 func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) { // 将相机刚拍好的照片拿出来 let gotImage = info[UIImagePickerControllerOriginalImage] as! UIImage // 数据变更 self.collectionView.performBatchUpdates({ let indexPath = IndexPath(item: self.imageArray.count, section: 0) let arr = [indexPath] self.collectionView.insertItems(at: arr) self.imageArray.append(gotImage) print(self.imageArray.count) }, completion: {(completion) in self.collectionView.reloadData() }) // 判断是否使添加图片按钮失效 if imageArray.count > 8 { self.addButton.isEnabled = false self.addButton.backgroundColor = UIColor.darkGray } // 关闭此页面 self.dismiss(animated: true, completion: nil) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } // MARK: - collection代理方法实现 extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { // 每个区的item个数 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return imageArray.count } // 分区个数 func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } // 自定义cell func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as! PhotoCollectionViewCell cell.imageView.image = imageArray[indexPath.item] cell.button.addTarget(self, action: #selector(removeItem(_:)), for: UIControlEvents.touchUpInside) cell.button.tag = indexPath.row return cell } // 是否可以移动 func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool { return true } }

参考: 相册图片多选功能的实现 Swift中将PHAsset对象转为UIImage对象 整个项目源码地址

转载请注明原文地址: https://www.6miu.com/read-356.html

最新回复(0)