iOS實現(xiàn)微信/QQ顯示最近拍攝圖片的功能實例代碼
如果你剛剛拍攝了圖片,在使用微信/QQ發(fā)生消息時會顯示“你可能要發(fā)送的圖片”,

實現(xiàn)原理:
1、打開或重新進入聊天窗口時查詢圖庫最新的照片, 對比拍照時間和當(dāng)前時間的差,當(dāng)?shù)陀陂撝担ɡ缫环昼姡r就顯示出來。 PS:閾值是邏輯上判斷是否最近的依據(jù)。優(yōu)點:總能找到最近拍攝的圖片; 缺點:每次都要查詢圖片數(shù)據(jù),響應(yīng)較慢。
2、注冊圖庫變化監(jiān)聽(觀察者模式), 響應(yīng)圖庫的增刪改事件, 拿到變化圖片數(shù)據(jù)后做對應(yīng)的邏輯。 優(yōu)點: 實時響應(yīng); 缺點:影響性能, 在注冊監(jiān)聽前拿不到變化數(shù)據(jù)。
實現(xiàn)方式:
1、在info.plist文件中添加訪問相機數(shù)據(jù)的權(quán)限。

2、在啟動應(yīng)用后要獲取相機權(quán)限, 調(diào)用PHPhotoLibrary.requestAuthoriztion方法,提示內(nèi)容是plist對應(yīng)相機權(quán)限字段內(nèi)容(PS:跟Android的動態(tài)權(quán)限獲取是一個套路)。
3、獲取相機權(quán)限后,要緩存所有PHAsset類型的照片記錄(不包含圖片二進制數(shù)據(jù),所有不用擔(dān)心內(nèi)存溢出); 緩存所有圖片記錄是為了后續(xù)比較變化使用, 邏輯上是變化前數(shù)據(jù)。
4、觀察者模式的register, 注意在適當(dāng)?shù)牡胤揭獔?zhí)行unregisterChangeObserver。
5、在回調(diào)函數(shù)photoLibraryDidChange里做圖庫變化后的邏輯, 這里的PHChange類可以跟前面緩存的變化前數(shù)據(jù)比較并得到變化的部分(包括新增、刪除、修改,厲害了; Android沒有這么方便的API。。。)。
6、使用DispatchQueue.main.async是主線程異步執(zhí)行, 作用同Android主線程Handler的sendMessage。這是觀察者模式的標(biāo)準(zhǔn)做法,避免阻塞通知隊列。
7、使用PHCachingImageManager取出PHAsset的圖片數(shù)據(jù)ImageView對象。
8、顯示到UI里。
參考代碼:
import UIKit
import Photos //使用圖庫功能時必須引用這個包
//顯示最近拍攝的照片為縮略圖
class ViewController: UIViewController, PHPhotoLibraryChangeObserver {
var assetsFetchResults:PHFetchResult<PHAsset>!
var imageManager: PHCachingImageManager! //帶緩存的圖片管理對象
var imageView: UIImageView! //用于顯示縮略圖
var assetGridThumbnailSize: CGSize! //縮略圖大小
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
imageView = UIImageView()
imageView.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
imageView.contentMode = .scaleAspectFit
imageView.clipsToBounds = true
self.view.addSubview(imageView)
self.imageManager = PHCachingImageManager() //初始化和充值緩存
let scale = UIScreen.main.scale //像素比
assetGridThumbnailSize = CGSize(width: imageView.frame.width*scale,
height: imageView.frame.height*scale)
//申請權(quán)限
PHPhotoLibrary.requestAuthorization({ (status) in
if status != .authorized {
return
}
//獲取所有圖片資源(按照創(chuàng)建時間排序)
let allPhotoOptions = PHFetchOptions()
allPhotoOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate",
ascending: false)] //排序方式
allPhotoOptions.predicate = NSPredicate(format: "mediaType = %d",
PHAssetMediaType.image.rawValue) //類型
self.assetsFetchResults = PHAsset.fetchAssets(with: .image,
options: allPhotoOptions) //查詢照片類型
var i = 0
while i<self.assetsFetchResults.count {
let asset = self.assetsFetchResults[i]
print(" 創(chuàng)建時間:\(asset.creationDate?.description)") //打印所有圖片的創(chuàng)建時間
i += 1
}
if (self.assetsFetchResults.count > 0) {
//顯示最近一張拍攝的圖片(也可以根據(jù)拍攝時間遠近決定是否要顯示)
self.imageManager.requestImage(for: self.assetsFetchResults[0], //最近一張圖片
targetSize: self.assetGridThumbnailSize,
contentMode: .aspectFill,
options: nil, resultHandler: { (image, info) in
self.imageView.image = image //取出圖像并顯示出來
})
}
print("圖片數(shù)量:\(self.assetsFetchResults?.count)")
//注冊監(jiān)聽資源變化
PHPhotoLibrary.shared().register(self) //刪除是unregisterChangeObserver
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func photoLibraryDidChange(_ changeInstance: PHChange) {
guard let changes = changeInstance.changeDetails(for: self.assetsFetchResults as! PHFetchResult<PHObject>) else {
return
}
//異步執(zhí)行,避免阻塞圖片變化事件隊列
DispatchQueue.main.async {
if let result = changes.fetchResultAfterChanges as? PHFetchResult<PHAsset> {
self.assetsFetchResults = result //差異結(jié)果
}
//判斷是否有新增圖片或刪除圖片的情況
if !changes.hasIncrementalChanges || changes.hasMoves {
return
} else {
print("圖片數(shù)據(jù)有變化")
if let indexs = changes.changedIndexes, indexs.count>0 { //不顯示0的情況
print("有\(zhòng)(indexs.count)張圖片發(fā)生變化")
}
if let removes = changes.removedIndexes, removes.count>0 {
print("刪除了\(removes.count)張圖片")
}
if let inserts = changes.insertedIndexes, inserts.count>0 {
//有新增圖片
print("新增了\(inserts.count)張圖片")
let picture = self.assetsFetchResults[inserts.first!]
self.imageManager.requestImage(for: picture,
targetSize: self.assetGridThumbnailSize,
contentMode: .aspectFill,
options: nil, resultHandler: { (image, option) in
self.imageView.image = image //取出圖像并顯示出來
})
}
}
}
}
}
以上所述是小編給大家介紹的iOS實現(xiàn)微信/QQ顯示最近拍攝圖片的功能實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
iOS中關(guān)于Swift UICollectionView橫向分頁的問題
這篇文章通過圖文并茂的形式給大家介紹UICollectionView橫向分頁的問題,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧2017-05-05
iOS開發(fā)Quick Actions創(chuàng)建桌面Icon快捷方式
在本文里我們給大家分享了關(guān)于iOS開發(fā)Quick Actions創(chuàng)建桌面Icon快捷方式的相關(guān)知識點內(nèi)容,需要的讀者們可以參考下。2019-05-05
IOS開發(fā)之多線程NSThiread GCD NSOperation Runloop
這篇文章主要介紹了IOS多線程開發(fā),主要用到NSThiread、GCD、 NSOperation、Runloop,有詳細的原理解析和實例代碼,對多線程感興趣的同學(xué),可以參考下2021-04-04
iOS程序開發(fā)中設(shè)置UITableView的全屏分隔線的方法(不畫線)
ableView是app開發(fā)中常用到的控件,功能很強大,多用于數(shù)據(jù)的顯示。下面給大家介紹設(shè)置UITableView的全屏分隔線的兩種方法2016-04-04
iOS中使用JSPatch框架使Objective-C與JavaScript代碼交互
有了JSPatch,我們便可以在iOS App開發(fā)中令JavaScript代碼調(diào)用原生的Objective-C屬性和方法等,下面就來詳細看一下如何在iOS中使用JSPatch框架使Objective-C與JavaScript代碼交互2016-06-06

