当前位置:网站首页>Photo selector collectionview
Photo selector collectionview
2022-07-07 05:24:00 【Hanyang Li】
1. Definition PicturePickerController
import UIKit
// reusable Cell
private let PicturePickerCellId = "PicturePickerCellId"
// Maximum number of selected photos
private let PicturePickerMaxCount = 8
//MARK: - Photo picker
class PicturePickerController: UICollectionViewController {
// Matching array
lazy var pictures = [UIImage]()
// The photo index selected by the current user
private var selectedIndex = 0
//MARK: - Constructors
init(){
super.init(collectionViewLayout: PicturePickerLayout())
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// stay collectionViewController in collectionView != view
override func viewDidLoad() {
super.viewDidLoad()
//self.collectionView.backgroundColor = .orange
self.collectionView!.register(PicturePickerCell.self, forCellWithReuseIdentifier: PicturePickerCellId)
}
// Photo selector layout
private class PicturePickerLayout: UICollectionViewFlowLayout{
override func prepare() {
// iOS 9.0 after ,iPad Support split screen , It is not recommended to rely too much on UIScreen As a layout reference
super.prepare()
let count = 4.0
let margin = UIScreen.main.scale * 4
let w = (collectionView!.bounds.width - (count + 1) * margin) / count
itemSize = CGSize(width: w, height: w)
sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: 0, right: margin)
minimumLineSpacing = margin
minimumInteritemSpacing = margin
}
}
}
2. Extended classification , Data source implementation
extension PicturePickerController{
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// Make sure there is a plus button at the end If it reaches the upper limit , No display + Button pictures.count + (pictures.count == PicturePickerMaxCount ? 0 : 1)
return pictures.count + 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: PicturePickerCellId, for: indexPath) as! PicturePickerCell
cell.pictureDelegate = self
cell.image = indexPath.item < pictures.count ? pictures[indexPath.item] : nil
cell.hiddenButton = (indexPath.item == PicturePickerMaxCount)
return cell
}
}
3. Realization Cell Medium proxy method
//MARK: - PicturePickerCellDelegate
extension PicturePickerController: PicturePickerCellDelegate{
func picturePickerCellDidAdd(cell: PicturePickerCell) {
// Determine whether to allow access to the album
/**
PhotoLibrary Saved photos + Synced photos
SavedPhotosAlbum Saved photos / Screenshot of the screen / Taking pictures
*/
if !UIImagePickerController.isSourceTypeAvailable(.savedPhotosAlbum){
print(" Unable to access Photo Gallery ")
return
}
// Record the photo index selected by the current user
selectedIndex = collectionView!.indexPath(for: cell)?.item ?? 0
let picker = UIImagePickerController()
picker.modalPresentationStyle = .fullScreen
picker.delegate = self
//picker.allowsEditing = true
present(picker, animated: true)
}
func picturePickerCellDidRemove(cell: PicturePickerCell) {
//1. Get photo index
let indexPath = collectionView.indexPath(for: cell)!
//2. Determine whether the index exceeds the upper limit
if indexPath.item >= pictures.count{
return
}
collectionView.performBatchUpdates {
//3. Delete data
pictures.remove(at: indexPath.item)
//4. Animation refresh data
collectionView.deleteItems(at: [indexPath])
} completion: { finished in
//5. The refresh data
self.collectionView.reloadData()
}
}
}
4.UIImagePickerController Abide by the agreement
//MARK: - UIImagePickerController Abide by the agreement
extension PicturePickerController: UIImagePickerControllerDelegate, UINavigationControllerDelegate{
/// Photo selection complete
/// - Parameters:
/// - picker: Photo selection controller
/// - info: info Dictionaries
/// - Tips : Once the proxy method is implemented , Must oneself dismiss
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
/**
If you use cocos2dx To develop a ‘ Blank template ’ game , Memory footprint 70M iOS UI A blank application for , Probably 19M
General applications , In memory 100M Both sides are acceptable , No matter how high you are, you need to pay attention
*/
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
let scaleImage = image.scaleToWith(width: 600)
// Add image to array
// Judge whether the currently selected index exceeds the array
if selectedIndex >= pictures.count{
pictures.append(scaleImage)
}else{
pictures[selectedIndex] = scaleImage
}
// Release the controller
dismiss(animated: true) {
// refresh the view
self.collectionView.reloadData()
}
}
}
5.PicturePickerCellDelegate agent
///PicturePickerCellDelegate agent
/// If the agreement includes optional Function of , The protocol needs to use @objc modification
@objc
protocol PicturePickerCellDelegate: NSObjectProtocol{
/// Add photo
@objc optional func picturePickerCellDidAdd(cell: PicturePickerCell)
/// Remove the photo
@objc optional func picturePickerCellDidRemove(cell: PicturePickerCell)
}
6. Photo selection Cell
// Photo selection Cell
class PicturePickerCell: UICollectionViewCell{
// Photo selection agent
weak var pictureDelegate: PicturePickerCellDelegate?
var image: UIImage? {
didSet{
addButton.setImage(image ?? UIImage(named: "compose_pic_add"), for: .normal)
// Hide delete button image == nil Is to add a new button
removeButton.isHidden = (image == nil)
}
}
var hiddenButton: Bool? {
didSet{
addButton.isHidden = hiddenButton ?? false
}
}
//MARK: - Monitoring methods
/// Add photo
@objc func addPicture(){
pictureDelegate?.picturePickerCellDidAdd?(cell: self)
}
/// Remove the photo
@objc func removePicture(){
pictureDelegate?.picturePickerCellDidRemove?(cell: self)
}
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// Setting controls
private func setupUI(){
//1. add controls
contentView.addSubview(addButton)
contentView.addSubview(removeButton)
//2. Setting up layout
addButton.frame = bounds
removeButton.snp.makeConstraints { make in
make.top.equalTo(contentView.snp.top)
make.right.equalTo(contentView.snp.right)
}
//3. Monitoring methods
addButton .addTarget(self, action: #selector(addPicture), for: .touchUpInside)
removeButton.addTarget(self, action: #selector(removePicture), for: .touchUpInside)
//4. Set fill mode
addButton.imageView?.contentMode = .scaleAspectFill
}
//MARK: - Lazy load control
/// Add a button
private lazy var addButton = UIButton(imageName: "compose_pic_add", backImageName: nil)
/// Delete button
private lazy var removeButton = UIButton(imageName: "compose_photo_close", backImageName: nil)
}
7. design sketch
边栏推荐
- Phenomenon analysis when Autowired annotation is used for list
- torch optimizer小解析
- DFS, BFS and traversal search of Graphs
- The sooner you understand the four rules of life, the more blessed you will be
- Timer create timer
- 磁盘监控相关命令
- 10 distributed databases that take you to the galaxy
- [opencv] image morphological operation opencv marks the positions of different connected domains
- 【最佳网页宽度及其实现】「建议收藏」
- QT simple layout box model with spring
猜你喜欢
高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
利用OPNET进行网络单播(一服务器多客户端)仿真的设计、配置及注意点
JHOK-ZBL1漏电继电器
No experts! Growth secrets for junior and intermediate programmers and "quasi programmers" who are still practicing in Universities
Record a pressure measurement experience summary
数字化如何影响工作流程自动化
带你遨游银河系的 10 种分布式数据库
window定时计划任务
Safe landing practice of software supply chain under salesforce containerized ISV scenario
高压漏电继电器BLD-20
随机推荐
利用OPNET进行网络指定源组播(SSM)仿真的设计、配置及注意点
Longest non descent subsequence (LIS) (dynamic programming)
Leetcode (46) - Full Permutation
Salesforce 容器化 ISV 场景下的软件供应链安全落地实践
Dynamically generate tables
【PHP SPL笔记】
Auto. JS get all app names of mobile phones
Complete code of C language neural network and its meaning
The sooner you understand the four rules of life, the more blessed you will be
Knapsack problem (01 knapsack, complete knapsack, dynamic programming)
与利润无关的背包问题(深度优先搜索)
Timer创建定时器
How can project managers counter attack with NPDP certificates? Look here
Talk about mvcc multi version concurrency controller?
Addressable pre Download
模拟线程通信
Creation and use of thread pool
QSlider of QT control style series (I)
《五》表格
batch size设置技巧