最近要做一个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
}
// 相簿列表页控制器
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)
// 相册按包含的照片数量排序(降序)
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){
for i in 0..// 获取出但前相簿内的图片
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!
// 带缓存的图片管理对象
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对象
整个项目源码地址