美文网首页
Swift3.0-利用Photos框架自定义照片选择器

Swift3.0-利用Photos框架自定义照片选择器

作者: Supremodeamor | 来源:发表于2017-06-02 14:02 被阅读0次

    授人以鱼不如授人以渔,今天就谈谈如何利用Photos框架自定义照片选择器。

    目录

    代码:

    AlbumManager.swift
    //
    //  CustomAlbum.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/3.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    //  AlbumManager.shared 提供请求相册、请求图片、创建相册、保存相片等操作。
    //
    
    
    import Foundation
    import UIKit
    import Photos
    
    
    /// 需要的图片尺寸:缩略图或原图
    ///
    /// - Thumbnail: 缩略图
    /// - Origin: 原图
    /// - All: 原图和缩略图
    enum ImageSizeType {
        case Thumbnail
        case Origin
        case All
    }
    
    
    class AlbumManager: NSObject, PHPhotoLibraryChangeObserver {
        
        static let shared = AlbumManager()
        var albumType: PHAssetCollectionType = .smartAlbum
        var albumSubType: PHAssetCollectionSubtype = .albumRegular
        
        fileprivate let imageManager = PHCachingImageManager()
        
        fileprivate var thumbnailSize: CGSize = CGSize(width: (screenWidth-spacing*5)/4, height: (screenWidth-spacing*5)/4)
        
        private override init() {}
        
        
        // 创建相册
        func createAlbum(albumName: String, completionHandler: @escaping (_ success: Bool, _ error: Error?) -> ()) {
            PHPhotoLibrary.shared().performChanges({
                PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: albumName)
            }, completionHandler: { success, error in
                completionHandler(success, error)
            })
        }
      
        
        /// 保存图片到相册
        ///
        /// - Parameters:
        ///   - image: 需要保存的图片
        ///   - album: 指定相册
        /// - Returns: 保存是否成功
        func addAsset(image: UIImage, to album: PHAssetCollection) -> Bool {
            
            var isSuccess = false
            PHPhotoLibrary.shared().performChanges({
                // 为image 创建asset
                let creationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
                // 请求编辑相册
                guard let addAssetRequest = PHAssetCollectionChangeRequest(for: album)
                    else { return }
                // 创建一个占位符然后将图片asset添加进去
                addAssetRequest.addAssets([creationRequest.placeholderForCreatedAsset!] as NSArray)
            }, completionHandler: { success, error in
                if !success { NSLog("error:添加asset失败 \(error.debugDescription)") }
                isSuccess = success
            })
            return isSuccess
        }
    
    /***************************************************************************/
        // MARK: Public Methods
        
        /// 获取所有相册model
        ///
        /// - Returns: [AlbumModel]
        func fetchAlbumModels() -> [AlbumModel] {
            
            var models = [AlbumModel]()
            
            // 智能相册
            let collections = fetchCollection(type: albumType, subType: albumSubType)
            collections.enumerateObjects({ (collection, index, stop) in
                // 过滤掉删除/视频的相册
                if  collection.localizedTitle?.range(of: "Deleted") != nil || collection.localizedTitle?.range(of: "Videos") != nil { return }
                // 过滤掉没有照片的相册
                let assetResult = PHAsset.fetchAssets(in: collection, options: nil)
                if assetResult.count == 0 { return }
                
                let model = AlbumModel(collection: collection)
                models.append(model)
            })
            //获取用户创建的相册
            let userCollections = PHAssetCollection.fetchTopLevelUserCollections(with: nil)
            userCollections.enumerateObjects({ (collection, index, stop) in
                guard let collection:PHAssetCollection = collection as? PHAssetCollection  else {
                    return
                }
                let assetResult = PHAsset.fetchAssets(in: collection, options: nil)
                if assetResult.count == 0 { return }
                
                let model = AlbumModel(collection: collection)
                models.append(model)
            })
            return models
        }
        
        /// 从某一相册获取model
        ///
        /// - Parameter result:PHFetchResult<PHAsset>
        /// - Returns:[PhotoModel]
        func fetchPhotoModels(result: PHFetchResult<PHAsset>) -> [PhotoModel] {
            var models = [PhotoModel]()
            result.enumerateObjects({ (asset, index, stop) in
                let model = PhotoModel(asset: asset)
                models.append(model)
            })
            return models
        }
        /// 从PHAssetCollection获取 PHFetchResult<PHAsset>
        ///
        /// - Parameter assetCollection: PHAssetCollection
        /// - Returns: PHFetchResult<PHAsset>
        func fetchResult(in assetCollection: PHAssetCollection) -> PHFetchResult<PHAsset> {
            let allPhotosOptions = PHFetchOptions()
            allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
            //这里只检索照片
            allPhotosOptions.predicate = NSPredicate.init(format: "mediaType in %@", [PHAssetMediaType.image.rawValue])
            return PHAsset.fetchAssets(in: assetCollection, options: allPhotosOptions)
        }
        // 获取所有照片
        func fetchAllPhotosResult() -> PHFetchResult<PHAsset> {
            let allPhotosOptions = PHFetchOptions()
            allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
            
            //这里只检索照片
            allPhotosOptions.predicate = NSPredicate.init(format: "mediaType in %@", [PHAssetMediaType.image.rawValue, PHAssetMediaType.video.rawValue])
            return PHAsset.fetchAssets(with: allPhotosOptions)
        }
    
        /// 获取相册
        ///
        /// - Parameters:
        ///   - type: PHAssetCollectionType
        ///   - subType: PHAssetCollectionSubtype
        /// - Returns: PHFetchResult<PHAssetCollection>
        func fetchCollection(type: PHAssetCollectionType, subType: PHAssetCollectionSubtype) -> PHFetchResult<PHAssetCollection> {
            let options = PHFetchOptions()
           
            return PHAssetCollection.fetchAssetCollections(with: type, subtype: subType, options: options)
        }
        
        func fetchCollection(name: String) -> PHAssetCollection? {
            let collections = fetchCollection(type: albumType, subType: albumSubType)
            var result: PHAssetCollection?
            
            collections.enumerateObjects({ (collection, index, stop) in
                if collection.localizedTitle == name {
                    result = collection
                }
            })
        
            return result
        }
    
        
        /// 从PHAsset中获取data
        ///
        /// - Parameters:
        ///   - asset: 目标PHAsset
        ///   - options: 定制options
        /// - Returns: Data?
        func fetchPhotoData(in asset: PHAsset, options: PHImageRequestOptions?) -> Data? {
            var resultData: Data?
            
            imageManager.requestImageData(for: asset, options: options) { (data, string, orientation, info) in
                resultData = data
            }
           
            return resultData
        }
        
        
        /// 默认配置的options
        ///
        /// - Returns: PHImageRequestOptions
        func defaultOptions() -> PHImageRequestOptions {
            let imageRequestOption = PHImageRequestOptions()
            imageRequestOption.isSynchronous = false
            imageRequestOption.isNetworkAccessAllowed = true
            imageRequestOption.deliveryMode = .opportunistic
            
            return imageRequestOption
        }
        
    /***************************************************************************/
        
        
        // MARK: PHPhotoLibraryChangeObserver
        func photoLibraryDidChange(_ changeInstance: PHChange) {
           
            DispatchQueue.main.sync {
                
            }
        }
    }
    
    Common.swift
    //
    //  Common.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/5.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import Foundation
    import UIKit
    
    /// 自定义打印方法
    ///
    /// - Parameters:
    ///   - message: 需要打印的信息
    ///   - file: 当前文件名
    ///   - method: 当前方法名
    ///   - line: 当前行
    func printLog<T>(message: T,
                  file: String = #file,
                  method: String = #function,
                  line: Int = #line)
    {
        #if DEBUG
            print("\((file as NSString).lastPathComponent)[\(line)], \(method): \(message)")
        #endif
    }
    
    let screenWidth: CGFloat = UIScreen.main.bounds.width
    let screenHeight: CGFloat = UIScreen.main.bounds.height
    let screenScale: CGFloat = UIScreen.main.scale
    
    let defaultBackColor = UIColor.colorFromString("#f0f8ff")
    
    
    func fontRoundedBold(size: CGFloat) -> UIFont {
        return UIFont(name: "Arial Rounded MT Bold", size: size)!
    }
    func fontMarkerFelt(size: CGFloat) -> UIFont {
        return UIFont(name: "Marker Felt", size: size)!
    }
    
    func fontSystem(size: CGFloat) -> UIFont {
        return UIFont.systemFont(ofSize: size)
    }
    
    // 将时间转成 00:00:00 格式字符串
    func stringFromTimeInterval(interval: TimeInterval) -> String {
        let interval = Int(interval)
        let seconds = interval % 60
        let minutes = (interval / 60) % 60
        let hours = (interval / 3600)
        return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
    }
    
    AlbumModel
    //
    //  AlbumModel.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/9.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import Foundation
    import UIKit
    import Photos
    
    
    struct AlbumModel {
        var albumName: String! = ""                   //相册名称
        var result: [PhotoModel]!                     //资源集合
        var lastPhotoAsset: PHAsset?
        var photoesCount: Int {                       //资源数量
            get {
                return result.count
            }
        }
        
        init(collection: PHAssetCollection) {
            albumName = collection.localizedTitle
            let assetResult = AlbumManager.shared.fetchResult(in: collection)
            result = AlbumManager.shared.fetchPhotoModels(result: assetResult)
            // 判断相册中是否有资源
            if result.isEmpty { return }
            // 判断资源是否可以转成图片
            lastPhotoAsset = result[result.count-1].asset
    
        }
    }
    
    PhotoModel
    //
    //  AlbumImageModel.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/8.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import Foundation
    import UIKit
    import Photos
    
    struct PhotoModel {
        var iselected: Bool = false
        var canSelect: Bool = true
        var asset: PHAsset
        
        init(asset: PHAsset) {
            self.asset = asset
        }
        
    }
    
    AlbumListViewController.swift
    //
    //  AlbumListViewController.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/9.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    
    private let cellIdentifier: String = String(describing: AlbumListCell.self)
    
    class AlbumListViewController: UITableViewController {
    
        var albumList = [AlbumModel]()
        
        var maxSelectCount: Int = 10
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            customUI()
        }
    
        private func customUI() {
            self.title = "照片"
            self.view.backgroundColor = defaultBackColor
            self.tableView.register(AlbumListCell.self, forCellReuseIdentifier: cellIdentifier)
            self.tableView.tableFooterView = UIView()
            
            let rightBtn: UIButton = UIButton(type: .custom)
            rightBtn.addTarget(self, action: #selector(rightAction(btn:)), for: UIControlEvents.touchUpInside)
            rightBtn.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
            rightBtn.setTitle("取消", for: UIControlState.normal)
            rightBtn.setTitleColor(UIColor.colorFromString("#1E90FF"), for: .normal)
            rightBtn.titleLabel?.font = fontSystem(size: 16)
            let right: UIBarButtonItem = UIBarButtonItem(customView: rightBtn)
            self.navigationItem.rightBarButtonItem = right
        }
        
        func rightAction(btn: UIButton) {
            let navi: AlbumViewController = self.navigationController as! AlbumViewController
            navi.albumDelegate?.didCancelSelect?()
            
            self.dismiss(animated: true, completion: nil)
        
        }
        deinit {
            printLog(message: "AlbumListController deinit")
        }
        
        // MARK: - Table view data source
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
            return albumList.count
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell: AlbumListCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! AlbumListCell
            
            let model: AlbumModel = albumList[indexPath.row]
            
            cell.loadData(model: model)
            return cell
        }
        override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            return cellWidth + 2 * spacing
        }
        
        // MARK: Delegate
        
        override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            let model = albumList[indexPath.row]
            let photoListVC: PhotoListViewController = PhotoListViewController()
            photoListVC.models = model.result
            photoListVC.title = model.albumName
            photoListVC.maxSelectCount = self.maxSelectCount
            self.navigationController?.pushViewController(photoListVC, animated: true)
        }
    
    }
    
    AlbumViewController.swift
    //
    //  AlbumViewController.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/9.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    //  Album入口VC,初始化时由CollectionType选择进入相册列表还是直接查看所有照片。
    //  AlbumViewControllerDelegate协议的`didSelect`方法获取所有选中的照片资源。
    
    import UIKit
    import Photos
    enum CollectionType {
        case albumList
        case photoList
    }
    
    
    @objc protocol AlbumViewControllerDelegate: NSObjectProtocol {
        func didSelect(photoAssets: [PHAsset])
        
        @objc optional func didCancelSelect()
    }
    
    
    class AlbumViewController: UINavigationController {
        
        weak var albumDelegate: AlbumViewControllerDelegate?
        
        convenience init(type collectionType: CollectionType, maxSelectCount: Int = 10){
            var vc: UIViewController
            switch collectionType {
            case .albumList:
                let albumVC = AlbumListViewController()
                albumVC.albumList = AlbumManager.shared.fetchAlbumModels()
                albumVC.maxSelectCount = maxSelectCount
                vc = albumVC
                break
            default:
                let photoVC = PhotoListViewController()
                let allPhotoResult = AlbumManager.shared.fetchAllPhotosResult()
                photoVC.models = AlbumManager.shared.fetchPhotoModels(result: allPhotoResult)
                photoVC.maxSelectCount = maxSelectCount
                vc = photoVC
                break
            }
            self.init(rootViewController: vc)
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            self.navigationBar.barTintColor = UIColor.colorFromString("#E6E9ED")
            self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.colorFromString("#434a54")]
            
        }
    
        
        
        
        
        
        
      
    
    }
    
    PhotoListViewController.swift
    //
    //  ShowPhotosViewController.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/4.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    import Photos
    import PhotosUI
    
    let spacing: CGFloat = 3
    let cellWidth = (screenWidth - spacing * 5) / 4
    
    
    class PhotoListViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
        // 选中照片集合
        var selectedAssets: Array<PHAsset> = Array() {
            didSet {
                selectedCountDidChange()
            }
        }
        // 选中数量
        var selectedCount: Int {
            get {
                return selectedAssets.count
            }
        }
        var maxSelectCount: Int = 10 //最大选择数量,默认10张
        
        var models = [PhotoModel]()
        
        fileprivate let imageManager = PHCachingImageManager()
        fileprivate var thumbnailSize: CGSize! = CGSize(width: cellWidth * UIScreen.main.scale, height: cellWidth * UIScreen.main.scale)
        fileprivate var previousPreheatRect = CGRect.zero
        fileprivate let editBtn = UIButton(type: .system)
        fileprivate let previewBtn = UIButton(type: .system)
        fileprivate let sendBtn = UIButton(type: .system)
        fileprivate let countLabel = UILabel()
        
        lazy var collectionView: UICollectionView  = {
            let flowLayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize(width: cellWidth , height: cellWidth)
            flowLayout.sectionInset = UIEdgeInsetsMake(spacing, spacing, spacing, spacing)
            flowLayout.minimumInteritemSpacing = spacing;
            flowLayout.minimumLineSpacing = spacing;
            let rect: CGRect = CGRect(x: 0, y: 64, width: screenWidth, height: screenHeight - 64 - 49)
            let collectionView = UICollectionView(frame: rect, collectionViewLayout: flowLayout)
            collectionView.backgroundColor = defaultBackColor
            collectionView.delegate = self
            collectionView.dataSource = self
            
            collectionView.register(PhotoListCell.self, forCellWithReuseIdentifier: String(describing: PhotoListCell.self))
            return collectionView
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            customUI()
            resetCachedAssets()
        }
        
        fileprivate func customUI() {
            view.addSubview(collectionView)
            self.automaticallyAdjustsScrollViewInsets = false
            self.navigationController?.toolbar.isHidden = false
            view.backgroundColor = defaultBackColor
            
            let tool: UIView = UIView(frame: CGRect(x: 0, y: screenHeight - 49, width: screenWidth, height: 49))
            tool.backgroundColor = UIColor.colorFromString("#e6e9ed")
            let line: CAShapeLayer = CAShapeLayer()
            line.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 0.5)
            line.backgroundColor = UIColor.colorFromString("#656d78").cgColor
            tool.layer.addSublayer(line)
    
            view.addSubview(tool)
            
            let normalColor = UIColor.colorFromString("#4a89dc")
            let disableColor = UIColor.colorFromString("#aab2bd")
            // 编辑按钮
            editBtn.frame = CGRect(x: 8, y: 4, width: 40, height: 40)
            editBtn.setTitle("edit", for: UIControlState.normal)
            editBtn.setTitleColor(normalColor, for: UIControlState.normal)
            editBtn.setTitleColor(disableColor, for: UIControlState.disabled)
            editBtn.titleLabel?.font = fontMarkerFelt(size: 16)
            editBtn.addTarget(self, action: #selector(editAction), for: UIControlEvents.touchUpInside)
            editBtn.isEnabled = false
            tool.addSubview(editBtn)
            
            // 预览按钮
            previewBtn.frame = CGRect(x: 60, y: 4, width: 60, height: 40)
            previewBtn.setTitle("preview", for: UIControlState.normal)
            previewBtn.setTitleColor(normalColor, for: UIControlState.normal)
            previewBtn.setTitleColor(disableColor, for: UIControlState.disabled)
            previewBtn.titleLabel?.font = fontMarkerFelt(size: 16)
            previewBtn.addTarget(self, action: #selector(previewAction), for: UIControlEvents.touchUpInside)
            previewBtn.isEnabled = false
            tool.addSubview(previewBtn)
            
            // 使用按钮
            sendBtn.frame = CGRect(x: screenWidth - 50, y: 4, width: 40, height: 40)
            sendBtn.setTitle("select", for: UIControlState.normal)
            sendBtn.setTitleColor(normalColor, for: UIControlState.normal)
            sendBtn.setTitleColor(disableColor, for: UIControlState.disabled)
            sendBtn.titleLabel?.font = fontMarkerFelt(size: 16)
            sendBtn.addTarget(self, action: #selector(sendAction), for: UIControlEvents.touchUpInside)
            sendBtn.isEnabled = false
            tool.addSubview(sendBtn)
            
            // 数量标签:
            countLabel.frame = CGRect(x: 0, y: 4, width: 40, height: 40)
            countLabel.center = CGPoint(x: tool.center.x, y: countLabel.center.y)
            countLabel.font = fontMarkerFelt(size: 18)
            countLabel.textColor = UIColor.colorFromString("#434a5d")
            countLabel.textAlignment = .center
            countLabel.text = "(\(selectedCount))"
            tool.addSubview(countLabel)
            
            
            let rightBtn: UIButton = UIButton(type: .custom)
            rightBtn.addTarget(self, action: #selector(rightAction(btn:)), for: UIControlEvents.touchUpInside)
            rightBtn.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
            rightBtn.setTitle("取消", for: UIControlState.normal)
            rightBtn.setTitleColor(UIColor.colorFromString("#1E90FF"), for: .normal)
            rightBtn.titleLabel?.font = fontSystem(size: 16)
            let right: UIBarButtonItem = UIBarButtonItem(customView: rightBtn)
            self.navigationItem.rightBarButtonItem = right
            
            
    //        let lastIndexpath = IndexPath(item: models.count - 1 , section: 0)
    //        collectionView.scrollToItem(at: lastIndexpath, at: UICollectionViewScrollPosition.bottom, animated: false)
        }
        
        
        func rightAction(btn: UIButton) {
            
            let navi: AlbumViewController = self.navigationController as! AlbumViewController
            navi.albumDelegate?.didCancelSelect?()
            
            self.dismiss(animated: true, completion: nil)
        }
        
        deinit {
          
            printLog(message: "PhotoListViewController deinit")
        }
        
        // MARK: Button Actions
        func previewAction() {
            printLog(message: "预览")
        }
        func editAction() {
            printLog(message: "编辑")
        }
        func sendAction() {
            printLog(message: "使用")
            if selectedCount == 0 {
                let alertView = UIAlertView(title: "提示", message: "您没有选中任何照片", delegate: self, cancelButtonTitle: "确定")
                alertView.show()
            } else {
                let navi: AlbumViewController = self.navigationController as! AlbumViewController
                if navi.albumDelegate != nil {
                    navi.albumDelegate?.didSelect(photoAssets: selectedAssets)
                }
            }
            
            self.dismiss(animated: true, completion: nil)
        }
        
        // MARK: 选中照片数改变的监听
        func selectedCountDidChange() {
            
            countLabel.text = "(\(selectedCount))"
            
            if selectedCount > 0 {
                previewBtn.isEnabled = true
                editBtn.isEnabled = true
                sendBtn.isEnabled = true
                
            } else {
                previewBtn.isEnabled = false
                editBtn.isEnabled = false
                sendBtn.isEnabled = false
            }
            
            // 选择数量>=最大选择数时,需要更新models的可选状态,非选中的model,其可选状态设为false。选择数量<最大选择数时,将models可选状态都重新设为可选
        
            if selectedCount < maxSelectCount {
                for i in 0 ..< models.count {
                    var model = models[i]
                    if model.canSelect == false {
                        model.canSelect = true
                        models[i] = model
                    }
                }
                
            } else {
    
                for i in 0 ..< models.count {
                    var model = models[i]
                    if model.iselected == false {
                        model.canSelect = false
                        models[i] = model
                    }
                }
            }
            let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
            let indexPathes = collectionView.indexPathsForElements(in: visibleRect)
            collectionView.reloadItems(at: indexPathes)
            
        }
        
        // MARK:UICollectionView DataSource
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return models.count
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            
            guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: PhotoListCell.self), for: indexPath) as? PhotoListCell
                else { fatalError("unexpected cell in collection view") }
            
            
            let model = models[indexPath.row]
            let asset = model.asset
            
            // 添加Live Photo标识
            if #available(iOS 9.1, *) {
                if asset.mediaSubtypes.contains(.photoLive) {
                    cell.livePhotoBadgeImageView.image = PHLivePhotoView.livePhotoBadgeImage(options: .overContent)
                    cell.contentView.addSubview(cell.livePhotoBadgeImageView)
                } else {
                    cell.livePhotoBadgeImageView.image = nil
                    cell.livePhotoBadgeImageView.removeFromSuperview()
                }
            }
            
            cell.loadData(model:self.models[indexPath.row])
            
            cell.selectPhotoDelegate = self
            
            return cell
        }
        
        // MARK: delegate
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            let cell = collectionView.cellForItem(at: indexPath) as! PhotoListCell
            
            if selectedCount == maxSelectCount && cell.selecedImage == false  {
                let alertView = UIAlertView(title: "不能再多选了,这么多够了!", message: "最多只能选择\(maxSelectCount)张照片", delegate: self, cancelButtonTitle: "确定")
                alertView.show()
                return
            }
            
            let preview: PreviewController = PreviewController()
            preview.currentIndexPath = indexPath
            preview.maxSelectCount = maxSelectCount
            preview.photos = models
            preview.selectedAssets = selectedAssets
            preview.previewDelegate = self
            self.navigationController?.pushViewController(preview, animated: true)
        }
        
        // MARK: UIScrollView
        
        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            updateCachedAssets()
        }
        
        // MARK: Asset Caching
        
        fileprivate func resetCachedAssets() {
            imageManager.stopCachingImagesForAllAssets()
            previousPreheatRect = .zero
        }
      //
        fileprivate func updateCachedAssets() {
            // 只更新可见区域内的视图
            guard isViewLoaded && view.window != nil else { return }
            
            // 预见区高度为可见区高度的2倍
            let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
            let preheatRect = visibleRect.insetBy(dx: 0, dy: -0.5 * visibleRect.height)
            
            // 可见区与最后的预见区有明显差异再更新(减少更新频率)
            let delta = abs(preheatRect.midY - previousPreheatRect.midY)
            guard delta > view.bounds.height / 3 else { return }
            
            // 计算缓存起点和终点
            let (addedRects, removedRects) = differencesBetweenRects(previousPreheatRect, preheatRect)
            let addedAssets = addedRects
                .flatMap { rect in collectionView.indexPathsForElements(in: rect) }
                .map { indexPath in models[indexPath.row].asset }
            let removedAssets = removedRects
                .flatMap { rect in collectionView.indexPathsForElements(in: rect) }
                .map { indexPath in models[indexPath.row].asset }
            
            // 更新PHCachingImageManager正在缓存的assets.
            imageManager.startCachingImages(for: addedAssets,
                                            targetSize: thumbnailSize, contentMode: .aspectFill, options: nil)
            imageManager.stopCachingImages(for: removedAssets,
                                           targetSize: thumbnailSize, contentMode: .aspectFill, options: nil)
            
            // 存储最后的预见区
            previousPreheatRect = preheatRect
        }
        
        fileprivate func differencesBetweenRects(_ old: CGRect, _ new: CGRect) -> (added: [CGRect], removed: [CGRect]) {
            if old.intersects(new) {
                var added = [CGRect]()
                if new.maxY > old.maxY {
                    added += [CGRect(x: new.origin.x, y: old.maxY,
                                     width: new.width, height: new.maxY - old.maxY)]
                }
                if old.minY > new.minY {
                    added += [CGRect(x: new.origin.x, y: new.minY,
                                     width: new.width, height: old.minY - new.minY)]
                }
                var removed = [CGRect]()
                if new.maxY < old.maxY {
                    removed += [CGRect(x: new.origin.x, y: new.maxY,
                                       width: new.width, height: old.maxY - new.maxY)]
                }
                if old.minY < new.minY {
                    removed += [CGRect(x: new.origin.x, y: old.minY,
                                       width: new.width, height: new.minY - old.minY)]
                }
                return (added, removed)
            } else {
                return ([new], [old])
            }
        }
        
        private func drawColorImage()-> UIImage {
            // 创建随机颜色和方向的图片
            let size = (arc4random_uniform(2) == 0) ?
                CGSize(width: 400, height: 300) :
                CGSize(width: 300, height: 400)
            var image: UIImage?
            if #available(iOS 10.0, *) {
                let renderer = UIGraphicsImageRenderer(size: size)
                image = renderer.image { context in
                    UIColor(hue: CGFloat(arc4random_uniform(100))/100,
                            saturation: 1, brightness: 1, alpha: 1).setFill()
                    context.fill(context.format.bounds)
                }
            } else {
            //开启图片上下文
            UIGraphicsBeginImageContext(size)
            //从当前上下文获取图片
            image = UIGraphicsGetImageFromCurrentImageContext()
            //关闭上下文
            UIGraphicsEndImageContext()
          
            }
              return image!
        }
    }
    
    
    private extension UICollectionView {
        // 获取区域内所有IndexPath
        func indexPathsForElements(in rect: CGRect) -> [IndexPath] {
            let allLayoutAttributes = collectionViewLayout.layoutAttributesForElements(in: rect)!
            return allLayoutAttributes.map { $0.indexPath }
        }
    }
    
    
    // MARK: SelectPhotoProtocol
    extension PhotoListViewController: SelectPhotoProtocol {
        func selectPhoto(cell: PhotoListCell) {
            let indexPath = collectionView.indexPath(for: cell)!
            var model = models[indexPath.row]
            cell.selecedImage = !cell.selecedImage
            model.iselected = cell.selecedImage
            models[indexPath.row] = model
            if model.iselected == true {
                selectedAssets.append(model.asset)
            } else {
                for i in 0 ..< selectedAssets.count {
                    let asset = selectedAssets[i]
                    if asset.localIdentifier == model.asset.localIdentifier {
                        selectedAssets.remove(at: i)
                        return
                    }
                }
            }
        }
    }
    
    
    extension PhotoListViewController: PreviewProtocol {
        
        func previewChangeSelection(indexPath: IndexPath) {
            
            let cell: PhotoListCell? = collectionView.cellForItem(at: indexPath) as? PhotoListCell
            if cell == nil {
                collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.bottom, animated: false)
            }
            var model = models[indexPath.row]
            model.iselected = !model.iselected
            models[indexPath.row] = model
            if model.iselected == true {
                selectedAssets.append(model.asset)
            } else {
                for i in 0 ..< selectedAssets.count {
                    let asset = selectedAssets[i]
                    if asset.localIdentifier == model.asset.localIdentifier {
                        selectedAssets.remove(at: i)
                        return
                    }
                }
            }
    
        }
    }
    
    
    PreviewController.swift
    //
    //  PreviewController.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/15.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    import Photos
    
    @objc protocol PreviewProtocol {
        @objc optional func previewChangeSelection(indexPath: IndexPath)
    }
    
    private let cellIdentifier: String = String(describing: PreviewCell.self)
    
    private let cellMargin: CGFloat = 15.0
    
    class PreviewController: UICollectionViewController {
        var currentIndexPath: IndexPath?
        var photos: [PhotoModel]?
        var selectBtn: UIButton!
        var maxSelectCount: Int = 10
        
        weak var previewDelegate: PreviewProtocol?
        
        // 选中照片集合
        var selectedAssets: Array<PHAsset> = Array() {
            willSet {
                sendBtn.isEnabled = newValue.count > 0 ? true : false
                countLabel.text = "(\(newValue.count))"
            }
        }
        // 选中数量
        var selectedCount: Int {
            get {
                return selectedAssets.count
            }
        }
        
        fileprivate let editBtn = UIButton(type: .system)
        fileprivate let sendBtn = UIButton(type: .system)
        fileprivate let countLabel = UILabel()
        override init(collectionViewLayout layout: UICollectionViewLayout) {
            super.init(collectionViewLayout: layout)
        }
        
        convenience init() {
            let layout = UICollectionViewFlowLayout()
            layout.itemSize = CGSize(width: screenWidth, height: screenHeight - 64)
            layout.minimumLineSpacing = 15.0
            layout.minimumInteritemSpacing = 0
            layout.scrollDirection = .horizontal
            self.init(collectionViewLayout: layout)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        deinit {
            printLog(message: "preview deinit")
        }
        override func viewDidLoad() {
            super.viewDidLoad()
            
            customUI()
            
        }
        
        func customUI() {
            self.automaticallyAdjustsScrollViewInsets = false
            
            // 右上角选择按钮
            selectBtn = UIButton(type: .custom)
            selectBtn.frame = CGRect(x: 0, y: 0, width: 22, height: 22)
            
            let btnImage = UIImage(named: photos![currentIndexPath!.row].iselected ? "selected1" : "select")
            selectBtn.setImage(btnImage, for: .normal)
            selectBtn.addTarget(self, action: #selector(selectImage(btn:)), for: .touchUpInside)
            let rightBarItem: UIBarButtonItem = UIBarButtonItem(customView: selectBtn)
            self.navigationItem.rightBarButtonItem = rightBarItem
            
            // collectionview的设置
            self.collectionView!.register(PreviewCell.self, forCellWithReuseIdentifier: cellIdentifier)
            collectionView?.frame = CGRect(x: 0, y: 64, width: screenWidth + cellMargin, height: screenHeight - 64)
            self.collectionView?.isPagingEnabled = true
            guard currentIndexPath != nil else {
                return
            }
            // 设置显示时的位置(默认是从[0,0]开始的)
            self.collectionView?.scrollToItem(at: currentIndexPath! , at: .left, animated: false)
            
            let tool: UIView = UIView(frame: CGRect(x: 0, y: screenHeight - 49, width: screenWidth, height: 49))
            tool.backgroundColor = UIColor.colorFromString("#040b27", alpha: 0.4)
            let line: CAShapeLayer = CAShapeLayer()
            line.frame = CGRect(x: 0, y: 0, width: screenWidth, height: 0.5)
            line.backgroundColor = UIColor.colorFromString("#656d78").cgColor
            tool.layer.addSublayer(line)
            
            view.addSubview(tool)
            
            let normalColor = UIColor.colorFromString("#ffffff")
            let disableColor = UIColor.colorFromString("#4a485c")
            // 编辑按钮
            editBtn.frame = CGRect(x: 8, y: 4, width: 40, height: 40)
            editBtn.setTitle("edit", for: UIControlState.normal)
            editBtn.setTitleColor(normalColor, for: UIControlState.normal)
            editBtn.setTitleColor(disableColor, for: UIControlState.disabled)
            editBtn.titleLabel?.font = fontMarkerFelt(size: 16)
            editBtn.addTarget(self, action: #selector(editAction), for: UIControlEvents.touchUpInside)
            tool.addSubview(editBtn)
            
            // 使用按钮
            sendBtn.frame = CGRect(x: screenWidth - 50, y: 4, width: 40, height: 40)
            sendBtn.setTitle("select", for: UIControlState.normal)
            sendBtn.setTitleColor(normalColor, for: UIControlState.normal)
            sendBtn.setTitleColor(disableColor, for: UIControlState.disabled)
            sendBtn.titleLabel?.font = fontMarkerFelt(size: 16)
            sendBtn.addTarget(self, action: #selector(sendAction), for: UIControlEvents.touchUpInside)
            tool.addSubview(sendBtn)
            
            // 数量标签:
            countLabel.frame = CGRect(x: 0, y: 4, width: 40, height: 40)
            countLabel.center = CGPoint(x: tool.center.x, y: countLabel.center.y)
            countLabel.font = fontMarkerFelt(size: 18)
            countLabel.textColor = UIColor.colorFromString("#fffdf8")
            countLabel.textAlignment = .center
            countLabel.text = "(\(selectedCount))"
            tool.addSubview(countLabel)
    
        }
        
        // 选取图片action
        func selectImage(btn: UIButton) {
            guard previewDelegate != nil && previewDelegate!.previewChangeSelection?(indexPath: currentIndexPath!) != nil else {
                return
            }
            
            var currentModel: PhotoModel = photos![currentIndexPath!.row]
            if selectedCount == maxSelectCount && currentModel.iselected == false {
                let alertView = UIAlertView(title: "不能再多选了,这么多够了!", message: "最多只能选择\(maxSelectCount)张照片", delegate: self, cancelButtonTitle: "确定")
                alertView.show()
                return
            }
            
            currentModel.iselected = !currentModel.iselected
            photos![currentIndexPath!.row] = currentModel
            
            if currentModel.iselected == true {
                btn.setImage(UIImage(named: "selected1"), for: .normal)
                selectedAssets.append(currentModel.asset)
            } else {
                btn.setImage(UIImage(named: "select"), for: .normal)
                
                for i in 0 ..< selectedAssets.count {
                    if selectedAssets[i].localIdentifier == currentModel.asset.localIdentifier {
                        selectedAssets.remove(at: i)
                        return
                    }
                }
            }
            
        }
        
        func editAction() {
            printLog(message: "编辑")
        }
        func sendAction() {
    
            if selectedCount == 0 {
                let alertView = UIAlertView(title: "提示", message: "您没有选中任何照片", delegate: self, cancelButtonTitle: "确定")
                alertView.show()
            } else {
                let navi: AlbumViewController = self.navigationController as! AlbumViewController
                if navi.albumDelegate != nil {
                    navi.albumDelegate?.didSelect(photoAssets: selectedAssets)
                }
            }
            
            self.dismiss(animated: true, completion: nil)
        }
        
        
        // MARK: UICollectionViewDataSource
        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            
            return photos?.count ?? 0
        }
        
        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! PreviewCell
            
            guard  let model:PhotoModel = photos?[indexPath.item] else {
                cell.filterWithImage(UIImage(named: "default.gif")!,resizeStyle: kCAGravityResizeAspect)
    
                return cell
            }
            
            cell.loadData(model: model)
        
            return cell
        }
        
        override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            
            printLog(message: "点击了\(indexPath.row)cell")
        }
        
        
        override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
            if scrollView == collectionView {
                currentIndexPath?.row = Int(ceil(collectionView!.contentOffset.x / (screenWidth + cellMargin)))
                
                let currentModel: PhotoModel = photos![currentIndexPath!.row]
                if currentModel.iselected == true {
                    selectBtn.setImage(UIImage(named: "selected1"), for: .normal)
                } else {
                    selectBtn.setImage(UIImage(named: "select"), for: .normal)
                }
                let cell: PreviewCell = collectionView?.cellForItem(at: currentIndexPath!) as! PreviewCell
                printLog(message: cell.imgView.image)
            }
        }
        
    }
    
    AlbumListCell
    //
    //  AlbumTableViewCell.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/8.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    import Photos
    
    class AlbumListCell: UITableViewCell {
        
        fileprivate let phmanager: PHCachingImageManager = PHCachingImageManager()
        fileprivate var representedAssetIdentifier: String?
        
        lazy var photoView: UIImageView = {
            let phView: UIImageView = UIImageView(frame: CGRect(x:10, y:spacing, width:cellWidth, height:cellWidth ))
            phView.contentMode = UIViewContentMode.scaleAspectFill
            phView.layer.masksToBounds = true
            return phView
        }()
        
        lazy var nameLabel: UILabel = {
            let label: UILabel = UILabel(frame: CGRect(x: cellWidth + 20, y: 20 , width: screenWidth - cellWidth - 20, height: 30))
            label.center = CGPoint(x: label.center.x, y: cellWidth / 2 )
            label.font = fontMarkerFelt(size: 20)
            label.textColor = UIColor.colorFromString("#111111")
            return label
        }()
        
        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            
            self.selectionStyle = .none
            self.separatorInset = UIEdgeInsetsMake(3, 5 + cellWidth + 10, 0, 5)
            contentView.addSubview(photoView)
            contentView.addSubview(nameLabel)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        override func awakeFromNib() {
            super.awakeFromNib()
            
        }
    
        func loadData(model: AlbumModel) {
            nameLabel.text = model.albumName + "  (\(model.photoesCount))"
            
            guard model.lastPhotoAsset != nil else {
                photoView.image = UIImage(named: "default.gif")
                return
            }
            
            representedAssetIdentifier = model.lastPhotoAsset?.localIdentifier
            weak var weakSelf = self
            phmanager.requestImage(for: model.lastPhotoAsset!, targetSize: CGSize(width: cellWidth * screenScale ,height: cellWidth * screenScale), contentMode: PHImageContentMode.aspectFill, options: nil) { (image, info) in
                guard image != nil else {
                    weakSelf!.photoView.image = UIImage(named: "default.gif")
                    return
                }
                if weakSelf?.representedAssetIdentifier == model.lastPhotoAsset?.localIdentifier {
                    weakSelf!.photoView.image = image
                }
            }
        }
        
        
        
        override func setSelected(_ selected: Bool, animated: Bool) {
            super.setSelected(selected, animated: animated)
    
        }
    
    }
    
    PhotoListCell
    //
    //  CustomCollectionViewCell.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/4.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    import Photos
    
    /// 选择照片协议
    protocol SelectPhotoProtocol: NSObjectProtocol {
        
        func selectPhoto(cell: PhotoListCell)
    }
    
    class PhotoListCell: UICollectionViewCell {
        
        weak var selectPhotoDelegate: SelectPhotoProtocol?
        
        fileprivate var representedAssetIdentifier: String?
        
        fileprivate let phmanager: PHCachingImageManager = PHCachingImageManager()
        lazy var coverView: UIView = {
            let view = UIView(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellWidth))
            view.backgroundColor = UIColor(white: 1.0, alpha: 0.4)
            return view
        }()
        
        lazy var imageView: UIImageView = {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: cellWidth , height: cellWidth))
            imageView.backgroundColor = UIColor.white
            imageView.contentMode = UIViewContentMode.scaleAspectFill
            imageView.layer.masksToBounds = true
    
            return imageView
        }()
        
        lazy var livePhotoBadgeImageView: UIImageView = {
            let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 22, height: 22))
            imageView.backgroundColor = UIColor.clear
            imageView.contentMode = UIViewContentMode.scaleAspectFill
      
            return imageView
        }()
        lazy var selectedImageView: UIImageView = {
            let imageView = UIImageView(frame: CGRect(x: cellWidth - 25 - 2, y: 2, width: 25, height: 25))
            imageView.backgroundColor = UIColor.clear
            imageView.contentMode = UIViewContentMode.scaleAspectFit
            imageView.image = UIImage(named: "select")
            
            let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapSelect(tap:)))
            imageView.addGestureRecognizer(tap)
            imageView.isUserInteractionEnabled = true
            return imageView
        }()
        
        var selecedImage: Bool  = false {
            willSet(newValue) {
                if newValue == true {
                    selectedImageView.image = UIImage(named: "selected1")
                } else {
                    selectedImageView.image = UIImage(named: "select")
                }
            }
        }
        override init(frame: CGRect) {
            super.init(frame: frame)
            contentView.backgroundColor = .white
            contentView.addSubview(imageView)
            contentView.addSubview(selectedImageView)
            
        }
        
        func loadData(model: PhotoModel) {
            selecedImage = model.iselected
            
            if model.canSelect == false {
                addCover()
            } else {
                removeCover()
            }
            representedAssetIdentifier = model.asset.localIdentifier
            weak var weakSelf = self
            phmanager.requestImage(for: model.asset, targetSize: CGSize(width: cellWidth * screenScale, height: cellWidth * screenScale), contentMode: .aspectFill, options: nil) { (image, info) in
                guard image != nil else {
                    return
                }
                if weakSelf?.representedAssetIdentifier == model.asset.localIdentifier {
                    weakSelf!.imageView.image = image
                }
            }
        
        }
        
        func tapSelect(tap: UITapGestureRecognizer)  {
            
            if selectPhotoDelegate != nil {
                selectPhotoDelegate!.selectPhoto(cell: self)
            }
        }
        
        func addCover() {
            if !contentView.subviews.contains(coverView) {
                contentView.addSubview(coverView)
            }
        }
        
        func removeCover() {
            if contentView.subviews.contains(coverView) {
                coverView.removeFromSuperview()
            }
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
       
    }
    
    
    PreviewCell
    //
    //  PreviewCell.swift
    //  PhotoLibraryDemo
    //
    //  Created by AtronJia on 2017/5/15.
    //  Copyright © 2017年 Artron. All rights reserved.
    //
    
    import UIKit
    import Photos
    class PreviewCell: UICollectionViewCell, UIScrollViewDelegate {
        fileprivate lazy var progressView: UIProgressView = {
            let progressView = UIProgressView(frame: CGRect(x:20, y: 100, width: screenWidth - 40, height: 5))
            progressView.progress = 0
            
            progressView.tintColor = UIColor.colorFromString("#040b27")
            return progressView
        }()
        
        fileprivate lazy var scroll: UIScrollView = {
            let scroll = UIScrollView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight - 64))
            scroll.backgroundColor = .black
            scroll.maximumZoomScale = 3.0
            scroll.minimumZoomScale = 1.0
            let doubleTap = UITapGestureRecognizer(target: self, action: #selector(doubleTapAction(tap:)))
            doubleTap.numberOfTapsRequired = 2
            scroll.addGestureRecognizer(doubleTap)
            return scroll
        }()
        lazy var imgView: UIImageView = {
            let imgView: UIImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight - 64 - 49))
    //        imgView.center = self.contentView.center
            imgView.backgroundColor = .black
            imgView.isUserInteractionEnabled = true
            imgView.contentMode = .scaleAspectFit
            return imgView
        }()
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            addUI()
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        // 需要交互时采用imageview添加图片
        func addUI() {
            self.contentView.addSubview(scroll)
            scroll.delegate = self
            scroll.addSubview(imgView)
        }
        
        // 加载数据
        func loadData(model: PhotoModel) {
    
            let phmanager = PHCachingImageManager.default()
            let size: CGSize = CGSize(width: screenWidth * screenScale, height: screenHeight * screenScale)
            let imageRequestOption = AlbumManager.shared.defaultOptions()
            
            imageRequestOption.progressHandler = { progress, _, stop, _  in
                
                DispatchQueue.main.sync {
                    if progress < 1{
                        self.contentView.addSubview(self.progressView)
                        self.progressView.center =  self.contentView.center
                        self.progressView.progress = Float(progress)
                    } else {
                        self.progressView.removeFromSuperview()
                    }
                }
            }
    
            phmanager.requestImage(for: model.asset, targetSize: size, contentMode: .aspectFill, options: imageRequestOption) { (image, info) in
                guard image != nil else {
                    return
                }
               self.imgView.image = image
            }
        }
        
    //    // 加载原图
    //    func loadOriginalData(model: PhotoModel) {
    //        
    //        let phmanager = PHCachingImageManager.default()
    //        let scale = 5
    //        phmanager.requestImage(for: model.asset, targetSize: CGSize(width: model.asset.pixelWidth/scale, height: model.asset.pixelHeight/scale), contentMode: .aspectFill, options: nil) { (image, info) in
    //            guard image != nil else {
    //                return
    //            }
    //            self.imgView.image = image
    //        }
    //    }
    
        
        
        /**
         *  如果只是一张图片做背景,直接设置layer
         *  @parm: image:UIImage        目标图片
         *  @parm: resizeStyle:String    图片缩放方式
         */
        func filterWithImage(_ image:UIImage, resizeStyle:String) {
            //       下面方法据说耗内存太严重,没测试
            //        self.contentView.backgroundColor = UIColor(patternImage: image)
            
            self.contentView.layer.contents = image.cgImage
            self.contentView.layer.masksToBounds = true
            self.contentView.layer.contentsGravity = resizeStyle
        }
        
        func resetScale() {
            if scroll.zoomScale > 1 {
                scroll.setZoomScale(1, animated: false)
            }
        }
        //MARKL 双击事件
        func doubleTapAction(tap: UITapGestureRecognizer) {
            if scroll.zoomScale >= 1.5 {
                scroll.setZoomScale(1, animated: true)
            } else {
                let point = tap.location(in: scroll)
                scroll.zoom(to: CGRect(x:point.x - 40,y: point.y - 40, width:80, height:80), animated: true)
            }
        }
        
        // MARK: scrollViewDelegate 
        func viewForZooming(in scrollView: UIScrollView) -> UIView? {
            return imgView
        }
    }
    

    相关文章

      网友评论

          本文标题:Swift3.0-利用Photos框架自定义照片选择器

          本文链接:https://www.haomeiwen.com/subject/zzidxxtx.html