首页 热点资讯 义务教育 高等教育 出国留学 考研考公
您的当前位置:首页正文

iOS UIImagePickerController封装(Sw

2024-12-15 来源:花图问答
//
//  JHImagePickerController.swift
//
//
//  Created by jonhory on 16/6/11.
//  Copyright © 2016年  All rights reserved.
//

import UIKit
import AVFoundation
import AssetsLibrary
import Photos
import PhotosUI
import MobileCoreServices

/** 获取相机权限成功*/
typealias cameraSuccess   = (imagePickerController:UIImagePickerController)  -> Void
/** 获取相机权限失败*/
typealias cameraFail      = ()                                               -> Void
/** 获取相簿权限成功*/
typealias albumSuccess    = (imagePickerController:UIImagePickerController)  -> Void
/** 获取相簿权限失败*/
typealias albumFail       = ()                                               ->Void

@objc protocol JHImagePickerControllerDelegate: class {
    /**
     获取图片回调
     
     - parameter image: 获取的图片
     
     - returns: 返回获取的图片
     */
    optional func selectImageFinished(image:UIImage)
    
    /**
     返回获取的图片并缓存(当设置缓存并且设置缓存标识符时返回该方法)
     - parameter image:            获取的图片
     - parameter cachesIdentifier: 缓存标识符(缓存文件时的名称)
     - parameter isCachesSuccess:  缓存图片是否成功
     
     - returns: 返回获取的图片并缓存
     */
    optional func selectImageFinishedAndCaches(image:UIImage,cachesIdentifier:String,isCachesSuccess:Bool)
    
}

class JHImagePickerController: NSObject,UIImagePickerControllerDelegate,UINavigationControllerDelegate {

    //publice
    /** 选取图片代理*/
    weak var delegate:JHImagePickerControllerDelegate?
    /** 是否缓存*/
    var isCaches:Bool?
    /** 缓存图片的标识符*/
    var identifier:String?
    
    //private
    /** 获取相机权限成功*/
    private var cameraSuccessClosure:cameraSuccess!
    /** 获取相机权限失败*/
    private var cameraFailClosure:cameraFail!
    /** 获取相簿权限成功*/
    private var albumSuccessClosure:albumSuccess!
    /** 获取相簿权限失败*/
    private var albumFailClosure:albumFail!
    /** UIImagePickerController*/
    private var imagePickerController:UIImagePickerController! = nil
    /** 选取的图片*/
    private var image:UIImage?
    
    deinit{
       print("dealloc : \(self)")
    }
    
    override init() {
        super.init()
        cameraReady()
        
    }
    
    init(isCaches:Bool,identifier:String){
        super.init()
        cameraReady()
        self.isCaches = isCaches
        self.identifier = identifier
    }
    
    //MARK:从相机拍摄图片
    func selectImageFromCameraSuccess(closure:cameraSuccess,Fail failClosure:cameraFail){
        cameraFailClosure = failClosure
        let authStatus = AVCaptureDevice.authorizationStatusForMediaType(AVMediaTypeVideo)
        if authStatus == .Restricted || authStatus == .Denied{
            if cameraFailClosure != nil {
                cameraFailClosure()
            }
            return
        }
        
        cameraSuccessClosure = closure
        if UIImagePickerController.isSourceTypeAvailable(.Camera) {
            imagePickerController!.sourceType = .Camera
            imagePickerController!.mediaTypes = [kUTTypeImage as String]
            imagePickerController!.cameraCaptureMode = .Photo
            if cameraSuccessClosure != nil {
                cameraSuccessClosure(imagePickerController: imagePickerController!)
            }
        }
        
    }
    
    //MARK:从相簿选取图片
    func selectImageFromAlbumSuccess(closure:albumSuccess,Fail failClosure:albumFail){
        albumFailClosure = failClosure
        let status = ALAssetsLibrary.authorizationStatus()
        if status == .Restricted || status == .Denied {
            if albumFailClosure != nil {
                albumFailClosure()
            }
            return
        }

        albumSuccessClosure = closure
        imagePickerController!.sourceType = .PhotoLibrary
        if albumSuccessClosure != nil {
            albumSuccessClosure(imagePickerController:imagePickerController!)
        }
    }
    
    //MARK:UIImagePickerControllerDelegate
    //选取图片完成
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
        let mediaType:String = info[UIImagePickerControllerMediaType] as! String
        if mediaType == kUTTypeImage as String{
            image = info[UIImagePickerControllerEditedImage] as? UIImage
            if self.isCaches == true && self.identifier != nil && self.identifier != ""{
                let cachesStatus = saveImageToCaches(image!, identifier: self.identifier!)
                self.delegate?.selectImageFinishedAndCaches?(image!, cachesIdentifier: self.identifier!, isCachesSuccess: cachesStatus)
            }else {
                self.delegate?.selectImageFinished?(image!)
            }
        }
    }
    
    //MARK:读取缓存的图片
    /**
     读取缓存的图片
     
     - parameter identifier: 图片标识符(缓存文件的名称)
     
     - returns: 读取缓存的图片
     */
    func readImageFromCaches(identifier:String) -> UIImage {
        let path = jhSavePath + "/" + identifier
        var image:UIImage?
        if NSFileManager.defaultManager().fileExistsAtPath(path) {
            let read = NSFileHandle.init(forReadingAtPath: path)
            let data = read?.readDataToEndOfFile()
            image = UIImage.init(data: data!)
            //若要判断是否返回正确的缓存图片,可以设置图片的accessibilityIdentifier属性,然后在外部调用的时候判断accessibilityIdentifier属性是否等于你设置的
            image?.accessibilityIdentifier = identifier
        }else {
            image = UIImage(named: "jhSurprise.jpg")
            image?.accessibilityIdentifier = "jhSurprise.jpg"
        }
        
        return image!
    }
    
    /**
     删除指定缓存图片
     
     - parameter identifier: 缓存图片标识符(缓存图片名称)
     
     - returns: 删除指定缓存图片
     */
    func removeCachesPictureForIdentifier(identifier:String) -> Bool{
        let path = jhSavePath + "/" + identifier
        if NSFileManager.defaultManager().fileExistsAtPath(path) {
            do {
                try NSFileManager.defaultManager().removeItemAtPath(path)
                return true
            }catch {
                print("\(self) remove picture for id:\(identifier) failure")
                return false
            }
        }
        print("\(self) remove picture for id:\(identifier) failure ,error: path=\(path) isn't existed")
        return false
    }
    
    /**
     删除全部缓存图片
     
     - returns: 删除全部缓存图片
     */
    func removeCachesPictures() -> Bool {
        if NSFileManager.defaultManager().fileExistsAtPath(jhSavePath) {
            do {
                try NSFileManager.defaultManager().removeItemAtPath(jhSavePath)
                return true
            }catch {
                print("\(self) remove pictures for path:\(jhSavePath) failure")
                return false
            }
        }
        print("\(self) remove pictures failure ,error: path=\(jhSavePath) isn't existed")
        return false
    }
    
    //MARK:Private
    private func cameraReady(){
        imagePickerController = UIImagePickerController()
        imagePickerController.delegate = self
        imagePickerController.allowsEditing = true
    }
    
    //缓存图片
    private func saveImageToCaches(image:UIImage,identifier:String) -> Bool {
        let imageData = UIImageJPEGRepresentation(image, 0.5)
        if  !NSFileManager.defaultManager().fileExistsAtPath(jhSavePath) {//如果不存在文件则创建
            do {
                try NSFileManager.defaultManager().createDirectoryAtPath(jhSavePath, withIntermediateDirectories: true, attributes: nil)
                print("create file success:\(jhSavePath)")
            }catch{
                print("create file failure")
                return false
            }
        }
        let path = jhSavePath + "/" + identifier

        if NSFileManager.defaultManager().createFileAtPath(path, contents: imageData, attributes: nil){
            print("save pic for id:\(identifier) success")
            return true
        }
        print("save pic failure")
        return false
    }
}


//MARK:缓存图片路径
let jhCachesPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0]
let jhSavePath = jhCachesPath + "/jhImageCaches"

以下是使用方法:
1.声明

var imagePickerController:JHImagePickerController?

2.初始化

//初始化方法一
//        imagePickerController = JHImagePickerController()
//初始化方法一的补充设置(若需要缓存时才设置)
//设置是否缓存(默认为false)
//        imagePickerController?.isCaches = true
//设置缓存id(当需要缓存时才设置)
//        imagePickerController?.identifier = "xx"

//初始化方法二
imagePickerController = JHImagePickerController(isCaches: true, identifier: "abc")

3.设置代理 JHImagePickerControllerDelegate

imagePickerController?.delegate = self

选取图片来自相册 注意使用[weak self]防止强引用

self.imagePickerController?.selectImageFromAlbumSuccess({[weak self] (imagePickerController) in
    if let strongSelf = self {
        strongSelf.presentViewController(imagePickerController, animated: true, completion: nil)
    }
}, Fail: {
    //SVProgressHUD.showErrorWithStatus("无法获取照片权限")
})

选取图片来自相机 注意使用[weak self]防止强引用

self.imagePickerController?.selectImageFromCameraSuccess({[weak self](imagePickerController) in
    if let strongSelf = self {
        strongSelf.presentViewController(imagePickerController, animated: true, completion: nil)
    }
}, Fail: {
    //SVProgressHUD.showErrorWithStatus("无法获取相机权限")
})

当未设置缓存或缓存identifier为空时返回该方法

func selectImageFinished(image: UIImage) {
    imageView.image = image
    self.dismissViewControllerAnimated(true, completion: nil)
}

当设置了缓存,且输入缓存identifier时返回该方法(未设置缓存时可以不实现)

func selectImageFinishedAndCaches(image: UIImage, cachesIdentifier: String, isCachesSuccess: Bool) {
    if isCachesSuccess == true {
        imageView.image = image
    }
    self.dismissViewControllerAnimated(true, completion: nil)
}

6.根据identifier读取缓存图片

let image = self.imagePickerController?.readImageFromCaches("abc")
if image != nil {
    imageView.image = image
}else {
    print("读取缓存照片失败,请检查图片identifier是否存在")
}

7.删除指定identifier的缓存图片(删除id:abc)

self.imagePickerController?.removeCachesPictureForIdentifier("abc")

删除全部缓存图片

if self.imagePickerController?.removeCachesPictures() == true {
    print("删除全部缓存图片成功")
}
显示全文