相册图片多选功能的实现

使用  UIImagePickerController,我们可以很方便的从系统相册中选择照片。但  UIImagePickerController 每次只能选择一张图片,不支持多选。这样如果我们需要一次上传多张图片到服务器,使用  UIImagePickerController 效率就会很低。
本文演示如何实现一个多选组件,类似微信发朋友圈那样,可以一次打勾选择多张照片。

一、组件介绍

1,实现原理

(1)我们通过  Photos 框架( PhotoKit)读取出所有图片数据,并使用自定义的  collection view 将缩略图显示出来,同时实现相关的多选功能。
(2)相簿列表同样是通过  PhotoKit 读取出所有相簿信息,并使用  tableview 展示出来。

2,效果图

(1)点击“ 开始选择照片”按钮,会弹出我们自定义的图片多选组件。默认显示出“ 相机胶卷”里的所有照片。
    原文:Swift - 相册图片多选功能的实现       原文:Swift - 相册图片多选功能的实现

(2)点击导航栏左上角的“ 相簿”按钮,即可列出设备中所有相簿,点击便显示出该相簿中的所有照片。
    原文:Swift - 相册图片多选功能的实现       原文:Swift - 相册图片多选功能的实现

(3)点击图片缩略图即可在选中和取消选中状态间切换,同时图片右上角的打勾图标在状态改变时也会有弹性变化效果。
原文:Swift - 相册图片多选功能的实现

(4)选择图片的同时下方工具栏也会实时显示出选中的图片数量,这个改变时同样有动画效果。如果超过限制(可用设置),则会弹出消息提示。
    原文:Swift - 相册图片多选功能的实现       原文:Swift - 相册图片多选功能的实现

(5)点击“ 完成”按钮,退出图片选择组件。这里我们在在回调方法中把选中的结果给打印出来。
原文:Swift - 相册图片多选功能的实现

二、组件介绍

整个组件的代码结构如下,下面分别进行介绍。
原文:Swift - 相册图片多选功能的实现

1,相簿列表相关

(1) HGImagePickerController.swift(相簿列表页控制器)
  • 注意最下面,为方便使用,我扩展了 UIViewController,添加了个 presentHGImagePicker() 方法,调用后便会出现照片选择组件。
  • 虽然上面方法调用时加载的是相簿列表视图。但一开始时会先加载相机胶卷图片,并自动跳转到图片选择视图。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import  UIKit
import  Photos
 
//相簿列表项
struct  HGImageAlbumItem  {
     //相簿名称
     var  title: String ?
     //相簿内的资源
     var  fetchResult: PHFetchResult < PHAsset >
}
 
//相簿列表页控制器
class  HGImagePickerController UIViewController  {
     //显示相簿列表项的表格
     @IBOutlet  weak  var  tableView: UITableView !
     
     //相簿列表项集合
     var  items:[ HGImageAlbumItem ] = []
     
     //每次最多可选择的照片数量
     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:  "hgImageCollectionVC" )
                     as HGImageCollectionViewController {
                     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(cancel) )
         self .navigationItem.rightBarButtonItem = rightBarItem
     }
     
     //转化处理获取到的相簿
     private  func  convertCollection(collection: PHFetchResult < PHAssetCollection >){
         for  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 = titleOfAlbumForChinse(title: c.localizedTitle)
                 items.append( HGImageAlbumItem (title: title,
                                               fetchResult: assetsFetchResult))
             }
         }
     }
     
     //由于系统返回的相册集名称为英文,我们需要转换为中文
     private  func  titleOfAlbumForChinse(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  cancel() {
         //退出当前视图控制器
         self .dismiss(animated:  true , completion:  nil )
     }
     
     //页面跳转
     override  func  prepare( for  segue:  UIStoryboardSegue , sender:  Any ?) {
         //如果是跳转到展示相簿缩略图页面
         if  segue.identifier ==  "showImages" {
             //获取照片展示控制器
             guard  let  imageCollectionVC = segue.destination
                 as HGImageCollectionViewController ,
                 let  cell = sender  as HGImagePickerCell  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  HGImagePickerController : UITableViewDelegate , UITableViewDataSource {
     //设置单元格内容
     func  tableView(_ tableView:  UITableView , cellForRowAt indexPath:  IndexPath )
         ->  UITableViewCell  {
         //同一形式的单元格重复使用,在声明时已注册
         let  cell = tableView.dequeueReusableCell(withIdentifier:  "cell" for : indexPath)
             as HGImagePickerCell
         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  {
     //HGImagePicker提供给外部调用的接口,同于显示图片选择页面
     func  presentHGImagePicker(maxSelected: Int  Int . max ,
                               completeHandler:((_ assets:[ PHAsset ])->())?)
         ->  HGImagePickerController ?{
         //获取图片选择视图控制器
         if  let  vc =  UIStoryboard (name:  "HGImage" , bundle:  Bundle .main)
             .instantiateViewController(withIdentifier:  "imagePickerVC" )
             as HGImagePickerController {
             //设置选择完毕后的回调
             vc.completeHandler = completeHandler
             //设置图片最多选择的数量
             vc.maxSelected = maxSelected
             //将图片选择视图控制器外添加个导航控制器,并显示
             let  nav =  UINavigationController (rootViewController: vc)
             self .present(nav, animated:  true , completion:  nil )
             return  vc
         }
         return  nil
     }
}

(2) HGImagePickerCell.swift(相簿列表单元格)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  UIKit
 
//相簿列表单元格
class  HGImagePickerCell 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)
     }
}


2,图片选择页面相关

(1) HGImageCollectionViewController.swift(图片缩略图集合页控制器)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
import  UIKit
import  Photos
 
//图片缩略图集合页控制器
class  HGImageCollectionViewController 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: HGImageCompleteButton !
     
     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.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 =  HGImageCompleteButton ()
         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)
         })
     }
}
 
//图片缩略图集合页控制器UICollectionViewDataSource,UICollectionViewDelegate协议方法的实现
extension  HGImageCollectionViewController : UICollectionViewDataSource
, UICollectionViewDelegate {
     //CollectionView项目
     func  collectionView(_ collectionView:  UICollectionView ,
                         numberOfItemsInSection section:  Int ) ->  Int  {
         return  self .assetsFetchResults?.count ?? 0
     }
     
     // 获取单元格
     func  collectionView(_ collectionView:  UICollectionView ,
                         cellForItemAt indexPath:  IndexPath ) ->  UICollectionViewCell  {
         //获取storyboard里设计的单元格,不需要再动态添加界面元素
         let  cell = collectionView.dequeueReusableCell(withReuseIdentifier:  "cell" ,
                                     for : indexPath)  as HGImageCollectionViewCell
         let  asset =  self .assetsFetchResults![indexPath.row]
         //获取缩略图
         self .imageManager.requestImage( for : asset, targetSize: assetGridThumbnailSize,
                                        contentMode: .aspectFill, options:  nil ) {
                                         (image, nfo)  in
             cell.imageView.image = image
         }
         
         return  cell
     }
     
     //单元格选中响应
     func  collectionView(_ collectionView:  UICollectionView ,
                         didSelectItemAt indexPath:  IndexPath ) {
         if  let  cell = collectionView.cellForItem(at: indexPath)
             as HGImageCollectionViewCell {
             //获取选中的数量
             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 HGImageCollectionViewCell {
              //获取选中的数量
             let  count =  self .selectedCount()
             completeButton.num = count
              //改变完成按钮数字,并播放动画
             if  count == 0{
                 completeButton.isEnabled =  false
             }
             cell.playAnimate()
         }
     }
}

(2) HGImageCollectionViewCell.swift(图片缩略图集合页单元格)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import  UIKit
 
//图片缩略图集合页单元格
open  class  HGImageCollectionViewCell UICollectionViewCell  {
     //显示缩略图
     @IBOutlet  weak  var  imageView: UIImageView !
     
     //显示选中状态的图标
     @IBOutlet  weak  var  selectedIcon: UIImageView !
     
     //设置是否选中
     open  override  var  isSelected:  Bool  {
         didSet {
             if  isSelected {
                 selectedIcon.image =  UIImage (named:  "hg_image_selected" )
             } else {
                 selectedIcon.image =  UIImage (named:  "hg_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 )
     }
     
     open  override  func  awakeFromNib() {
         super .awakeFromNib()
         imageView.contentMode = .scaleAspectFill
         imageView.clipsToBounds =  true
     }
}

(3) HGImageCompleteButton.swift(照片选择页下方工具栏的“完成”按钮)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import  UIKit
 
//照片选择页下方工具栏的“完成”按钮
class  HGImageCompleteButton 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 ) {
         super . init (coder: aDecoder)
     }
     
     //用户数字改变时播放的动画
     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 )
     }
     
     //添加事件响应
     func  addTarget(target:  Any ?, action:  Selector ?) {
         //单击监听
         tapSingle =  UITapGestureRecognizer (target:target,action:action)
         tapSingle!.numberOfTapsRequired = 1
         tapSingle!.numberOfTouchesRequired = 1
         self .addGestureRecognizer(tapSingle!)
     }
}

3,相关资源

(1) HGImage.xcassets
里面就两个图标图片,分别表示选中和未选中状态。
原文:Swift - 相册图片多选功能的实现

(2) HGImage.storyboard
  • 在 storyboard 中添加两个 View Controller Scene,分别绑定上面的 HGImagePickerController 和 HGImageCollectionViewController
  • 同时两个 Scene 中的 cell 分别绑定 HGImagePickerCell 和 HGImageCollectionViewCell
  • Image Picker Controller Scene  Storyboard ID 设置为 imagePickerVC。单元格 identifier 设置为 cell
  • Image Collection View Controller Scene 的 Storyboard ID 设置为 hgImageCollectionVC。单元格 identifier 设置为 cell
  •  Image Picker Controller Scene 的单元格拖动一个 Segue 到 Image Collection View Controller Scene。类型为 Showidentifier 为 showImages
原文:Swift - 相册图片多选功能的实现

三、使用样例

1,Info.plist配置

由于苹果安全策略更新,在使用  Xcode8 开发时,需要在  Info.plist 配置请求照片相的关描述字段( Privacy - Photo Library Usage Description
原文:Swift - 相册图片多选功能的实现

2,样例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import  UIKit
 
class  ViewController UIViewController  {
 
     override  func  viewDidLoad() {
         super .viewDidLoad()
     }
 
     //“开始选择照片”按钮点击
     @IBAction  func  buttonTapped(_ sender:  AnyObject ) {
         //开始选择照片,最多允许选择4张
         _ =  self .presentHGImagePicker(maxSelected:4) { (assets)  in
             //结果处理
             print ( "共选择了\(assets.count)张图片,分别如下:" )
             for  asset  in  assets {
                 print (asset)
             }
         }
     }
     
     override  func  didReceiveMemoryWarning() {
         super .didReceiveMemoryWarning()
     }
}
原文链接: http://www.hangge.com/blog/cache/detail_1512.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android系统提供了一个名为 "Gallery" 的应用程序,它可以允许用户在本地相册中选择多个图片,并将这些图片传递给应用程序。但是,由于 "Gallery" 应用程序已经被弃用,我们可以使用其他第三方库来实现类似的效果。 以下是一个使用 "Glide" 和 "PhotoPicker" 库来实现本地相册多选功能的示例代码: 1. 在 build.gradle 文件中添加 "Glide" 和 "PhotoPicker" 库的依赖: ``` dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0' implementation 'me.iwf.photopicker:PhotoPicker:0.9.12@aar' } ``` 2. 在 AndroidManifest.xml 文件中添加读取本地相册的权限: ``` <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ``` 3. 在 Java 代码中调用 "PhotoPicker" 库来选择多个图片: ``` PhotoPicker.builder() .setPhotoCount(9) // 设置最多选择的图片数量 .setShowCamera(true) // 显示相机按钮 .setShowGif(true) // 显示 GIF 图片 .setPreviewEnabled(false) // 不显示预览界面 .start(context, PhotoPicker.REQUEST_CODE); ``` 4. 在 onActivityResult 方法中获取选择的图片列表: ``` @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == PhotoPicker.REQUEST_CODE) { List<String> photos = null; if (data != null) { photos = data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS); } // 在这里对选择的图片进行处理 } } ``` 5. 如果需要显示选择的图片,可以使用 "Glide" 库来加载和显示图片: ``` Glide.with(context) .load(photoPath) // 图片路径 .into(imageView); // 图片显示控件 ``` 希望这个示例代码能够帮助你实现本地相册多选功能

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值