在 Swift 開發(fā)中,打開和編輯 PDF 的系統(tǒng)控制器通常是 QLPreviewController
瓣距,它是 iOS 提供的一個通用文檔預覽控制器黔帕。通過 QLPreviewController
,你可以打開和查看 PDF 文件蹈丸,甚至是其他類型的文檔(如 Word成黄、Excel 等)。
- 使用
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é)議的詳細解釋:
-
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ù)量
}
-
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)保存
}
-
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ù)操作
}
-
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
}
-
previewController(_:frameFor:inSourceView:)
可用版本:iOS 4.0+
參數(shù):
controller
:QLPreviewController
實例理疙。
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)
}
-
previewController(_:transitionImageFor:contentRect:)
可用版本:iOS 4.0+
參數(shù):
controller
:QLPreviewController
實例豌熄。
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") // 返回用于縮放過渡的縮略圖
}
-
previewController(_:transitionViewFor:)
可用版本:iOS 10.0+
描述:該方法在QLPreviewController
切換到全屏或從全屏模式返回時被調(diào)用。它允許你返回一個自定義視圖掩幢,用于過渡動畫逊拍。
參數(shù):
controller
:QLPreviewController
實例上鞠。
item
:正在預覽的QLPreviewItem
。
func previewController(_ controller: QLPreviewController, transitionViewFor item: any QLPreviewItem) -> UIView? {
let transitionView = UIView()
transitionView.backgroundColor = UIColor.blue
return transitionView // 自定義過渡視圖
}
-
previewController(_:editingModeFor:)
可用版本:iOS 13.0+
描述:該方法在預覽控制器加載數(shù)據(jù)時被調(diào)用芯丧。它允許您指定如何處理編輯版本的預覽項芍阎,例如是否允許編輯。
參數(shù):
controller
:QLPreviewController
實例缨恒。
previewItem
:正在預覽的QLPreviewItem
谴咸。
返回值:
返回一個表示如何處理編輯版本的QLPreviewItemEditingMode
枚舉值。
如果允許編輯骗露,可以返回 .updateContents 來啟用更新岭佳,或者返回其他值來指定不同的處理方式。
func previewController(_ controller: QLPreviewController, editingModeFor previewItem: any QLPreviewItem) -> QLPreviewItemEditingMode {
return .updateContents // 允許更新內(nèi)容
}
-
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)")
}
-
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)")
}