QLPreviewController 全解-PDF文件圖片等簡單編輯

在 Swift 開發(fā)中,打開和編輯 PDF 的系統(tǒng)控制器通常是 QLPreviewController瓣距,它是 iOS 提供的一個通用文檔預覽控制器黔帕。通過 QLPreviewController,你可以打開和查看 PDF 文件蹈丸,甚至是其他類型的文檔(如 Word成黄、Excel 等)。

  1. 使用 QLPreviewController 打開 PDF 文件
    如果你只是想打開和查看 PDF 文件逻杖,可以使用 QLPreviewController 來實現(xiàn)奋岁。以下是打開 PDF 的代碼示例:

示例代碼(使用 QLPreviewController 打開 PDF):

import UIKit
import QuickLook

class ViewController: UIViewController, QLPreviewControllerDataSource, QLPreviewControllerDelegate {

var documentURL: URL?

override func viewDidLoad() {
super.viewDidLoad()

// 設置 PDF 文件路徑
if let pdfPath = Bundle.main.path(forResource: "sample", ofType: "pdf") {
documentURL = URL(fileURLWithPath: pdfPath)
}

// 創(chuàng)建并展示 QLPreviewController
let previewController = QLPreviewController()
previewController.dataSource = self
previewController.delegate = self
self.present(previewController, animated: true, completion: nil)
}

// QLPreviewControllerDataSource 方法,返回文檔的數(shù)量
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}

// 返回文檔的 URL
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return documentURL! as QLPreviewItem
}
}


   func previewControllerWillDismiss(_ controller: QLPreviewController) {
      print("previewControllerWillDismiss")
   }
   func previewControllerDidDismiss(_ controller: QLPreviewController) {
      print("previewControllerDidDismiss")
   }

   func previewController(_ controller: QLPreviewController, editingModeFor previewItem: any QLPreviewItem) -> QLPreviewItemEditingMode {
      return .createCopy
   }
   
   func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: any QLPreviewItem) -> Bool {
      return true
   }
   
   func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: any QLPreviewItem) {
      
   }
   
   func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: any QLPreviewItem, at modifiedContentsURL: URL) {
      
   }
   

QLPreviewControllerDataSource 協(xié)議是 QLPreviewController 用來獲取預覽內(nèi)容的數(shù)據(jù)源協(xié)議弧腥。它定義了兩個方法厦取,允許開發(fā)者提供要在預覽控制器中顯示的項目數(shù)量和具體內(nèi)容潮太。
下面是對該協(xié)議的詳細解釋:

  1. numberOfPreviewItems(in:)
    方法描述:該方法返回預覽控制器需要展示的項目數(shù)量管搪。預覽控制器將根據(jù)這個數(shù)量來顯示相應的內(nèi)容。
    參數(shù):
    controller:當前的 QLPreviewController 實例铡买,通常不需要在實現(xiàn)時使用此參數(shù)更鲁。
    返回值:返回一個整數(shù),表示預覽控制器應該顯示的項目數(shù)量奇钞。
    可用版本:iOS 4.0 及以上
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
    return items.count  // 返回預覽項的數(shù)量
}
  1. previewController(_:previewItemAt:)
    方法描述:該方法返回給定索引位置的預覽項澡为。返回的預覽項必須符合 QLPreviewItem 協(xié)議,該協(xié)議代表一個可以被預覽的對象(如文件景埃、圖片等)媒至。
    參數(shù):
    controller:當前的 QLPreviewController 實例,通常不需要在實現(xiàn)時使用此參數(shù)谷徙。
    index:需要返回的預覽項的索引拒啰。
    返回值:返回一個符合 QLPreviewItem 協(xié)議的對象,通常是一個包含文件路徑宇姚、URL 或本地資源的對象埂软。
    可用版本:iOS 4.0 及以上
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
    return items[index]  // 返回指定索引位置的預覽項
}

QLPreviewItem 協(xié)議
QLPreviewItem 協(xié)議是所有預覽項的基協(xié)議必尼,任何需要被 QLPreviewController 預覽的對象都需要遵循該協(xié)議。
QLPreviewItem 的常見實現(xiàn)類:
URL:可以是本地文件的路徑或者遠程文件的 URL册着。
文件對象:代表需要預覽的本地文件。


以下是 QLPreviewControllerDelegate 協(xié)議中各個方法的中文詳細說明:

1.previewControllerWillDismiss(_:)
可用版本:iOS 4.0+
描述:該方法在 QLPreviewController 即將關(guān)閉時被調(diào)用脾歧。您可以在此方法中執(zhí)行一些清理操作或準備工作甲捏。
QLPreviewController 關(guān)閉之前,可以執(zhí)行一些必要的操作鞭执,例如保存狀態(tài)或記錄事件摊鸡。

func previewControllerWillDismiss(_ controller: QLPreviewController) {
// 在控制器關(guān)閉前進行清理或狀態(tài)保存
}

  1. previewControllerDidDismiss(_:)
    可用版本:iOS 4.0+
    描述:該方法在 QLPreviewController 關(guān)閉后被調(diào)用绽媒。適用于執(zhí)行關(guān)閉后需要進行的后續(xù)操作。
    可以在此方法中執(zhí)行 UI 更新免猾、狀態(tài)恢復或通知其他部分的代碼是辕,表明預覽已經(jīng)關(guān)閉。
func previewControllerDidDismiss(_ controller: QLPreviewController) {
// 在控制器關(guān)閉后執(zhí)行后續(xù)操作
}

  1. previewController(_:shouldOpen:for:)
    可用版本:iOS 8.0+
    參數(shù):
    controller:請求打開 URL 的 QLPreviewController 實例猎提。
    url:用戶點擊的 URL获三。
    item:與 URL 關(guān)聯(lián)的 QLPreviewItem
    描述:當用戶點擊預覽中的 URL 時锨苏,這個方法會被調(diào)用疙教。它允許你決定是否允許 QLPreviewController 打開該 URL。返回 false 可以阻止 QLPreviewController 打開 URL伞租。
    如果需要攔截點擊事件贞谓,并根據(jù) URL 的類型來決定是否打開,可以返回 false 來阻止打開葵诈。比如裸弦,只允許打開特定的 URL。

func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: any QLPreviewItem) -> Bool {
// 攔截 URL作喘,根據(jù)需求決定是否打開
if url.scheme == "myapp" {
return false
}
return true
}

  1. previewController(_:frameFor:inSourceView:)
    可用版本:iOS 4.0+
    參數(shù):
    controllerQLPreviewController 實例理疙。
    item:正在預覽的 QLPreviewItem
    view:視圖指針泞坦,表示點擊的源視圖窖贤。
    描述:該方法在 QLPreviewController 即將切換到全屏或從全屏模式消失時被調(diào)用。它用于提供縮放動畫的初始框架贰锁。
    如果你想自定義縮放效果赃梧,可以通過返回一個 CGRect 來指定預覽項的初始位置和大小。

func previewController(_ controller: QLPreviewController, frameFor item: any QLPreviewItem, inSourceView view: AutoreleasingUnsafeMutablePointer<UIView?>) -> CGRect {
// 自定義縮放框架
return CGRect(x: 50, y: 50, width: 200, height: 200)
}

  1. previewController(_:transitionImageFor:contentRect:)
    可用版本:iOS 4.0+
    參數(shù):
    controllerQLPreviewController 實例豌熄。
    item:正在預覽的 QLPreviewItem授嘀。
    contentRect:指向矩形的指針,表示圖像中的實際內(nèi)容區(qū)域房轿。
    描述:該方法在預覽控制器切換到全屏或從全屏模式返回時被調(diào)用粤攒。它允許你提供一張圖像,在縮放過程中進行交叉淡入淡出動畫囱持,并且你可以指定圖像中的內(nèi)容矩形夯接。
    用于提供平滑的圖像過渡效果。你可以返回一個縮略圖或低分辨率圖像纷妆,用于在縮放時交叉淡入淡出盔几。
func previewController(_ controller: QLPreviewController, transitionImageFor item: any QLPreviewItem, contentRect: UnsafeMutablePointer<CGRect>) -> UIImage? {
return UIImage(named: "thumbnail_image") // 返回用于縮放過渡的縮略圖
}

  1. previewController(_:transitionViewFor:)
    可用版本:iOS 10.0+
    描述:該方法在 QLPreviewController 切換到全屏或從全屏模式返回時被調(diào)用。它允許你返回一個自定義視圖掩幢,用于過渡動畫逊拍。
    參數(shù):
    controllerQLPreviewController 實例上鞠。
    item:正在預覽的 QLPreviewItem

func previewController(_ controller: QLPreviewController, transitionViewFor item: any QLPreviewItem) -> UIView? {
let transitionView = UIView()
transitionView.backgroundColor = UIColor.blue
return transitionView // 自定義過渡視圖
}

  1. previewController(_:editingModeFor:)
    可用版本:iOS 13.0+
    描述:該方法在預覽控制器加載數(shù)據(jù)時被調(diào)用芯丧。它允許您指定如何處理編輯版本的預覽項芍阎,例如是否允許編輯。
    參數(shù):
    controllerQLPreviewController 實例缨恒。
    previewItem:正在預覽的 QLPreviewItem谴咸。
    返回值:
    返回一個表示如何處理編輯版本的 QLPreviewItemEditingMode 枚舉值。
    如果允許編輯骗露,可以返回 .updateContents 來啟用更新岭佳,或者返回其他值來指定不同的處理方式。
func previewController(_ controller: QLPreviewController, editingModeFor previewItem: any QLPreviewItem) -> QLPreviewItemEditingMode {
return .updateContents // 允許更新內(nèi)容
}

  1. previewController(_:didUpdateContentsOf:)
    方法描述:此方法會在預覽控制器成功更新并覆蓋文件內(nèi)容時被調(diào)用萧锉,表示用戶已經(jīng)對文件進行了修改并保存了更改珊随。
    參數(shù):
    controller: 當前的 QLPreviewController 實例。
    previewItem: 被修改內(nèi)容的 QLPreviewItem 對象柿隙,即正在編輯的文件項叶洞。
    功能:當用戶保存編輯后的文件時,QLPreviewController 會調(diào)用此方法优俘。特別地京办,這可能會多次調(diào)用掀序,因為每當用戶保存修改時帆焕,都會觸發(fā)該方法。
    使用場景:如果用戶在 QLPreviewController 中編輯了文件(如文本不恭、文檔等)叶雹,每次保存編輯后,都會調(diào)用此方法來通知數(shù)據(jù)源文件內(nèi)容已被更新换吧。

@available(iOS 13.0, *)
func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: any QLPreviewItem) {
// 處理文件內(nèi)容更新的邏輯
print("文件內(nèi)容已更新:\(previewItem)")
}

  1. previewController(_:didSaveEditedCopyOf:at:)
    方法描述:此方法會在用戶保存文件的編輯副本時被調(diào)用折晦。這個副本是一個臨時文件,可能是在編輯過程中生成的沾瓦,也可能是由于內(nèi)容未能直接覆蓋原始文件而創(chuàng)建的满着。
    參數(shù):
    controller: 當前的 QLPreviewController 實例。
    previewItem: 編輯過的原始文件項贯莺。
    modifiedContentsURL: 一個指向臨時文件的 URL风喇,該文件包含編輯后的內(nèi)容。
    功能:此方法會在用戶保存編輯副本時觸發(fā)缕探,并且返回的是一個指向修改后內(nèi)容的臨時文件的 URL魂莫。此方法在以下幾種情況下會被調(diào)用:
    如果 QLPreviewItemEditingModeCreateCopy 模式被使用(即用戶創(chuàng)建了文件的副本)。
    如果 QLPreviewItemEditingModeUpdateContents 模式被使用爹耗,但原始文件無法成功覆蓋耙考,此時返回的是臨時存儲的編輯副本谜喊。
    如果修改后的文件類型與原始文件類型不匹配(例如,編輯一個 PDF 文件后另存為圖片格式)倦始,此時返回的副本可能是不同類型的文件斗遏。
    使用場景:當用戶保存修改的副本時,例如文本編輯應用允許用戶修改文件并保存編輯副本鞋邑,或者當修改文件后無法直接覆蓋原始文件時最易,都會調(diào)用此方法。

@available(iOS 13.0, *)
func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: any QLPreviewItem, at modifiedContentsURL: URL) {
// 處理保存的副本
print("文件的編輯副本已保存:\(modifiedContentsURL)")
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炫狱,一起剝皮案震驚了整個濱河市藻懒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌视译,老刑警劉巖嬉荆,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酷含,居然都是意外死亡鄙早,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門椅亚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來限番,“玉大人,你說我怎么就攤上這事呀舔∶峙埃” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵媚赖,是天一觀的道長霜瘪。 經(jīng)常有香客問我,道長惧磺,這世上最難降的妖魔是什么颖对? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮磨隘,結(jié)果婚禮上缤底,老公的妹妹穿的比我還像新娘。我一直安慰自己番捂,他們只是感情好个唧,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著白嘁,像睡著了一般坑鱼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天鲁沥,我揣著相機與錄音呼股,去河邊找鬼。 笑死画恰,一個胖子當著我的面吹牛彭谁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播允扇,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼缠局,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了考润?” 一聲冷哼從身側(cè)響起狭园,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎糊治,沒想到半個月后唱矛,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡井辜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年绎谦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粥脚。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡窃肠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出刷允,到底是詐尸還是另有隱情冤留,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布恃锉,位于F島的核電站搀菩,受9級特大地震影響呕臂,放射性物質(zhì)發(fā)生泄漏破托。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一歧蒋、第九天 我趴在偏房一處隱蔽的房頂上張望土砂。 院中可真熱鬧,春花似錦谜洽、人聲如沸萝映。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽序臂。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奥秆,已是汗流浹背逊彭。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留构订,地道東北人侮叮。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像悼瘾,于是被迫代替她去往敵國和親囊榜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355