博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS/swift之获取系统所有相册和照片录像、封装相册多选
阅读量:4290 次
发布时间:2019-05-27

本文共 28574 字,大约阅读时间需要 95 分钟。

参考:

 

ios14 使用PHPicker获取相册(需要 import PhotosUI)

  • 支持多选
  • 支持搜索
  • 独立的进程
  • 内置隐私
    • 不需要直接访问用户相册
    • 不会弹出访问相册提示
    • 仅提供用户选择的照片和视频(App 无法获取其他照片)

PHPicker 是由系统提供的选择器,可以访问用户相册里的照片和视频。它内置了搜索功能,支持网格中的流体缩放,以及经常会被用到的照片多选功能。

PHPicker 运行在应用程序的进程之外,尽管它看起来像是在应用程序内部运行。它实际上是在一个独立的进程中运行,而不是在它上面呈现的宿主应用。但是该应用不能直接访问选择器,甚至不能截屏选择器内容。只有用户实际选择的内容才会传递回主机应用程序。

PHPickerViewController 依然是通过 delegate 属性来向宿主 App 返回用户选择的结果。

 PHPickerConfiguration 。 PHPickerConfiguration 有两个可选属性 selectionLimit 和 filter 。 selectionLimit 默认值为 1,表示单选。若要多选,则设置为 0; filter 指定相册显示类型,可单独设置,也可用数组形式显示多种类型。

代理方法中用户选择的结果会以 PHPickerResult 数组的形式传入,每一个 PHPickerResult 都对应一个照片、视频或者 LivePhoto 的数据。PHPickerResult 只有 itemProviderassetIdentifier 两个属性,剩下的是继承的 Equatable 和 Hashable 协议的实现。

assetIdentifier这是选中对象对应的 PHAsset 的 id,可以用这个 id 通过 PHAset 的相关 api 来进行其他操作。不过苹果在 WWDC 的介绍视频中明确强调了如果要访问 PHAsset 的额外信息,依然需要获取到相册权限后才可以执行。

通过 itemProvider 的 api,我们可以获取到最终的结果,不过这里有点小麻烦:针对照片、视频和 LivePhoto 三种媒体类型,分别要使用不同的 api 来获取;

1.获取照片,通过 NSItemProvider 的 loadObject 方法,并且指定 Class 类型为 UIImage,就可以在回调中得到 UIImage 类型的照片了。

   //获取图片

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

        picker.dismiss(animated: true, completion: nil)

        //下面只是获取了一张图片

        //获取PHPickerResult的itemProvider

        if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {

           // 通过 NSItemProvider 的 loadObject 方法,并且指定 Class 类型为 UIImage,就可以在回调中得到 UIImage 类型的照片了; [weak self]

            itemProvider.loadObject(ofClass: UIImage.self) { image, error in

                print("一张图片\(String(describing: image))")

               DispatchQueue.main.async {

                //在主线更新UI

               }

         }

      }

    }

2.获取 LivePhoto 与获取照片类似,只是需要将 UIImage 替换为 PHLivePhoto。之后你可以通过 PHLivePhotoView 来显示。或者通过 PHAssetResourceManager 获取 LivePhoto 的原始数据。

//获取LivePhoto

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

        picker.dismiss(animated: true, completion: nil)

        //下面只是获取了一张图片

        //获取PHPickerResult的itemProvider

        if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: PHLivePhoto.self) {

           // 通过 NSItemProvider 的 loadObject 方法,并且指定 Class 类型为 UIImage,就可以在回调中得到 UIImage 类型的照片了; [weak self]

            itemProvider.loadObject(ofClass: PHLivePhoto.self) { [weak self] phlivephoto, error in

                print("phlivephoto\(String(describing: phlivephoto))")

              let livephoto = PHLivePhotoView.init(frame: CGRect.init(x: 0, y: 0, width: 300, height: 300))

                livephoto.livePhoto=(phlivephoto as! PHLivePhoto)

                self?.view.addSubview(livephoto)

         }

      }

    }

3.获取视频,使用 loadFileRepresentation 方法来加载大文件(包括视频)。loadFileRepresentation 的使用方式与 UIImage 类似,但需要额外传入一个参数 forTypeIdentifier 来指定文件类型,指定为 public.movie 可以覆盖相册中的 .mov 和 .mp4 类型。与照片不同的是,这个 api 返回的是一个 URL 类型的临时文件路径,苹果在这个 API 的说明中指出:系统会把请求的文件数据复制到这个路径对应的地址,并且在回调执行完毕后删除临时文件。

       //获取视频

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {

        picker.dismiss(animated: true, completion: nil)

        //下面只是获取了一张图片

        //获取PHPickerResult的itemProvider

        if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {

            //这个 api 返回的是一个 URL 类型的临时文件路径,苹果在这个 API 的说明中指出:系统会把请求的文件数据复制到这个路径对应的地址,并且在回调执行完毕后删除临时文件。

            itemProvider.loadFileRepresentation(forTypeIdentifier: "public.movie") { url, error in

 

           }

      }

    }

 

 配置PHPicker:

@available(iOS 14, *)    func setPHPicekr(){                        var config = PHPickerConfiguration()        // 可选择的资源数量,0表示不设限制,默认为1        config.selectionLimit = 0        // 可选择的资源类型        // 只显示图片(注:images 包含 livePhotos)        config.filter = .images        // 显示 Live Photos 和视频(注:livePhotos 不包含 images)//        config.filter = .any(of: [.livePhotos, .videos])        // 如果要获取视频,最好设置该属性,避免系统对视频进行转码,默认是automatic        config.preferredAssetRepresentationMode = .current        let picker = PHPickerViewController(configuration: config)        picker.delegate = self        present(picker, animated: true, completion: nil)    }

综合:

var selectType = "image" //"video" "livephoto"    @available(iOS 14, *)    func setPHPicekr(){                        var config = PHPickerConfiguration()        // 可选择的资源数量,0表示不设限制,默认为1        config.selectionLimit = 0        // 可选择的资源类型        // 只显示图片(注:images 包含 livePhotos)        config.filter = .images        // 显示 Live Photos 和视频(注:livePhotos 不包含 images)//        config.filter = .any(of: [.livePhotos, .videos])        // 如果要获取视频,最好设置该属性,避免系统对视频进行转码,默认是automatic,会自动转码        config.preferredAssetRepresentationMode = .current        let picker = PHPickerViewController(configuration: config)        picker.delegate = self        present(picker, animated: true, completion: nil)    }    //获取图片    @available(iOS 14, *)    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {            picker.dismiss(animated: true, completion: nil)                if selectType=="image"{            //下面只是获取了一张图片            //获取PHPickerResult的itemProvider            if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {               // 通过 NSItemProvider 的 loadObject 方法,并且指定 Class 类型为 UIImage,就可以在回调中得到 UIImage 类型的照片了; [weak self]                itemProvider.loadObject(ofClass: UIImage.self) { image, error in                    print("一张图片\(String(describing: image))")                   DispatchQueue.main.async {                    //在主线更新UI                   }             }          }        }else if selectType=="live"{//视频            //获取PHPickerResult的itemProvider               if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: UIImage.self) {                   //这个 api 返回的是一个 URL 类型的临时文件路径,苹果在这个 API 的说明中指出:系统会把请求的文件数据复制到这个路径对应的地址,并且在回调执行完毕后删除临时文件。itemProvider.loadFileRepresentation(forTypeIdentifier: "public.movie") { url, error in            }          }        }else if selectType=="livephoto"{//livephoto            //获取PHPickerResult的itemProvider                    if let itemProvider = results.first?.itemProvider, itemProvider.canLoadObject(ofClass: PHLivePhoto.self) {           // 通过 NSItemProvider 的 loadObject 方法,并且指定 Class 类型为 UIImage,就可以在回调中得到 UIImage 类型的照片了; [weak self]            itemProvider.loadObject(ofClass: PHLivePhoto.self) { [weak self] phlivephoto, error in                print("phlivephoto\(String(describing: phlivephoto))")              let livephoto = PHLivePhotoView.init(frame: CGRect.init(x: 0, y: 0, width: 300, height: 300))                livephoto.livePhoto=(phlivephoto as! PHLivePhoto)//                    self?.view.addSubview(livephoto)            }          }        }    }

 

ios8-13使用Photos获取相册(需要import Photos

1。***********获取系统相册的照片和录像*********

let assetArr: [PHAsset] =  getAllAlbumAndPHAsset()//获取照片资源        //吧强求到图片资源转换成UIIMgae,在回掉方法中获取图片data数据,然后做相应的操作        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1) {            self.getImageFromPHAsset(asset: assetArr[0], size: CGSize.init(width: 100, height: 100))        }******************** //    //1.获取所有PHAsset资源的集合,包含视频和照片    func getAllPHAssetFromSysytem()->([PHAsset]){        var arr:[PHAsset] = []        let options = PHFetchOptions.init()        let assetsFetchResults:PHFetchResult = PHAsset.fetchAssets(with: options)        // 遍历,得到每一个图片资源asset,然后放到集合中        assetsFetchResults.enumerateObjects { (asset, index, stop) in            arr.append(asset)        }        print("\(arr.count)")        return arr    }           //2.先获取所有相册,然后从相机胶卷中获取PHAsset集合,(相机胶卷是相册中的一个,包含了所有视频和相册)        func getAllAlbumAndPHAsset()->([PHAsset]){               var arr:[PHAsset] = []        let options = PHFetchOptions.init()        // 所有智能相册集合(系统自动创建的相册)        let smartAlbums:PHFetchResult = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.smartAlbum, subtype: PHAssetCollectionSubtype.albumRegular, options: options)        //遍历得到每一个相册        for i in 0..
0{ //某个相册里面的所有PHAsset对象(PHAsset对象对应的是图片,需要通过方法请求到图片) assetArr = getAllPHAssetFromOneAlbum(assetCollection: assetCollection) arr.append(contentsOf: assetArr) } } } } return arr } //获取一个相册里的所有图片的PHAsset对象 func getAllPHAssetFromOneAlbum(assetCollection:PHAssetCollection)->([PHAsset]){ // 存放所有图片对象 var arr:[PHAsset] = [] // 是否按创建时间排序 let options = PHFetchOptions.init() options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]//时间排序 options.predicate = NSPredicate.init(format: "mediaType == %ld", PHAssetMediaType.image.rawValue)//˙只选照片 // 获取所有图片资源对象 let results:PHFetchResult = PHAsset.fetchAssets(in: assetCollection, options: options) // 遍历,得到每一个图片资源asset,然后放到集合中 results.enumerateObjects { (asset, index, stop) in print("\(asset)") arr.append(asset) } return arr } 根据PHAsset获取原图片信息 func getImageFromPHAsset(asset:PHAsset,size:CGSize){ var requestID:PHImageRequestID = -2 let scale:CGFloat = CGFloat(UIScreen.main.scale) let width:CGFloat = CGFloat(min(WIDTH, 500)) if (requestID >= 1 && (size.width) / width == scale) { PHCachingImageManager.default().cancelImageRequest(requestID) } let option:PHImageRequestOptions=PHImageRequestOptions.init() option.deliveryMode = PHImageRequestOptionsDeliveryMode.opportunistic option.resizeMode = PHImageRequestOptionsResizeMode.fast; requestID = PHCachingImageManager.default().requestImageData(for: asset, options: option, resultHandler: { (Dat, str, orientation, [AnyHashable : Any]?) in //Dat是图片数据 self.image = UIImage.init(data: Dat!) self.collec?.reloadData() }) //请求视频的// requestID = PHCachingImageManager.default().requestAVAsset(forVideo: PHAsset, options: PHVideoRequestOptions?, resultHandler: { (<#AVAsset?#>, AVAudioMix?, [AnyHashable : Any]?) in//// }) }

 

 

2.*************获取所有相册显示在collectionview,分页加载***************

/** 用来显示所有的相册照片 使用: let looAlbum = LYBMutipleSelectAlbumView.init(frame: CGRect.init(x: 0, y: 0, width: Int(WIDTH), height: Int(HEIGHT)-Int(bottomSafeHeight))) view.addSubview(looAlbum) } */import UIKitimport Photosclass LYBMutipleSelectAlbumView: UIView,UICollectionViewDelegate,UICollectionViewDataSource { var collec:UICollectionView?    var image:UIImage!=UIImage.init(named: "appstart")    var imageArr:[UIImage]=[]//获取到的图片数组    var assetArr: [PHAsset]=[]//获取所有照片资源    var index:Int = 0//记录显示图片的最大索引    let step:Int = 12//每次加载多少张图片            override init(frame: CGRect) {        super.init(frame: frame)         assetArr =  getAllAlbumAndPHAsset()//获取照片资源        createCollectionView()               //吧强求到图片资源转换成UIIMgae,在回掉方法中获取图片data数据,然后做相应的操作         pullUprefresh()//先刷新一下          }        required init?(coder aDecoder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }             func createCollectionView(){        let flowLayout = UICollectionViewFlowLayout.init()        flowLayout.itemSize=CGSize.init(width: WIDTH/4, height: WIDTH/4)        flowLayout.minimumLineSpacing=0        flowLayout.minimumInteritemSpacing=0         collec = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: Int(WIDTH), height: Int(HEIGHT)-Int(bottomSafeHeight)-Int(TopSpaceHigh)), collectionViewLayout: flowLayout)        collec?.backgroundColor=UIColor.white        collec?.delegate=self        collec?.dataSource=self        collec?.register(LYBMutipleSelectAlbumCollectionviewcell.classForCoder(), forCellWithReuseIdentifier: "LYBMutipleSelectAlbumCollectionviewcell")        addSubview(collec!)               initNormalAutoFooterRefresh()//上拉加载    }        //上拉加载    func initNormalAutoFooterRefresh(){        let footer =  MJRefreshAutoNormalFooter()        //上刷新相关设置        footer.setRefreshingTarget(self, refreshingAction: #selector(pullUprefresh))        //self.bottom_footer.stateLabel.isHidden = true // 隐藏文字        //是否自动加载(默认为true,即表格滑到底部就自动加载,这个我建议关掉,要不然效果会不好)        footer.isAutomaticallyRefresh = false        footer.isAutomaticallyChangeAlpha = true //自动更改透明度        //修改文字        footer.setTitle("上拉加载", for: .idle)//普通闲置的状态        footer.setTitle("正在加载中", for: .refreshing)//正在刷新的状态        footer.setTitle("加载完成", for: .noMoreData)//数据加载完毕的状态        collec?.mj_footer=footer    }        //上拉刷新    @objc func pullUprefresh(){        if(assetArr.count<=step){//所有资源小于10个,加载实际的个数            for i in 0..
index{ for i in index-step..
index-step && assetArr.count
Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return imageArr.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell:LYBMutipleSelectAlbumCollectionviewcell = collectionView.dequeueReusableCell(withReuseIdentifier: "LYBMutipleSelectAlbumCollectionviewcell", for: indexPath) as! LYBMutipleSelectAlbumCollectionviewcell cell.image = imageArr[indexPath.item] cell.backgroundColor=UIColor.red return cell } //1.获取所有PHAsset资源的集合,包含视频和照片 func getAllPHAssetFromSysytem()->([PHAsset]){ var arr:[PHAsset] = [] let options = PHFetchOptions.init() let assetsFetchResults:PHFetchResult = PHAsset.fetchAssets(with: options) // 遍历,得到每一个图片资源asset,然后放到集合中 assetsFetchResults.enumerateObjects { (asset, index, stop) in arr.append(asset) } print("\(arr.count)") return arr } //2.先获取所有相册,然后从相机胶卷中获取PHAsset集合,(相机胶卷是相册中的一个,包含了所有视频和相册) func getAllAlbumAndPHAsset()->([PHAsset]){ var arr:[PHAsset] = [] let options = PHFetchOptions.init() // 所有智能相册集合(系统自动创建的相册) let smartAlbums:PHFetchResult = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.smartAlbum, subtype: PHAssetCollectionSubtype.albumRegular, options: options) //遍历得到每一个相册 for i in 0..
0{ //某个相册里面的所有PHAsset对象(PHAsset对象对应的是图片,需要通过方法请求到图片) assetArr = getAllPHAssetFromOneAlbum(assetCollection: assetCollection) arr.append(contentsOf: assetArr) } } } } return arr } //获取一个相册里的所有图片的PHAsset对象 func getAllPHAssetFromOneAlbum(assetCollection:PHAssetCollection)->([PHAsset]){ // 存放所有图片对象 var arr:[PHAsset] = [] // 是否按创建时间排序 let options = PHFetchOptions.init() options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]//时间排序 options.predicate = NSPredicate.init(format: "mediaType == %ld", PHAssetMediaType.image.rawValue)//˙只选照片 // 获取所有图片资源对象 let results:PHFetchResult = PHAsset.fetchAssets(in: assetCollection, options: options) // 遍历,得到每一个图片资源asset,然后放到集合中 results.enumerateObjects { (asset, index, stop) in print("\(asset)") arr.append(asset) } return arr } 根据PHAsset获取原图片信息 func getImageFromPHAsset(asset:PHAsset,size:CGSize){ var requestID:PHImageRequestID = -2 let scale:CGFloat = CGFloat(UIScreen.main.scale) let width:CGFloat = CGFloat(min(WIDTH, 500)) if (requestID >= 1 && (size.width) / width == scale) { PHCachingImageManager.default().cancelImageRequest(requestID) } let option:PHImageRequestOptions=PHImageRequestOptions.init() option.deliveryMode = PHImageRequestOptionsDeliveryMode.opportunistic option.resizeMode = PHImageRequestOptionsResizeMode.fast; requestID = PHCachingImageManager.default().requestImageData(for: asset, options: option, resultHandler: { (Dat, str, orientation, [AnyHashable : Any]?) in //Dat是图片数据,吧UIIMage加入到数组中 let image:UIImage=UIImage.init(data: Dat!)! self.imageArr.append(image) }) //请求视频的 // requestID = PHCachingImageManager.default().requestAVAsset(forVideo: PHAsset, options: PHVideoRequestOptions?, resultHandler: { (<#AVAsset?#>, AVAudioMix?, [AnyHashable : Any]?) in // // }) } }*************/** 相册多选的cell */import UIKitclass LYBMutipleSelectAlbumCollectionviewcell: UICollectionViewCell { var imageV:UIImageView! var image:UIImage=UIImage.init(named: "appstart")!{ willSet(image) { } didSet { imageV.image=image } } override init(frame: CGRect) { super.init(frame: frame) createCell() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func createCell(){ imageV = UIImageView.init(frame:CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) imageV.image=UIImage.init(named: "appstart") addSubview(imageV) } }

 

3.**************相册多选封装***************

/** //设置为不选中状态 collectionView.deselectItem(at: indexPath, animated: false) //这个是用来获取所有的indexpath collectionView.indexPathsForSelectedItems   用来显示所有的相册照片 使用: let looAlbum = LYBMutipleSelectAlbumView.init(frame: CGRect.init(x: 0, y: 0, width: Int(WIDTH), height: Int(HEIGHT)-Int(bottomSafeHeight))) looAlbum.selectBlock={ (selectimageArr)in print("\(selectimageArr)") } view.addSubview(looAlbum) */import UIKitimport Photosclass LYBMutipleSelectAlbumView: UIView,UICollectionViewDelegate,UICollectionViewDataSource { var collec:UICollectionView?    var image:UIImage!=UIImage.init(named: "appstart")    var imageArr:[UIImage]=[]//从系统相册获取到的图片数组    var assetArr: [PHAsset]=[]//从系统相册获取所有照片资源    var index:Int = 0//记录显示图片的最大索引    let step:Int = 12//每次加载多少张图片    var isSelectCell:Bool=false//是否选中cell,默认不选中,不显示对号    var indexArr:[Int]=[]//存放选中cell序号的数组        var selectImageArr:[UIImage]=[]//选中的cell对应的图片    //确认按钮,选中照片    var selectBlock:([UIImage])->()={        ([UIImage])->()in            }        override init(frame: CGRect) {        super.init(frame: frame)         assetArr =  getAllAlbumAndPHAsset()//获取照片资源        createCollectionView()               //吧强求到图片资源转换成UIIMgae,在回掉方法中获取图片data数据,然后做相应的操作         pullUprefresh()//先刷新一下          }        required init?(coder aDecoder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }       lazy var sureAndCancelView:UIView={    let v:UIView=UIView.init(frame: CGRect.init(x: 0, y: 0, width: WIDTH, height: 50))                let cancelBtn:UIButton=UIButton.init(frame: CGRect.init(x: 20, y: 0, width: 100, height: 50))        cancelBtn.setTitle("取消", for: UIControl.State.normal)        cancelBtn.addTarget(self, action: #selector(cancelClick), for: UIControl.Event.touchUpInside)        cancelBtn.setTitleColor(UIColor.black, for: UIControl.State.normal)        v.addSubview(cancelBtn)                let sureBtn:UIButton=UIButton.init(frame: CGRect.init(x:WIDTH-120, y: 0, width: 100, height: 50))        sureBtn.setTitle("确定", for: UIControl.State.normal)        sureBtn.addTarget(self, action: #selector(sureClick), for: UIControl.Event.touchUpInside)        sureBtn.setTitleColor(UIColor.black, for: UIControl.State.normal)        v.addSubview(sureBtn)    return v    }()    //确定按钮    @objc func sureClick(sender:UIButton){        print("确定")        //吧选中的图片放到一个集合给到外面        for index in indexArr{            selectImageArr.append(imageArr[index])        }        selectBlock(selectImageArr)        self.removeFromSuperview()    }    //取消按钮    @objc func cancelClick(sender:UIButton){        print("取消")        self.removeFromSuperview()    }    func createCollectionView(){        addSubview(sureAndCancelView)                        let flowLayout = UICollectionViewFlowLayout.init()        flowLayout.itemSize=CGSize.init(width: WIDTH/4, height: WIDTH/4)        flowLayout.minimumLineSpacing=0        flowLayout.minimumInteritemSpacing=0         collec = UICollectionView.init(frame: CGRect.init(x: 0, y: 50, width: Int(WIDTH), height: Int(HEIGHT)-Int(bottomSafeHeight)-Int(TopSpaceHigh)), collectionViewLayout: flowLayout)        collec?.backgroundColor=UIColor.white        collec?.delegate=self        collec?.dataSource=self//        collec?.register(LYBMutipleSelectAlbumCollectionviewcell.classForCoder(), forCellWithReuseIdentifier: "LYBMutipleSelectAlbumCollectionviewcell")        addSubview(collec!)        collec?.allowsMultipleSelection=true//允许多选       initNormalAutoFooterRefresh()//上拉加载    }        //上拉加载    func initNormalAutoFooterRefresh(){        let footer =  MJRefreshAutoNormalFooter()        //上刷新相关设置        footer.setRefreshingTarget(self, refreshingAction: #selector(pullUprefresh))        //self.bottom_footer.stateLabel.isHidden = true // 隐藏文字        //是否自动加载(默认为true,即表格滑到底部就自动加载,这个我建议关掉,要不然效果会不好)        footer.isAutomaticallyRefresh = false        footer.isAutomaticallyChangeAlpha = true //自动更改透明度        //修改文字        footer.setTitle("上拉加载", for: .idle)//普通闲置的状态        footer.setTitle("正在加载中", for: .refreshing)//正在刷新的状态        footer.setTitle("加载完成", for: .noMoreData)//数据加载完毕的状态        collec?.mj_footer=footer    }        //上拉刷新    @objc func pullUprefresh(){        if(assetArr.count<=step){//所有资源小于10个,加载实际的个数            for i in 0..
index{ for i in index-step..
index-step && assetArr.count
Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return imageArr.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let CellIdentifier:String = String.init(format: "cell%d%d", indexPath.section,indexPath.item)//以indexPath来唯一确定cell collec?.register(LYBMutipleSelectAlbumCollectionviewcell.classForCoder(), forCellWithReuseIdentifier: CellIdentifier) let cell:LYBMutipleSelectAlbumCollectionviewcell = collectionView.dequeueReusableCell(withReuseIdentifier: CellIdentifier, for: indexPath) as! LYBMutipleSelectAlbumCollectionviewcell cell.image = imageArr[indexPath.item] cell.backgroundColor=UIColor.red return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { collectionView.deselectItem(at: indexPath, animated: true)//取消选中,和显示按钮两回事 let cell:LYBMutipleSelectAlbumCollectionviewcell=collectionView.cellForItem(at: indexPath) as! LYBMutipleSelectAlbumCollectionviewcell if indexArr.contains(indexPath.item){ //过滤掉已经选中的cell,这里通过filter过滤掉的到一个新的数组,再把新的数组赋值给原来的数组,swift中没有现成的删除指定元素的方法 let filterArr = indexArr.filter { $0 != indexPath.item//数组中留下的元素都是不等于indexPath.item } indexArr=filterArr cell.isSelect=false }else { indexArr.append(indexPath.item)//吧cell的画序号加入到数组 cell.isSelect=true } //数组中的序号做一个数组排序,升序 indexArr.sort { $0<$1 } print("\(indexPath.item)-----\(indexArr)-----") } func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { print("取消选择") } //1.获取所有PHAsset资源的集合,包含视频和照片 func getAllPHAssetFromSysytem()->([PHAsset]){ var arr:[PHAsset] = [] let options = PHFetchOptions.init() let assetsFetchResults:PHFetchResult = PHAsset.fetchAssets(with: options) // 遍历,得到每一个图片资源asset,然后放到集合中 assetsFetchResults.enumerateObjects { (asset, index, stop) in arr.append(asset) } print("\(arr.count)") return arr } //2.先获取所有相册,然后从相机胶卷中获取PHAsset集合,(相机胶卷是相册中的一个,包含了所有视频和相册) func getAllAlbumAndPHAsset()->([PHAsset]){ var arr:[PHAsset] = [] let options = PHFetchOptions.init() // 所有智能相册集合(系统自动创建的相册) let smartAlbums:PHFetchResult = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.smartAlbum, subtype: PHAssetCollectionSubtype.albumRegular, options: options) //遍历得到每一个相册 for i in 0..
0{ //某个相册里面的所有PHAsset对象(PHAsset对象对应的是图片,需要通过方法请求到图片) assetArr = getAllPHAssetFromOneAlbum(assetCollection: assetCollection) arr.append(contentsOf: assetArr) } } } } return arr } //获取一个相册里的所有图片的PHAsset对象 func getAllPHAssetFromOneAlbum(assetCollection:PHAssetCollection)->([PHAsset]){ // 存放所有图片对象 var arr:[PHAsset] = [] // 是否按创建时间排序 let options = PHFetchOptions.init() options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]//时间排序 options.predicate = NSPredicate.init(format: "mediaType == %ld", PHAssetMediaType.image.rawValue)//˙只选照片 // 获取所有图片资源对象 let results:PHFetchResult = PHAsset.fetchAssets(in: assetCollection, options: options) // 遍历,得到每一个图片资源asset,然后放到集合中 results.enumerateObjects { (asset, index, stop) in print("\(asset)") arr.append(asset) } return arr } 根据PHAsset获取原图片信息 func getImageFromPHAsset(asset:PHAsset,size:CGSize){ var requestID:PHImageRequestID = -2 let scale:CGFloat = CGFloat(UIScreen.main.scale) let width:CGFloat = CGFloat(min(WIDTH, 500)) if (requestID >= 1 && (size.width) / width == scale) { PHCachingImageManager.default().cancelImageRequest(requestID) } let option:PHImageRequestOptions=PHImageRequestOptions.init() option.deliveryMode = PHImageRequestOptionsDeliveryMode.opportunistic option.resizeMode = PHImageRequestOptionsResizeMode.fast; requestID = PHCachingImageManager.default().requestImageData(for: asset, options: option, resultHandler: { (Dat, str, orientation, [AnyHashable : Any]?) in //Dat是图片数据,吧UIIMage加入到数组中 let image:UIImage=UIImage.init(data: Dat!)! print("\(image.size)---压缩前") //压缩图片 let newSize:CGSize = CGSize.init(width: 100, height: 100) UIGraphicsBeginImageContext(newSize) image.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() print("\(String(describing: newImage))---压缩后") self.imageArr.append(newImage!) }) //请求视频的 // requestID = PHCachingImageManager.default().requestAVAsset(forVideo: PHAsset, options: PHVideoRequestOptions?, resultHandler: { (<#AVAsset?#>, AVAudioMix?, [AnyHashable : Any]?) in // // }) } }**********/** 相册多选的cell */import UIKitclass LYBMutipleSelectAlbumCollectionviewcell: UICollectionViewCell { var imageV:UIImageView! var image:UIImage=UIImage.init(named: "appstart")!{ willSet(image) { } didSet { imageV.image=image } } //是否选中 var isSelect:Bool=false{ didSet{ print("\(isSelect)") if isSelect{ selectbtn.setImage(UIImage.init(named: "comm_btn_checkmark"), for: UIControl.State.normal) }else { selectbtn.setImage(UIImage.init(), for: UIControl.State.normal) } } } override init(frame: CGRect) { super.init(frame: frame) createCell() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func createCell(){ imageV = UIImageView.init(frame:CGRect.init(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) imageV.image=UIImage.init(named: "appstart") addSubview(imageV) addSubview(selectbtn) } lazy var selectbtn:UIButton={ let btn:UIButton=UIButton.init(frame: CGRect.init(x: 0, y: self.frame.size.width-50, width: 30, height: 30)) return btn }()}

 

转载地址:http://glmgi.baihongyu.com/

你可能感兴趣的文章
Python sys.argv[]详解
查看>>
Python sys.path、sys.modules模块介绍
查看>>
python元组遍历
查看>>
python字典用法总结
查看>>
python异常处理
查看>>
python sys.exc_info()详解
查看>>
python中os模块作用
查看>>
ubuntu python subprocess模块执行python脚本
查看>>
python xticks()函数设置X轴方法--刻度、标签
查看>>
HTTP协议原理
查看>>
python正则表达式模块re
查看>>
python爬虫总结
查看>>
python网络编程基础--http
查看>>
python 构造http请求对象-Request对象
查看>>
解决Ubuntu16.04更新源时显示“暂时不能解析域名”问题
查看>>
Ubuntu16.04运行清空文件命令时提示权限不够解决方法
查看>>
shell脚本编写笔记
查看>>
Ubuntu16.04实现定时免密远程拷贝脚本
查看>>
Ubuntu 16.04安装Docker
查看>>
Docker报错:Temporary failure in name resolution&Proxy Authentication Required
查看>>