带大图显示的图片选择器&自定义相机(选中的自动前移)-----》PhotoKit
来源:互联网 发布:名片制作软件美图秀秀 编辑:程序博客网 时间:2024/05/19 17:57
最终效果:
模拟器没有相机功能,所以这里就不展示了。
思路
因为ALAssetLibrary获取系统资源的方法在iOS9中不被推荐,所以这里使用PhotoKit
关于PhotoKit跟ALAssetLibrary的差异以及使用详细使用方法可以点击iOS 开发之照片框架详解
图中的图片表格列表是用的UICollectionView,collectionview是类似tableview的列表控件,但是功能更强大,有兴趣的同学可以参考UICollection学习总结以及案例集合
里面有7个关于collectionview的demo,有一些功能比较好玩的实现,这里就不一一介绍了。
回到正题,
因为用的是photokit,photokit中获取的资源并不是直接的是图片资源,而是PHAsset(代表照片库中的一个资源,跟 ALAsset 类似,通过 PHAsset 可以获取和保存资源)所以基本的思路是,从系统相册获取到资源,都以PHAsset保存到模型中,在最后要展示的时候再通过统一的方法将PHAsset转换成图片
模型
class CHImage: NSObject { var asset:PHAsset! var isSelected = false override init() { super.init() } }
用来保存获取的资源信息
图片有选中和未选中两个状态定义一个isSelected属性来记录选中状态
未完待续。。。。
续:
有了可以保存资源的Model以后,就需要去获取资源了,这路贴一张网上的关于photokit组成的图:
PhotoKit获取资源的方式,是通过一系列形如 class func fetchXXX(…, options: PHFetchOptions) -> PHFetchResult 的类方法,可以根据这些方法来封装一些方法:
/** 获取全部相册 */ func getPhotoListDatas() -> NSArray { var dataArr = [AnyObject]() // 列出所有相册智能相册 let smartAlbums = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype:.SmartAlbumUserLibrary, options: nil) dataArr.append(smartAlbums[0]) // 列出所有用户创建的相册 let topLevelUserCollections:PHFetchResult = PHAssetCollection.fetchTopLevelUserCollectionsWithOptions(nil) for i in 0 ..< topLevelUserCollections.count { let sub = topLevelUserCollections[i] dataArr.append(sub) } return dataArr }/** 获取一个相册的结果集合 */ func getFetchResult(assetCollection:PHAssetCollection) -> PHFetchResult { let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let fetchResult = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: fetchOptions) return fetchResult }/** 只获取相机胶卷结果集 */ func getCameraRollFetchResul() -> PHFetchResult{ let fetchOptions = PHFetchOptions() let smartAlbumsFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.SmartAlbum, subtype:.SmartAlbumUserLibrary, options: fetchOptions) let fetch = PHAsset.fetchAssetsInAssetCollection(smartAlbumsFetchResult[0] as! PHAssetCollection, options: nil) return fetch }/** 获取图片实体并把图片结果存放到数组中,返回数组 */ func getPhotoAssets(fetchResult:PHFetchResult) -> [CHImage]{ var dataArr = [CHImage]() for i in 0 ..< fetchResult.count { let asset = fetchResult[i] as! PHAsset let image = CHImage() /** 过滤视频 */ if asset.mediaType == .Image{ image.asset = asset dataArr.append(image) } } return dataArr }// 获取某个分组的第一张照片缩略图 func firstPhotoThumbnails(assetCollection:PHAssetCollection,synchronous:Bool, resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) { self.photoThumbnails(self.getFetchResult(assetCollection).firstObject as! PHAsset,synchronous:synchronous, resultHandler: resultHandler) } // 获取某一张照片缩略图 func photoThumbnails(asset: PHAsset!,synchronous:Bool,resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) { let superSize = CGSizeMake(186 , 186 ) return self.photoImage(superSize,synchronous:synchronous ,asset: asset, resultHandler: resultHandler) } // 获取一张大图 func photoDefault(asset: PHAsset!, synchronous:Bool, targetSize:CGSize,resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) { return self.photoImage(targetSize, synchronous:synchronous, asset: asset, resultHandler: resultHandler) }
最后,我们前面的这些方法获取到的最后的不管是缩略图还是大图,获取到的都是自定义的Model类型的而不是我们想要的UIImage类型的所以还需要一个方法来获取最后的image
/** 获取图片 */ func photoImage(targetSize: CGSize, synchronous:Bool,asset: PHAsset!, resultHandler: (UIImage?, [NSObject : AnyObject]?) -> Void) { let options = PHImageRequestOptions() options.resizeMode = .Exact options.synchronous = synchronous PHImageManager.defaultManager().requestImageForAsset(asset, targetSize:targetSize, contentMode: .AspectFill, options: options, resultHandler: resultHandler) }
这里有一个坑,因为存在相册中的图片的宽高比我们是不知道的,所以获取图片的时候targetSize我们只能穿PhotoKi给我们的默认值就是原图大小PHImageManagerMaximumSize,但是这样获取到的图片大小肯定会超乎你的想象,所以获取到图片之后需要通过:
/** 修改图片尺寸 */ static func scaleToSize(image:UIImage?,width:CGFloat,height:CGFloat) -> UIImage { // let scale = image!.size.height/image!.size.width let size = CGSizeMake(width, height) UIGraphicsBeginImageContext(size) image!.drawInRect(CGRectMake(0, 0, size.width, size.height)) let newImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return newImage }
来重新画一张图片,缩小图片更好的展示的同时还可以缩小图片的大小,上传的时候更方便。注意,这里的width跟height应该是你所先要的图片尺寸的2以上倍,不然图片看上去会格外的不清晰(AV画质~)
获取到资源之后,就是用uicollectionview展示,实现delegate跟datasource这里就不赘述了。关键点是实习选中的图片前移,没选中的后移,移动的动画非常简单,用uicollectionview自带的func moveItemAtIndexPath(indexPath: NSIndexPath, toIndexPath newIndexPath: NSIndexPath) 这里要确定要交换的图的初始位置跟要换到的位置,而在点击继续之后需要从全部相册资源中选出isSelected = true的资源,如果用循环,因为大部分人的手机中照片都是500+,用循环会卡死,所以这里用正则来匹配,swift中的正则使用方法:
func getSelectedImageArray() -> [CHImage] { let predicate1 = NSPredicate(format: "isSelected == true") return (self.imageArray as NSArray).filteredArrayUsingPredicate(predicate1) as! [CHImage] }
可以很快的匹配出条件符合的资源,并放入数组,之后只要将这个数组传给下一个页面,或者将资源转换成图片之后再传,这个可以根据需求自己定。下面是demo自定义相册&相机
里面还有一个相机的自定义,基本上就自定义了图标跟重拍之类的。仅供大家一起学习讨论。
- 带大图显示的图片选择器&自定义相机(选中的自动前移)-----》PhotoKit
- iOS开发进阶 - 基于PhotoKit的图片选择器
- Android 调用系统相机进行拍照 使用自带的图片选择器和裁剪工具
- Android 自定义相机开发(支持前置,后置摄像头,可以自动聚焦,保存和显示图片)
- android 超强大的图片选择器,支持超大图加载
- 带滚动条的大图无刷新显示框
- 自定义一个可以自动循环显示图片的Demo
- 自定义图片的显示
- 自定义 RadioButton 选中和未选中时的图片
- TabBarItem自定义选中和未选中的图片高度超出
- 自定义 RadioButton 选中和未选中时的图片
- RadioButton的自定义大图片变为小图片
- iOS7 UITabBar自定义选中图片显示为默认蓝色的Bug
- OS7 UITabBar自定义选中图片显示为默认蓝色的Bug
- iOS7 UITabBar自定义选中图片显示为默认蓝色的Bug
- iOS7修改UITabBar文本颜色以及解决自定义选中图片显示为默认蓝色的问题
- iOS7 UITabBar自定义选中图片显示为默认蓝色的Bug
- Android中高效的显示图片 - 加载大图
- git常用命令
- STL中list的简单实现
- 菜单组件
- 限制波尔兹曼机
- 安卓开发学习心得-------GridView基础
- 带大图显示的图片选择器&自定义相机(选中的自动前移)-----》PhotoKit
- 【Dongle】【VS】之窗体异常
- 在Sublime Text 3下解决中文乱码的情况
- JStorm-2.1.1源码分析--Topology提交(上)
- iOS 可读性 readonly
- java 实现全角字符转换为半角字符
- 2016年读书记录
- JavaScript笔记整理——this 的工作原理
- sscanf&sprintf讲解