مساء الخير أقدم لكم استمرار المقالة "تنزيل وحفظ وعرض ملف PDF في Swift" ، كما وعد المؤلف - سنلقي نظرة فاحصة على PDFKit.
ظهر PDFKit في iOS 11 ، ولديه 3 ميزات رائعة أود الحديث عنها في عملية إنشاء تطبيق قارئ الكتب الإلكترونية:
ترقيم الصفحات ،
وعرض المحتوى ورمز الصفحة.
كل من يهمه الأمر ، مرحبا بك في القط


الترحيل والمخطط التفصيلي والصور المصغرةإنشاء PDFViewController مع حقن التهيئةعند إنشاء متغير
URL في PDFViewController ، جعلناه غير قابل للتغيير. هذا هو السبب في أنني اخترت
Initializer Injection بدلاً من
Property Injection أو
Method Injection .
المتغير الوحيد الذي يتم تنفيذه هو
pdfUrl ، والباقي:
المستند والمخطط التفصيلي ، يمكن الوصول إليهما من خلال نطاق الفصل المحلي ويمكن البدء به عبر
init () .
لا يتغير محتوى
pdfView ، لذلك قمت بتعيينه مع
المستند المتغير
وقمت بتهيئته أيضًا عبر
init () .
import UIKit import PDFKit class PDFViewController: UIViewController { private let pdfUrl: URL private let document: PDFDocument! private let outline: PDFOutline? private var pdfView = PDFView() init(pdfUrl: URL) { self.pdfUrl = pdfUrl self.document = PDFDocument(url: pdfUrl) self.outline = document.outlineRoot pdfView.document = document super.init(nibName: nil, bundle: nil) } ... override func viewDidLoad() { super.viewDidLoad() view.addSubview(pdfView) } }
import UIKit class ViewController: UIViewController { @IBAction func openPdfPressed(_ sender: Any) { guard let path = Bundle.main.url(forResource: "swift", withExtension: "pdf") else { print("failed to unwrap fileURL") return } let pdfViewController = PDFViewController(pdfUrl: path) present(pdfViewController, animated: true, completion: nil) } }
تعيين ترقيم الصفحات الأفقيالآن لدينا المحتوى في المستند ، الذي
كتبناه في
pdfView.document . من أجل التمرير الأفقي ، كما هو الحال في الكتاب ، تحتاج إلى إضافة العديد من الإعدادات إلى PDFView.
private func setupPDFView() { view.addSubview(pdfView) pdfView.displayDirection = .horizontal pdfView.usePageViewController(true) pdfView.pageBreakMargins = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) pdfView.autoScales = true }
أيقونات الصفحة لسهولة التنقليحتوي PDFKit على شيء مفيد بشكل مثير للدهشة مثل ThumbnailView. كل ما عليك القيام به هو تعيين
pdfView الخاص بنا إلى خاصية
thumbnailView.pdfView . هذا كل ما في الأمر! لا يوجد مفوضين أو إخطارات أو إعدادات أخرى.
private func setupThumbnailView() { thumbnailView.pdfView = pdfView thumbnailView.backgroundColor = UIColor(displayP3Red: 179/255, green: 179/255, blue: 179/255, alpha: 0.5) thumbnailView.layoutMode = .horizontal thumbnailView.thumbnailSize = CGSize(width: 80, height: 100) thumbnailView.contentInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) view.addSubview(thumbnailView) }
عرض المحتوى للملاحة الفصلللوصول إلى صفحة معينة ، نحتاج إلى نقل صفحة معينة (
PDFPage ) إلى
pdfView . لذلك نحن بحاجة إلى الخوض في التسلسل الهرمي للمحتوى (
المخطط التفصيلي ) في المستند (
المستند ) للوصول إلى الصفحة (
الصفحة ) المطلوبة.

أنا أستخدم
UITableViewController كنافذة منبثقة (
popOver ). لذلك ، أحتاج إلى:
- إنشاء بروتوكول. يجب أن يتبع UITableViewController هذا البروتوكول.
- أضف بعض طرق التفويض للوصول إلى pdfView في PDFViewController .
- استدعاء أسلوب المفوض عندما يحدد المستخدم خلية معينة.
import UIKit import PDFKit protocol OutlineDelegate: class { func goTo(page: PDFPage) } class OutlineTableViewController: UITableViewController { let outline: PDFOutline weak var delegate: OutlineDelegate? init(outline: PDFOutline, delegate: OutlineDelegate?) { self.outline = outline self.delegate = delegate super.init(nibName: nil, bundle: nil) } ... override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return outline.numberOfChildren } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell if let label = cell.textLabel, let title = outline.child(at: indexPath.row)?.label { label.text = String(title) } return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if let page = outline.child(at: indexPath.row)?.destination?.page { delegate?.goTo(page: page) } } }

الصيحة! لذلك قمنا بتطبيق الوظائف الرئيسية الثلاثة لـ PDFKit. لا تزال هناك بعض التفاصيل التافهة للواجهة ، ولكن في هذه المقالة لن نركز عليها. المشروع متاح للجميع.