Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/ios.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarino Faggiana <ios@nextcloud.com>2022-05-04 15:46:59 +0300
committerGitHub <noreply@github.com>2022-05-04 15:46:59 +0300
commit43b97986c21eb04ff352d93e1c19f7a2ea9257d4 (patch)
tree43a908c665b72fd0d11b2a30ce2f4c354535989b
parent9a92d1fb43bc4ea1d1b88f89af62d5301ee4c454 (diff)
parentb0d1644c4c9ef87f18327ebd2206c07dd17af9e2 (diff)
Merge pull request #1981 from nextcloud/improved/pdfview
Improved PDF Viewer
-rw-r--r--Nextcloud.xcodeproj/project.pbxproj17
-rw-r--r--iOSClient/Data/NCDatabase.swift5
-rw-r--r--iOSClient/Data/NCManageDatabase.swift32
-rw-r--r--iOSClient/Menu/NCViewer+Menu.swift25
-rw-r--r--iOSClient/NCGlobal.swift7
-rw-r--r--iOSClient/Supporting Files/en.lproj/Localizable.strings3
-rw-r--r--iOSClient/Utility/CCUtility.h3
-rw-r--r--iOSClient/Utility/CCUtility.m17
-rw-r--r--iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift324
9 files changed, 305 insertions, 128 deletions
diff --git a/Nextcloud.xcodeproj/project.pbxproj b/Nextcloud.xcodeproj/project.pbxproj
index 666f1af0c..a52626815 100644
--- a/Nextcloud.xcodeproj/project.pbxproj
+++ b/Nextcloud.xcodeproj/project.pbxproj
@@ -207,6 +207,7 @@
F74E7720277A2EF40013B958 /* XLForm in Frameworks */ = {isa = PBXBuildFile; productRef = F74E771F277A2EF40013B958 /* XLForm */; };
F7501C322212E57500FB1415 /* NCMedia.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F7501C302212E57400FB1415 /* NCMedia.storyboard */; };
F7501C332212E57500FB1415 /* NCMedia.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7501C312212E57400FB1415 /* NCMedia.swift */; };
+ F753BA93281FD8020015BFB6 /* EasyTipView in Frameworks */ = {isa = PBXBuildFile; productRef = F753BA92281FD8020015BFB6 /* EasyTipView */; };
F755BD9B20594AC7008C5FBB /* NCService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F755BD9A20594AC7008C5FBB /* NCService.swift */; };
F7581D1A25EFDA61004DC699 /* NCLoginWeb+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7581D1925EFDA60004DC699 /* NCLoginWeb+Menu.swift */; };
F7581D2425EFDDDF004DC699 /* NCMedia+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7581D2325EFDDDF004DC699 /* NCMedia+Menu.swift */; };
@@ -1016,6 +1017,7 @@
F758A01227A7F03E0069468B /* JGProgressHUD in Frameworks */,
F76DA96F277B78AE0082465B /* TLPhotoPicker in Frameworks */,
F76DA966277B76F30082465B /* UICKeyChainStore in Frameworks */,
+ F753BA93281FD8020015BFB6 /* EasyTipView in Frameworks */,
F76DA95B277B75A90082465B /* TOPasscodeViewController.xcframework in Frameworks */,
F76DA963277B760E0082465B /* Queuer in Frameworks */,
F75E57BD25BF0EC1002B72C2 /* SVGKit in Frameworks */,
@@ -2085,6 +2087,7 @@
F7233B3927835FA400F40A43 /* ChromaColorPicker */,
F7BB7E4627A18C56009B9F29 /* Parchment */,
F758A01127A7F03E0069468B /* JGProgressHUD */,
+ F753BA92281FD8020015BFB6 /* EasyTipView */,
);
productName = "Crypto Cloud";
productReference = F7CE8AFA1DC1F8D8009CAE48 /* Nextcloud.app */;
@@ -2212,6 +2215,7 @@
F7233B3827835FA300F40A43 /* XCRemoteSwiftPackageReference "ChromaColorPicker" */,
F7BB7E4527A18C56009B9F29 /* XCRemoteSwiftPackageReference "Parchment" */,
F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */,
+ F753BA91281FD8010015BFB6 /* XCRemoteSwiftPackageReference "EasyTipView" */,
);
productRefGroup = F7F67B9F1A24D27800EE80DA;
projectDirPath = "";
@@ -3209,6 +3213,14 @@
minimumVersion = 4.0.0;
};
};
+ F753BA91281FD8010015BFB6 /* XCRemoteSwiftPackageReference "EasyTipView" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/marinofaggiana/EasyTipView";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 2.0.0;
+ };
+ };
F75E57A725BF0D61002B72C2 /* XCRemoteSwiftPackageReference "SVGKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SVGKit/SVGKit.git";
@@ -3393,6 +3405,11 @@
package = F74E771E277A2EF40013B958 /* XCRemoteSwiftPackageReference "XLForm" */;
productName = XLForm;
};
+ F753BA92281FD8020015BFB6 /* EasyTipView */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = F753BA91281FD8010015BFB6 /* XCRemoteSwiftPackageReference "EasyTipView" */;
+ productName = EasyTipView;
+ };
F758A01127A7F03E0069468B /* JGProgressHUD */ = {
isa = XCSwiftPackageProductDependency;
package = F72CD01027A7E92400E59476 /* XCRemoteSwiftPackageReference "JGProgressHUD" */;
diff --git a/iOSClient/Data/NCDatabase.swift b/iOSClient/Data/NCDatabase.swift
index 948cb78c7..d2cd149ac 100644
--- a/iOSClient/Data/NCDatabase.swift
+++ b/iOSClient/Data/NCDatabase.swift
@@ -493,6 +493,11 @@ class tableTag: Object {
}
}
+class tableTip: Object {
+
+ @Persisted(primaryKey: true) var tipName = ""
+}
+
class tableTrash: Object {
@objc dynamic var account = ""
diff --git a/iOSClient/Data/NCManageDatabase.swift b/iOSClient/Data/NCManageDatabase.swift
index 1cc04ca60..39033459a 100644
--- a/iOSClient/Data/NCManageDatabase.swift
+++ b/iOSClient/Data/NCManageDatabase.swift
@@ -245,6 +245,7 @@ class NCManageDatabase: NSObject {
self.clearTable(tablePhotoLibrary.self, account: account)
self.clearTable(tableShare.self, account: account)
self.clearTable(tableTag.self, account: account)
+ self.clearTable(tableTip.self)
self.clearTable(tableTrash.self, account: account)
self.clearTable(tableUserStatus.self, account: account)
self.clearTable(tableVideo.self, account: account)
@@ -1547,6 +1548,37 @@ class NCManageDatabase: NSObject {
}
// MARK: -
+ // MARK: Table Tip
+
+ @objc func tipExists(_ tipName: String) -> Bool {
+
+ let realm = try! Realm()
+
+ guard (realm.objects(tableTip.self).where {
+ $0.tipName == tipName
+ }.first) == nil else {
+ return true
+ }
+
+ return false
+ }
+
+ @objc func addTip(_ tipName: String) {
+
+ let realm = try! Realm()
+
+ do {
+ try realm.safeWrite {
+ let addObject = tableTip()
+ addObject.tipName = tipName
+ realm.add(addObject, update: .all)
+ }
+ } catch let error {
+ NCCommunicationCommon.shared.writeLog("Could not write to database: \(error)")
+ }
+ }
+
+ // MARK: -
// MARK: Table Trash
@objc func addTrash(account: String, items: [NCCommunicationTrash]) {
diff --git a/iOSClient/Menu/NCViewer+Menu.swift b/iOSClient/Menu/NCViewer+Menu.swift
index e85354bce..fb49825fe 100644
--- a/iOSClient/Menu/NCViewer+Menu.swift
+++ b/iOSClient/Menu/NCViewer+Menu.swift
@@ -226,31 +226,6 @@ extension NCViewer {
)
)
- var title = ""
- var icon = UIImage()
-
- if CCUtility.getPDFDisplayDirection() == .horizontal {
- title = NSLocalizedString("_pdf_vertical_", comment: "")
- icon = UIImage(named: "pdf-vertical")!.image(color: NCBrandColor.shared.gray, size: 50)
- } else {
- title = NSLocalizedString("_pdf_horizontal_", comment: "")
- icon = UIImage(named: "pdf-horizontal")!.image(color: NCBrandColor.shared.gray, size: 50)
- }
-
- actions.append(
- NCMenuAction(
- title: title,
- icon: icon,
- action: { _ in
- if CCUtility.getPDFDisplayDirection() == .horizontal {
- NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMenuPDFDisplayDirection, userInfo: ["direction": PDFDisplayDirection.vertical])
- } else {
- NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterMenuPDFDisplayDirection, userInfo: ["direction": PDFDisplayDirection.horizontal])
- }
- }
- )
- )
-
actions.append(
NCMenuAction(
title: NSLocalizedString("_go_to_page_", comment: ""),
diff --git a/iOSClient/NCGlobal.swift b/iOSClient/NCGlobal.swift
index 8fa81b169..a943207e1 100644
--- a/iOSClient/NCGlobal.swift
+++ b/iOSClient/NCGlobal.swift
@@ -112,7 +112,7 @@ class NCGlobal: NSObject {
// Database Realm
//
let databaseDefault = "nextcloud.realm"
- let databaseSchemaVersion: UInt64 = 217
+ let databaseSchemaVersion: UInt64 = 218
// Intro selector
//
@@ -344,7 +344,6 @@ class NCGlobal: NSObject {
let notificationCenterFavoriteFile = "favoriteFile" // userInfo: ocId
let notificationCenterMenuSearchTextPDF = "menuSearchTextPDF"
- let notificationCenterMenuPDFDisplayDirection = "menuPDFDisplayDirection" // userInfo: direction
let notificationCenterMenuGotToPageInPDF = "menuGotToPageInPDF"
let notificationCenterMenuDetailClose = "menuDetailClose"
@@ -360,4 +359,8 @@ class NCGlobal: NSObject {
let notificationCenterReloadMediaPage = "reloadMediaPage"
let notificationCenterPlayMedia = "playMedia"
let notificationCenterPauseMedia = "pauseMedia"
+
+ // Tip
+ //
+ let tipNCViewerPDFThumbnail = "tipncviewerpdfthumbnail"
}
diff --git a/iOSClient/Supporting Files/en.lproj/Localizable.strings b/iOSClient/Supporting Files/en.lproj/Localizable.strings
index 77165a34b..0709a71d9 100644
--- a/iOSClient/Supporting Files/en.lproj/Localizable.strings
+++ b/iOSClient/Supporting Files/en.lproj/Localizable.strings
@@ -857,4 +857,5 @@
"_subtitle_not_found_" = "Subtitle not found";
"_disable_" = "Disable";
"_subtitle_not_dowloaded_" = "There are subtitles not downloaded locally";
-
+// Tip
+"_tip_pdf_thumbnails_" = "Swipe left from the right edge of the screen to show the thumbnails.";
diff --git a/iOSClient/Utility/CCUtility.h b/iOSClient/Utility/CCUtility.h
index e2aee0e86..3d5eee7e8 100644
--- a/iOSClient/Utility/CCUtility.h
+++ b/iOSClient/Utility/CCUtility.h
@@ -180,9 +180,6 @@
+ (NSInteger)getCleanUpDay;
+ (void)setCleanUpDay:(NSInteger)days;
-+ (PDFDisplayDirection)getPDFDisplayDirection;
-+ (void)setPDFDisplayDirection:(PDFDisplayDirection)direction;
-
+ (BOOL)getPrivacyScreenEnabled;
+ (void)setPrivacyScreenEnabled:(BOOL)set;
diff --git a/iOSClient/Utility/CCUtility.m b/iOSClient/Utility/CCUtility.m
index 0a2a97a6f..df4325707 100644
--- a/iOSClient/Utility/CCUtility.m
+++ b/iOSClient/Utility/CCUtility.m
@@ -715,23 +715,6 @@
[UICKeyChainStore setString:daysString forKey:@"cleanUpDay" service:NCGlobal.shared.serviceShareKeyChain];
}
-+ (PDFDisplayDirection)getPDFDisplayDirection
-{
- NSString *direction = [UICKeyChainStore stringForKey:@"PDFDisplayDirection" service:NCGlobal.shared.serviceShareKeyChain];
-
- if (direction == nil) {
- return kPDFDisplayDirectionVertical;
- } else {
- return [direction integerValue];
- }
-}
-
-+ (void)setPDFDisplayDirection:(PDFDisplayDirection)direction
-{
- NSString *directionString = [@(direction) stringValue];
- [UICKeyChainStore setString:directionString forKey:@"PDFDisplayDirection" service:NCGlobal.shared.serviceShareKeyChain];
-}
-
+ (BOOL)getPrivacyScreenEnabled
{
NSString *valueString = [UICKeyChainStore stringForKey:@"privacyScreen" service:NCGlobal.shared.serviceShareKeyChain];
diff --git a/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift b/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift
index f00dabc1e..3e77c598f 100644
--- a/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift
+++ b/iOSClient/Viewer/NCViewerPDF/NCViewerPDF.swift
@@ -23,21 +23,34 @@
import UIKit
import PDFKit
+import EasyTipView
-class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
+class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate, UIGestureRecognizerDelegate {
- let appDelegate = UIApplication.shared.delegate as! AppDelegate
var metadata = tableMetadata()
var imageIcon: UIImage?
+ private var filePath = ""
+
private var pdfView = PDFView()
- private var thumbnailViewHeight: CGFloat = 40
+ private var pdfThumbnailScrollView = UIScrollView()
private var pdfThumbnailView = PDFThumbnailView()
private var pdfDocument: PDFDocument?
private let pageView = UIView()
private let pageViewLabel = UILabel()
+ private var tipView: EasyTipView?
+
+ private let thumbnailViewHeight: CGFloat = 70
+ private let thumbnailViewWidth: CGFloat = 80
+ private let thumbnailPadding: CGFloat = 2
+ private let animateDuration: TimeInterval = 0.3
+
+ private var defaultBackgroundColor: UIColor = .clear
+
+ private var pdfThumbnailScrollViewTopAnchor: NSLayoutConstraint?
+ private var pdfThumbnailScrollViewTrailingAnchor: NSLayoutConstraint?
+ private var pdfThumbnailScrollViewWidthAnchor: NSLayoutConstraint?
private var pageViewWidthAnchor: NSLayoutConstraint?
- private var filePath = ""
// MARK: - View Life Cycle
@@ -48,80 +61,129 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
override func viewDidLoad() {
filePath = CCUtility.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileNameView)!
-
- pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
pdfDocument = PDFDocument(url: URL(fileURLWithPath: filePath))
+ let pageCount = CGFloat(pdfDocument?.pageCount ?? 0)
+ defaultBackgroundColor = pdfView.backgroundColor
+ view.backgroundColor = defaultBackgroundColor
+
+ navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "more")!.image(color: NCBrandColor.shared.label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
+ navigationItem.title = metadata.fileNameView
+
+ // PDF VIEW
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
+ } else {
+ pdfView = PDFView(frame: CGRect(x: 0, y: 0, width: view.frame.width-thumbnailViewWidth, height: view.frame.height))
+ }
+ pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleLeftMargin]
pdfView.document = pdfDocument
- pdfView.backgroundColor = NCBrandColor.shared.systemBackground
- pdfView.displayMode = .singlePageContinuous
pdfView.autoScales = true
- pdfView.displayDirection = CCUtility.getPDFDisplayDirection()
- pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleTopMargin, .flexibleBottomMargin]
- pdfView.usePageViewController(true, withViewOptions: nil)
-
+ pdfView.displayMode = .singlePageContinuous
+ pdfView.displayDirection = .vertical
+ pdfView.maxScaleFactor = 4.0
+ pdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit
view.addSubview(pdfView)
+ // PDF THUMBNAIL
+
+ pdfThumbnailScrollView.translatesAutoresizingMaskIntoConstraints = false
+ pdfThumbnailScrollView.backgroundColor = defaultBackgroundColor
+ pdfThumbnailScrollView.showsVerticalScrollIndicator = false
+ view.addSubview(pdfThumbnailScrollView)
+
+ pdfThumbnailScrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
+ pdfThumbnailScrollViewTopAnchor = pdfThumbnailScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
+ pdfThumbnailScrollViewTopAnchor?.isActive = true
+ pdfThumbnailScrollViewTrailingAnchor = pdfThumbnailScrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
+ pdfThumbnailScrollViewTrailingAnchor?.isActive = true
+ pdfThumbnailScrollViewWidthAnchor = pdfThumbnailScrollView.widthAnchor.constraint(equalToConstant: thumbnailViewWidth)
+ pdfThumbnailScrollViewWidthAnchor?.isActive = true
+
pdfThumbnailView.translatesAutoresizingMaskIntoConstraints = false
pdfThumbnailView.pdfView = pdfView
- pdfThumbnailView.layoutMode = .horizontal
- pdfThumbnailView.thumbnailSize = CGSize(width: 40, height: thumbnailViewHeight)
+ pdfThumbnailView.layoutMode = .vertical
+ pdfThumbnailView.thumbnailSize = CGSize(width: thumbnailViewHeight, height: thumbnailViewHeight)
pdfThumbnailView.backgroundColor = .clear
- // pdfThumbnailView.layer.shadowOffset.height = -5
- // pdfThumbnailView.layer.shadowOpacity = 0.25
-
- view.addSubview(pdfThumbnailView)
-
- pdfThumbnailView.heightAnchor.constraint(equalToConstant: thumbnailViewHeight).isActive = true
- pdfThumbnailView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
- pdfThumbnailView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
- pdfThumbnailView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ self.pdfThumbnailScrollView.isHidden = true
+ } else {
+ self.pdfThumbnailScrollView.isHidden = false
+ }
+ pdfThumbnailScrollView.addSubview(pdfThumbnailView)
+
+ NSLayoutConstraint.activate([
+ pdfThumbnailView.topAnchor.constraint(equalTo: pdfThumbnailScrollView.topAnchor),
+ pdfThumbnailView.bottomAnchor.constraint(equalTo: pdfThumbnailScrollView.bottomAnchor),
+ pdfThumbnailView.leadingAnchor.constraint(equalTo: pdfThumbnailScrollView.leadingAnchor),
+ pdfThumbnailView.leadingAnchor.constraint(equalTo: pdfThumbnailScrollView.trailingAnchor, constant: (UIApplication.shared.keyWindow?.safeAreaInsets.left ?? 0)),
+ pdfThumbnailView.widthAnchor.constraint(equalToConstant: thumbnailViewWidth)
+ ])
+ let contentViewCenterY = pdfThumbnailView.centerYAnchor.constraint(equalTo: pdfThumbnailScrollView.centerYAnchor)
+ contentViewCenterY.priority = .defaultLow
+ let contentViewHeight = pdfThumbnailView.heightAnchor.constraint(equalToConstant: CGFloat(pageCount * thumbnailViewHeight) + CGFloat(pageCount * thumbnailPadding) + 30)
+ contentViewHeight.priority = .defaultLow
+ NSLayoutConstraint.activate([
+ contentViewCenterY,
+ contentViewHeight
+ ])
+
+ // COUNTER PDF PAGE VIEW
pageView.translatesAutoresizingMaskIntoConstraints = false
pageView.layer.cornerRadius = 10
pageView.backgroundColor = NCBrandColor.shared.systemBackground.withAlphaComponent(
UIAccessibility.isReduceTransparencyEnabled ? 1 : 0.5
)
-
view.addSubview(pageView)
- pageView.heightAnchor.constraint(equalToConstant: 30).isActive = true
+ NSLayoutConstraint.activate([
+ pageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
+ pageView.heightAnchor.constraint(equalToConstant: 30),
+ pageView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 10)
+ ])
pageViewWidthAnchor = pageView.widthAnchor.constraint(equalToConstant: 10)
pageViewWidthAnchor?.isActive = true
- pageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 4).isActive = true
- pageView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 7).isActive = true
pageViewLabel.translatesAutoresizingMaskIntoConstraints = false
pageViewLabel.textAlignment = .center
pageViewLabel.textColor = NCBrandColor.shared.label
-
pageView.addSubview(pageViewLabel)
- pageViewLabel.leftAnchor.constraint(equalTo: pageView.leftAnchor).isActive = true
- pageViewLabel.rightAnchor.constraint(equalTo: pageView.rightAnchor).isActive = true
- pageViewLabel.topAnchor.constraint(equalTo: pageView.topAnchor).isActive = true
- pageViewLabel.bottomAnchor.constraint(equalTo: pageView.bottomAnchor).isActive = true
+ NSLayoutConstraint.activate([
+ pageViewLabel.topAnchor.constraint(equalTo: pageView.topAnchor),
+ pageViewLabel.leftAnchor.constraint(equalTo: pageView.leftAnchor),
+ pageViewLabel.rightAnchor.constraint(equalTo: pageView.rightAnchor),
+ pageViewLabel.bottomAnchor.constraint(equalTo: pageView.bottomAnchor)
+ ])
- pdfView.backgroundColor = NCBrandColor.shared.systemBackground
- pdfView.layoutIfNeeded()
- handlePageChange()
+ // GESTURE
- let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap(_:)))
- tapGesture.numberOfTapsRequired = 1
- pdfView.addGestureRecognizer(tapGesture)
+ let tapPdfView = UITapGestureRecognizer(target: self, action: #selector(tapPdfView))
+ tapPdfView.numberOfTapsRequired = 1
+ pdfView.addGestureRecognizer(tapPdfView)
// recognize single / double tap
for gesture in pdfView.gestureRecognizers! {
- tapGesture.require(toFail: gesture)
+ tapPdfView.require(toFail: gesture)
}
- }
- override func viewWillAppear(_ animated: Bool) {
- super.viewWillAppear(animated)
+ let swipePdfView = UISwipeGestureRecognizer(target: self, action: #selector(gestureClosePdfThumbnail))
+ swipePdfView.direction = .right
+ pdfView.addGestureRecognizer(swipePdfView)
- appDelegate.activeViewController = self
+ let swipePdfThumbnailScrollView = UISwipeGestureRecognizer(target: self, action: #selector(gestureClosePdfThumbnail))
+ swipePdfThumbnailScrollView.direction = .right
+ pdfThumbnailScrollView.addGestureRecognizer(swipePdfThumbnailScrollView)
+
+ let edgePdfView = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(gestureOpenPdfThumbnail))
+ edgePdfView.edges = .right
+ pdfView.addGestureRecognizer(edgePdfView)
+
+ let edgeView = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(gestureOpenPdfThumbnail))
+ edgeView.edges = .right
+ view.addGestureRecognizer(edgeView)
- //
NotificationCenter.default.addObserver(self, selector: #selector(favoriteFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterFavoriteFile), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(deleteFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(renameFile(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterRenameFile), object: nil)
@@ -130,19 +192,62 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
NotificationCenter.default.addObserver(self, selector: #selector(viewUnload), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuDetailClose), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(searchText), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuSearchTextPDF), object: nil)
- NotificationCenter.default.addObserver(self, selector: #selector(direction(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuPDFDisplayDirection), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(goToPage), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuGotToPageInPDF), object: nil)
+
NotificationCenter.default.addObserver(self, selector: #selector(handlePageChange), name: Notification.Name.PDFViewPageChanged, object: nil)
- //
- navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "more")!.image(color: NCBrandColor.shared.label, size: 25), style: .plain, target: self, action: #selector(self.openMenuMore))
+ // Tip
+ if UIDevice.current.userInterfaceIdiom == .phone && !NCManageDatabase.shared.tipExists(NCGlobal.shared.tipNCViewerPDFThumbnail){
- navigationController?.navigationBar.prefersLargeTitles = true
- navigationItem.title = metadata.fileNameView
+ var preferences = EasyTipView.Preferences()
+ preferences.drawing.foregroundColor = NCBrandColor.shared.brandText
+ preferences.drawing.backgroundColor = NCBrandColor.shared.customer
+ preferences.drawing.textAlignment = .left
+ preferences.drawing.arrowPosition = .right
+ preferences.drawing.cornerRadius = 10
+
+ preferences.positioning.bubbleInsets.right = UIApplication.shared.keyWindow?.safeAreaInsets.right ?? 0
+
+ preferences.animating.dismissTransform = CGAffineTransform(translationX: 0, y: 100)
+ preferences.animating.showInitialTransform = CGAffineTransform(translationX: 0, y: -100)
+ preferences.animating.showInitialAlpha = 0
+ preferences.animating.showDuration = 1.5
+ preferences.animating.dismissDuration = 1.5
+
+ tipView = EasyTipView(text: NSLocalizedString("_tip_pdf_thumbnails_", comment: ""), preferences: preferences, delegate: self)
+ }
+
+ setConstraints()
+ handlePageChange()
+ }
+
+ override func viewDidAppear(_ animated: Bool) {
+ super.viewDidAppear(animated)
+
+ self.tipView?.show(forView: self.pdfThumbnailScrollView, withinSuperview: self.view)
}
- override func viewWillDisappear(_ animated: Bool) {
- super.viewWillDisappear(animated)
+ @objc func viewUnload() {
+
+ navigationController?.popViewController(animated: true)
+ }
+
+ override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
+ super.viewWillTransition(to: size, with: coordinator)
+
+ coordinator.animate(alongsideTransition: { context in
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ // Close
+ self.tipView?.dismiss()
+ self.pdfThumbnailScrollViewTrailingAnchor?.constant = self.thumbnailViewWidth + (UIApplication.shared.keyWindow?.safeAreaInsets.right ?? 0)
+ self.pdfThumbnailScrollView.isHidden = true
+ }
+ }, completion: { context in
+ self.setConstraints()
+ })
+ }
+
+ deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterFavoriteFile), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterDeleteFile), object: nil)
@@ -152,17 +257,11 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuDetailClose), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuSearchTextPDF), object: nil)
- NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuPDFDisplayDirection), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterMenuGotToPageInPDF), object: nil)
NotificationCenter.default.removeObserver(self, name: Notification.Name.PDFViewPageChanged, object: nil)
}
- @objc func viewUnload() {
-
- navigationController?.popViewController(animated: true)
- }
-
// MARK: - NotificationCenter
@objc func uploadedFile(_ notification: NSNotification) {
@@ -236,17 +335,6 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
self.present(navigaionController, animated: true)
}
- @objc func direction(_ notification: NSNotification) {
-
- if let userInfo = notification.userInfo as NSDictionary? {
- if let direction = userInfo["direction"] as? PDFDisplayDirection {
- pdfView.displayDirection = direction
- CCUtility.setPDFDisplayDirection(direction)
- handlePageChange()
- }
- }
- }
-
@objc func goToPage() {
guard let pdfDocument = pdfView.document else { return }
@@ -272,45 +360,112 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
// MARK: - Action
@objc func openMenuMore() {
+
if imageIcon == nil { imageIcon = UIImage(named: "file_pdf") }
NCViewer.shared.toggleMenu(viewController: self, metadata: metadata, webView: false, imageIcon: imageIcon)
}
// MARK: - Gesture Recognizer
- @objc func didTap(_ recognizer: UITapGestureRecognizer) {
+ @objc func tapPdfView(_ recognizer: UITapGestureRecognizer) {
- if navigationController?.isNavigationBarHidden ?? false {
+ pdfThumbnailScrollViewTopAnchor?.isActive = false
- navigationController?.setNavigationBarHidden(false, animated: false)
- pdfThumbnailView.isHidden = false
- pdfView.backgroundColor = NCBrandColor.shared.systemBackground
+ if navigationController?.isNavigationBarHidden ?? false {
+ navigationController?.setNavigationBarHidden(false, animated: true)
+ pdfThumbnailScrollViewTopAnchor = pdfThumbnailScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
} else {
+ navigationController?.setNavigationBarHidden(true, animated: true)
+ pdfThumbnailScrollViewTopAnchor = pdfThumbnailScrollView.topAnchor.constraint(equalTo: view.topAnchor)
+ }
+
+ pdfThumbnailScrollViewTopAnchor?.isActive = true
+
+ handlePageChange()
+ }
- let point = recognizer.location(in: pdfView)
- if point.y > pdfView.frame.height - thumbnailViewHeight { return }
+ @objc func gestureOpenPdfThumbnail(_ recognizer: UIScreenEdgePanGestureRecognizer) {
- navigationController?.setNavigationBarHidden(true, animated: false)
- pdfThumbnailView.isHidden = true
- pdfView.backgroundColor = .black
+ if UIDevice.current.userInterfaceIdiom == .phone && self.pdfThumbnailScrollView.isHidden {
+ if let tipView = self.tipView {
+ tipView.dismiss()
+ NCManageDatabase.shared.addTip(NCGlobal.shared.tipNCViewerPDFThumbnail)
+ self.tipView = nil
+ }
+ self.pdfThumbnailScrollView.isHidden = false
+ self.pdfThumbnailScrollViewWidthAnchor?.constant = thumbnailViewWidth + (UIApplication.shared.keyWindow?.safeAreaInsets.right ?? 0)
+ UIView.animate(withDuration: animateDuration, animations: {
+ self.pdfThumbnailScrollViewTrailingAnchor?.constant = 0
+ self.view.layoutIfNeeded()
+ })
}
+ }
- handlePageChange()
+ @objc func gestureClosePdfThumbnail(_ recognizer: UIScreenEdgePanGestureRecognizer) {
+
+ if recognizer.state == .recognized && UIDevice.current.userInterfaceIdiom == .phone && !self.pdfThumbnailScrollView.isHidden {
+ UIView.animate(withDuration: animateDuration) {
+ self.pdfThumbnailScrollViewTrailingAnchor?.constant = self.thumbnailViewWidth + (UIApplication.shared.keyWindow?.safeAreaInsets.right ?? 0)
+ self.view.layoutIfNeeded()
+ } completion: { _ in
+ self.pdfThumbnailScrollView.isHidden = true
+ }
+ }
}
// MARK: -
+ func setConstraints() {
+
+ let widthThumbnail = thumbnailViewWidth + (UIApplication.shared.keyWindow?.safeAreaInsets.right ?? 0)
+
+ UIView.animate(withDuration: animateDuration, animations: {
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ // Close
+ self.pdfThumbnailScrollView.isHidden = true
+ self.pdfThumbnailScrollViewTrailingAnchor?.constant = widthThumbnail
+ self.pdfThumbnailScrollViewWidthAnchor?.constant = widthThumbnail
+ } else {
+ // Open
+ self.pdfThumbnailScrollViewTrailingAnchor?.constant = 0
+ self.pdfThumbnailScrollViewWidthAnchor?.constant = widthThumbnail
+ }
+ self.view.layoutIfNeeded()
+ self.pdfView.autoScales = true
+ })
+ }
+
@objc func handlePageChange() {
guard let curPage = pdfView.currentPage?.pageRef?.pageNumber else { pageView.alpha = 0; return }
guard let totalPages = pdfView.document?.pageCount else { return }
+ let visibleRect = CGRect(x: pdfThumbnailScrollView.contentOffset.x, y: pdfThumbnailScrollView.contentOffset.y, width: pdfThumbnailScrollView.bounds.size.width, height: pdfThumbnailScrollView.bounds.size.height)
+ let centerPoint = CGPoint(x: visibleRect.size.width/2, y: visibleRect.size.height/2)
+ let currentPageY = CGFloat(curPage) * thumbnailViewHeight + CGFloat(curPage) * thumbnailPadding
+ var gotoY = currentPageY - centerPoint.y
+
+ let startY = visibleRect.origin.y < 0 ? 0 : (visibleRect.origin.y + thumbnailViewHeight)
+ let endY = visibleRect.origin.y + visibleRect.height
+
+ if currentPageY < startY {
+ if gotoY < 0 { gotoY = 0 }
+ pdfThumbnailScrollView.setContentOffset(CGPoint(x: 0, y: gotoY), animated: true)
+ } else if currentPageY > endY {
+ if gotoY > pdfThumbnailView.frame.height - visibleRect.height {
+ gotoY = pdfThumbnailView.frame.height - visibleRect.height
+ }
+ pdfThumbnailScrollView.setContentOffset(CGPoint(x: 0, y: gotoY), animated: true)
+ } else {
+ print("visible")
+ }
+
pageView.alpha = 1
pageViewLabel.text = String(curPage) + " " + NSLocalizedString("_of_", comment: "") + " " + String(totalPages)
pageViewWidthAnchor?.constant = pageViewLabel.intrinsicContentSize.width + 10
- UIView.animate(withDuration: 1.0, delay: 3.0, animations: {
+ UIView.animate(withDuration: 1.0, delay: 2.5, animations: {
self.pageView.alpha = 0
})
}
@@ -341,3 +496,12 @@ class NCViewerPDF: UIViewController, NCViewerPDFSearchDelegate {
}
}
}
+
+extension NCViewerPDF: EasyTipViewDelegate {
+
+ func easyTipViewDidTap(_ tipView: EasyTipView) {
+ NCManageDatabase.shared.addTip(NCGlobal.shared.tipNCViewerPDFThumbnail)
+ }
+
+ func easyTipViewDidDismiss(_ tipView: EasyTipView) { }
+}