diff --git a/PDFReader.xcodeproj/project.pbxproj b/PDFReader.xcodeproj/project.pbxproj index 4c4496d..bdeb858 100644 --- a/PDFReader.xcodeproj/project.pbxproj +++ b/PDFReader.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ @@ -26,6 +26,8 @@ 146D371F1DAB7EDF004EEFA5 /* StartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 146D371E1DAB7EDF004EEFA5 /* StartViewController.swift */; }; 146D37231DAB7F0F004EEFA5 /* apple.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 146D37211DAB7F0F004EEFA5 /* apple.pdf */; }; 146D37241DAB7F0F004EEFA5 /* mongodb.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 146D37221DAB7F0F004EEFA5 /* mongodb.pdf */; }; + 8A044B8D20E39A05009D6A29 /* PDFViewUIProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A044B8C20E39A01009D6A29 /* PDFViewUIProperties.swift */; }; + BA24CD4A20E64A3100A24190 /* PDFThumbnailUIProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA24CD4920E64A3100A24190 /* PDFThumbnailUIProperties.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -74,6 +76,8 @@ 146D371E1DAB7EDF004EEFA5 /* StartViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StartViewController.swift; sourceTree = ""; }; 146D37211DAB7F0F004EEFA5 /* apple.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = apple.pdf; sourceTree = ""; }; 146D37221DAB7F0F004EEFA5 /* mongodb.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = mongodb.pdf; sourceTree = ""; }; + 8A044B8C20E39A01009D6A29 /* PDFViewUIProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PDFViewUIProperties.swift; sourceTree = ""; }; + BA24CD4920E64A3100A24190 /* PDFThumbnailUIProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PDFThumbnailUIProperties.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -143,6 +147,7 @@ 14083FE71D4A956E00909913 /* Classes */ = { isa = PBXGroup; children = ( + 8A044B8C20E39A01009D6A29 /* PDFViewUIProperties.swift */, 14083FE81D4A956E00909913 /* PDFDocument.swift */, 14083FE91D4A956E00909913 /* PDFPageCollectionViewCell.swift */, 14083FEA1D4A956E00909913 /* PDFPageView.swift */, @@ -150,6 +155,7 @@ 14083FEC1D4A956E00909913 /* PDFThumbnailCollectionViewController.swift */, 14083FED1D4A956E00909913 /* PDFViewController.swift */, 14083FEE1D4A956E00909913 /* TiledView.swift */, + BA24CD4920E64A3100A24190 /* PDFThumbnailUIProperties.swift */, ); path = Classes; sourceTree = ""; @@ -237,23 +243,25 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0910; + LastUpgradeCheck = 1000; ORGANIZATIONNAME = mytrus; TargetAttributes = { 14083FD81D4A953900909913 = { CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0900; + DevelopmentTeam = YXKHJYMJA6; + LastSwiftMigration = 1000; ProvisioningStyle = Automatic; }; 146D370B1DAB7E23004EEFA5 = { CreatedOnToolsVersion = 8.0; - LastSwiftMigration = 0900; + DevelopmentTeam = YXKHJYMJA6; + LastSwiftMigration = 1000; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 14083FD31D4A953900909913 /* Build configuration list for PBXProject "PDFReader" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -304,8 +312,10 @@ 14083FF11D4A956E00909913 /* PDFPageCollectionViewCell.swift in Sources */, 14083FF01D4A956E00909913 /* PDFDocument.swift in Sources */, 14083FF51D4A956E00909913 /* PDFViewController.swift in Sources */, + 8A044B8D20E39A05009D6A29 /* PDFViewUIProperties.swift in Sources */, 14083FF41D4A956E00909913 /* PDFThumbnailCollectionViewController.swift in Sources */, 14083FF31D4A956E00909913 /* PDFThumbnailCell.swift in Sources */, + BA24CD4A20E64A3100A24190 /* PDFThumbnailUIProperties.swift in Sources */, 14083FF61D4A956E00909913 /* TiledView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -362,12 +372,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -397,7 +409,6 @@ GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; @@ -420,12 +431,14 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; @@ -450,7 +463,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -462,46 +476,50 @@ 14083FE21D4A953900909913 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YXKHJYMJA6; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = PDFReader/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mytrus.PDFReader; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; 14083FE31D4A953900909913 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YXKHJYMJA6; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = PDFReader/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mytrus.PDFReader; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; @@ -514,16 +532,18 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YXKHJYMJA6; INFOPLIST_FILE = "$(SRCROOT)/PDFReader/Demo/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mytrus.Demo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -536,15 +556,17 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YXKHJYMJA6; INFOPLIST_FILE = "$(SRCROOT)/PDFReader/Demo/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = com.mytrus.Demo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; diff --git a/PDFReader.xcodeproj/xcshareddata/xcschemes/PDFReader.xcscheme b/PDFReader.xcodeproj/xcshareddata/xcschemes/PDFReader.xcscheme index 2497cb1..d6fc2af 100644 --- a/PDFReader.xcodeproj/xcshareddata/xcschemes/PDFReader.xcscheme +++ b/PDFReader.xcodeproj/xcshareddata/xcschemes/PDFReader.xcscheme @@ -1,6 +1,6 @@ @@ -37,7 +36,6 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" diff --git a/PDFReader/Demo/AppDelegate.swift b/PDFReader/Demo/AppDelegate.swift index a8796fd..3586744 100755 --- a/PDFReader/Demo/AppDelegate.swift +++ b/PDFReader/Demo/AppDelegate.swift @@ -12,7 +12,7 @@ import UIKit class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { return true } } diff --git a/PDFReader/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json b/PDFReader/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json index 1d060ed..d8db8d6 100644 --- a/PDFReader/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/PDFReader/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -84,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/Contents.json b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/Contents.json new file mode 100644 index 0000000..baa2620 --- /dev/null +++ b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "buttonBack64.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "buttonBack64@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "buttonBack64@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64.png b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64.png new file mode 100644 index 0000000..df8814e Binary files /dev/null and b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64.png differ diff --git a/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@2x.png b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@2x.png new file mode 100644 index 0000000..38c6d4e Binary files /dev/null and b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@2x.png differ diff --git a/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@3x.png b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@3x.png new file mode 100644 index 0000000..c8dc35c Binary files /dev/null and b/PDFReader/Demo/Assets.xcassets/buttonBack64.imageset/buttonBack64@3x.png differ diff --git a/PDFReader/Demo/Base.lproj/Main.storyboard b/PDFReader/Demo/Base.lproj/Main.storyboard index 420f7b8..a2a538a 100644 --- a/PDFReader/Demo/Base.lproj/Main.storyboard +++ b/PDFReader/Demo/Base.lproj/Main.storyboard @@ -1,11 +1,11 @@ - + - + @@ -22,10 +22,10 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + - + + + + + + + + + + + + - + - + - - - + + + - + - + - + + + - - + + + @@ -119,7 +208,7 @@ - + diff --git a/Sources/Classes/PDFDocument.swift b/Sources/Classes/PDFDocument.swift index 878366c..32bfc3e 100755 --- a/Sources/Classes/PDFDocument.swift +++ b/Sources/Classes/PDFDocument.swift @@ -108,7 +108,7 @@ public struct PDFDocument { var images = [UIImage]() var pagesCompleted = 0 for pageNumber in 0.. 0 else { return } - let curentPageIndexPath = IndexPath(row: currentPageIndex, section: 0) - if !collectionView.indexPathsForVisibleItems.contains(curentPageIndexPath) { - collectionView.scrollToItem(at: curentPageIndexPath, at: .centeredHorizontally, animated: true) + if currentPageIndex < collectionView.numberOfItems(inSection: 0) { + let curentPageIndexPath = IndexPath(row: currentPageIndex, section: 0) + if !collectionView.indexPathsForVisibleItems.contains(curentPageIndexPath) { + collectionView.scrollToItem(at: curentPageIndexPath, at: .centeredHorizontally, animated: true) + } } collectionView.reloadData() } @@ -43,35 +43,60 @@ internal final class PDFThumbnailCollectionViewController: UICollectionViewContr } } + /// UI properties + var uiProperties: PDFThumbnailUIProperties? + override func viewDidLoad() { super.viewDidLoad() - DispatchQueue.global(qos: .background).async { - self.document.allPageImages(callback: { (images) in - DispatchQueue.main.async { - self.pageImages = images - } - }) + DispatchQueue.global(qos: .background).async { [weak self] in + if let document = self?.document { + document.allPageImages(callback: { (images) in + DispatchQueue.main.async { + self?.pageImages = images + } + }) + } } } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return pageImages?.count ?? 0 + return self.document.pageCount } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! PDFThumbnailCell + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) + if let thumbnailCell = cell as? PDFThumbnailCell { + thumbnailCell.imageView?.image = pageImages?[indexPath.row] + } - cell.imageView?.image = pageImages?[indexPath.row] - cell.alpha = currentPageIndex == indexPath.row ? 1 : 0.2 + if let activeBorderColor = uiProperties?.activeThumbnailBorderColor, + let inactiveBorderColor = uiProperties?.inactiveThumbnailBorderColor { // if border colors are available, apply them + let borderColor = currentPageIndex == indexPath.row ? activeBorderColor : inactiveBorderColor + cell.layer.borderColor = borderColor.cgColor + cell.layer.borderWidth = 1.0 + } else { // else change the alpha + cell.alpha = currentPageIndex == indexPath.row ? 1 : 0.2 + } return cell } - @objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { + @objc func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return PDFThumbnailCell.cellSize } override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { delegate?.didSelectIndexPath(indexPath) } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { + return 2.0 + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { + if collectionView.bounds.width >= UIScreen.main.bounds.width { + return UIEdgeInsets(top: 0, left: 6, bottom: 0, right: 6) + } + return UIEdgeInsets.zero + } } diff --git a/Sources/Classes/PDFThumbnailUIProperties.swift b/Sources/Classes/PDFThumbnailUIProperties.swift new file mode 100644 index 0000000..4c716e3 --- /dev/null +++ b/Sources/Classes/PDFThumbnailUIProperties.swift @@ -0,0 +1,29 @@ +// +// PDFThumbnailUIProperties.swift +// PDFReader +// +// Created by Vrushali Wani on 29/06/2018. +// Copyright © 2018 mytrus. All rights reserved. +// + +import Foundation + +public struct PDFThumbnailUIProperties { + /// Border color for thumbnail for visible page (active) + public var activeThumbnailBorderColor: UIColor? + + /// Border color for thumbnails for invisible pages (inactive) + public var inactiveThumbnailBorderColor: UIColor? + + /** + Returns newly initialised PDFThumbnailUIProperties + + - activeThumbnailBorderColor: border color for thumbnail for visible page (active) + - inactiveThumbnailBorderColor: border color for thumbnails for invisible pages (inactive) + returns: a `PDFThumbnailUIProperties` + */ + public init(activeThumbnailBorderColor: UIColor?, inactiveThumbnailBorderColor: UIColor?) { + self.activeThumbnailBorderColor = activeThumbnailBorderColor + self.inactiveThumbnailBorderColor = inactiveThumbnailBorderColor + } +} diff --git a/Sources/Classes/PDFViewController.swift b/Sources/Classes/PDFViewController.swift old mode 100755 new mode 100644 index f468155..5d30f8c --- a/Sources/Classes/PDFViewController.swift +++ b/Sources/Classes/PDFViewController.swift @@ -10,48 +10,23 @@ import UIKit extension PDFViewController { /// Initializes a new `PDFViewController` /// - /// - parameter document: PDF document to be displayed - /// - parameter title: title that displays on the navigation bar on the PDFViewController; - /// if nil, uses document's filename - /// - parameter actionButtonImage: image of the action button; if nil, uses the default action system item image - /// - parameter actionStyle: sytle of the action button - /// - parameter backButton: button to override the default controller back button - /// - parameter isThumbnailsEnabled: whether or not the thumbnails bar should be enabled - /// - parameter startPageIndex: page index to start on load, defaults to 0; if out of bounds, set to 0 - /// + /// - parameter document: PDF document to be displayed + /// - parameter pdfViewProperties: PDFViewUIProperties comprising values and theme for UI components + /// - parameter thumbnailUIProperties: PDFThumbnailUIProperties comprising theme for UI components /// - returns: a `PDFViewController` - public class func createNew(with document: PDFDocument, title: String? = nil, actionButtonImage: UIImage? = nil, actionStyle: ActionStyle = .print, backButton: UIBarButtonItem? = nil, isThumbnailsEnabled: Bool = true, startPageIndex: Int = 0) -> PDFViewController { + public class func createNew(with document: PDFDocument, pdfViewProperties: PDFViewUIProperties, thumbnailUIProperties: PDFThumbnailUIProperties) -> PDFViewController { let storyboard = UIStoryboard(name: "PDFReader", bundle: Bundle(for: PDFViewController.self)) let controller = storyboard.instantiateInitialViewController() as! PDFViewController controller.document = document - controller.actionStyle = actionStyle - - if let title = title { - controller.title = title - } else { - controller.title = document.fileName - } - - if startPageIndex >= 0 && startPageIndex < document.pageCount { - controller.currentPageIndex = startPageIndex - } else { - controller.currentPageIndex = 0 - } - - controller.backButton = backButton + controller.uiProperties = pdfViewProperties + controller.thumbnailUIProperties = thumbnailUIProperties - if let actionButtonImage = actionButtonImage { - controller.actionButton = UIBarButtonItem(image: actionButtonImage, style: .plain, target: controller, action: #selector(actionButtonPressed)) - } else { - controller.actionButton = UIBarButtonItem(barButtonSystemItem: .action, target: controller, action: #selector(actionButtonPressed)) - } - controller.isThumbnailsEnabled = isThumbnailsEnabled return controller } } /// Controller that is able to interact and navigate through pages of a `PDFDocument` -public final class PDFViewController: UIViewController { +public class PDFViewController: UIViewController { /// Action button style public enum ActionStyle { /// Brings up a print modal allowing user to print current PDF @@ -64,9 +39,33 @@ public final class PDFViewController: UIViewController { case customAction(() -> ()) } + /// View representing the navigation bar + @IBOutlet public var navigationView: UIView! + + /// button for returning to previous view + @IBOutlet public var backButton: UIButton! + + /// Label for title + @IBOutlet public var titleLabel: UILabel! + + /// Label for subtitle + @IBOutlet public var subtitleLabel: UILabel! + + /// Line view in the navigation view + @IBOutlet public var lineView: UIView! + + /// Line view above the thumbnails + @IBOutlet public var lineViewSeparatingThumbnails: UIView! + /// Collection veiw where all the pdf pages are rendered @IBOutlet public var collectionView: UICollectionView! + /// Height of the navigation view (used to hide/show) + @IBOutlet private var navigationViewHeight: NSLayoutConstraint! + + /// Distance between the top of navigation view with top of page (used to hide/show) + @IBOutlet private var navigationViewTop: NSLayoutConstraint! + /// Height of the thumbnail bar (used to hide/show) @IBOutlet private var thumbnailCollectionControllerHeight: NSLayoutConstraint! @@ -79,7 +78,7 @@ public final class PDFViewController: UIViewController { /// PDF document that should be displayed private var document: PDFDocument! - private var actionStyle = ActionStyle.print + private var actionStyle: ActionStyle? /// Image used to override the default action button image private var actionButtonImage: UIImage? @@ -93,15 +92,8 @@ public final class PDFViewController: UIViewController { /// UIBarButtonItem used to override the default action button private var actionButton: UIBarButtonItem? - /// Backbutton used to override the default back button - private var backButton: UIBarButtonItem? - /// Background color to apply to the collectionView. - public var backgroundColor: UIColor? = .lightGray { - didSet { - collectionView?.backgroundColor = backgroundColor - } - } + public var backgroundColor: UIColor? = .lightGray /// Whether or not the thumbnails bar should be enabled private var isThumbnailsEnabled = true { @@ -116,7 +108,7 @@ public final class PDFViewController: UIViewController { } /// Slides horizontally (from left to right, default) or vertically (from top to bottom) - public var scrollDirection: UICollectionViewScrollDirection = .horizontal { + public var scrollDirection: UICollectionView.ScrollDirection = .horizontal { didSet { if collectionView == nil { // if the user of the controller is trying to change the scrollDiecton before it _ = view // is on the sceen, we need to show it ofscreen to access it's collectionView. @@ -127,16 +119,25 @@ public final class PDFViewController: UIViewController { } } + /// UI values + public var uiProperties: PDFViewUIProperties? + + ///Thumbnail UI properties + private var thumbnailUIProperties: PDFThumbnailUIProperties? + + /// Reset page when its unpresented + public var resetZoom: Bool = false + override public func viewDidLoad() { super.viewDidLoad() - + + view.backgroundColor = backgroundColor collectionView.backgroundColor = backgroundColor collectionView.register(PDFPageCollectionViewCell.self, forCellWithReuseIdentifier: "page") - navigationItem.rightBarButtonItem = actionButton - if let backItem = backButton { - navigationItem.leftBarButtonItem = backItem - } +// navigationItem.rightBarButtonItem = actionButton + + navigationItem.hidesBackButton = true let numberOfPages = CGFloat(document.pageCount) let cellSpacing = CGFloat(2.0) @@ -144,11 +145,39 @@ public final class PDFViewController: UIViewController { let thumbnailWidth = (numberOfPages * PDFThumbnailCell.cellSize.width) + totalSpacing let width = min(thumbnailWidth, view.bounds.width) thumbnailCollectionControllerWidth.constant = width + + if let properties = uiProperties { + if let title = properties.title { + titleLabel.text = title + if let font = properties.titleFont { + titleLabel.font = font + } + } else { + titleLabel.text = "" + } + if let subtitle = properties.subtitle { + subtitleLabel.text = subtitle + if let font = properties.subtitleFont { + subtitleLabel.font = font + } + } else { + subtitleLabel.text = "" + } + + backButton.setImage(properties.backButtonImage, for: .normal) + backButton.setTitle((properties.backButtonImage != nil ? "" : "Back"), for: .normal) + + isThumbnailsEnabled = properties.isThumbnailsEnabled + + if let lineViewColor = properties.lineViewColor { + lineView.backgroundColor = lineViewColor + lineViewSeparatingThumbnails.backgroundColor = lineViewColor + } + } } - public override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - didSelectIndexPath(IndexPath(row: currentPageIndex, section: 0)) + public override func didReceiveMemoryWarning() { + navigationController?.popViewController(animated: true) } override public var prefersStatusBarHidden: Bool { @@ -167,6 +196,7 @@ public final class PDFViewController: UIViewController { if let controller = segue.destination as? PDFThumbnailCollectionViewController { thumbnailCollectionController = controller controller.document = document + controller.uiProperties = thumbnailUIProperties controller.delegate = self controller.currentPageIndex = currentPageIndex } @@ -177,22 +207,29 @@ public final class PDFViewController: UIViewController { let currentIndexPath = IndexPath(row: self.currentPageIndex, section: 0) self.collectionView.reloadItems(at: [currentIndexPath]) self.collectionView.scrollToItem(at: currentIndexPath, at: .centeredHorizontally, animated: false) - }) { context in - self.thumbnailCollectionController?.currentPageIndex = self.currentPageIndex + }) { context in + self.thumbnailCollectionController?.currentPageIndex = self.currentPageIndex } super.viewWillTransition(to: size, with: coordinator) } + ///Back button tapped + @IBAction func backButtonTapped() { + navigationController?.popViewController(animated: true) + } + /// Takes an appropriate action based on the current action style @objc func actionButtonPressed() { - switch actionStyle { - case .print: - print() - case .activitySheet: - presentActivitySheet() - case .customAction(let customAction): - customAction() + if let actionStyle = actionStyle { + switch actionStyle { + case .print: + print() + case .activitySheet: + presentActivitySheet() + case .customAction(let customAction): + customAction() + } } } @@ -234,37 +271,33 @@ extension PDFViewController: UICollectionViewDataSource { } public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "page", for: indexPath) as! PDFPageCollectionViewCell - cell.setup(indexPath.row, collectionViewBounds: collectionView.bounds, document: document, pageCollectionViewCellDelegate: self) + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "page", for: indexPath) + if let pageCell = cell as? PDFPageCollectionViewCell { + pageCell.setup(indexPath.row, collectionViewBounds: collectionView.bounds, document: document, pageCollectionViewCellDelegate: self) + } return cell } } extension PDFViewController: PDFPageCollectionViewCellDelegate { - /// Toggles the hiding/showing of the thumbnail controller - /// - /// - parameter shouldHide: whether or not the controller should hide the thumbnail controller - private func hideThumbnailController(_ shouldHide: Bool) { - self.thumbnailCollectionControllerBottom.constant = shouldHide ? -thumbnailCollectionControllerHeight.constant : 0 - } func handleSingleTap(_ cell: PDFPageCollectionViewCell, pdfPageView: PDFPageView) { - var shouldHide: Bool { - guard let isNavigationBarHidden = navigationController?.isNavigationBarHidden else { - return false - } - return !isNavigationBarHidden + if navigationViewTop.constant < CGFloat(0.0) { + navigationViewTop.constant = CGFloat(0.0) + thumbnailCollectionControllerBottom.constant = CGFloat(0.0) + } else { + navigationViewTop.constant = -navigationViewHeight.constant + thumbnailCollectionControllerBottom.constant = -thumbnailCollectionControllerHeight.constant } UIView.animate(withDuration: 0.25) { - self.hideThumbnailController(shouldHide) - self.navigationController?.setNavigationBarHidden(shouldHide, animated: true) + self.view.layoutIfNeeded() } } } extension PDFViewController: UICollectionViewDelegateFlowLayout { public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { - return CGSize(width: collectionView.frame.width - 1, height: collectionView.frame.height) + return CGSize(width: collectionView.frame.width, height: collectionView.frame.height) } } @@ -278,8 +311,21 @@ extension PDFViewController: UIScrollViewDelegate { } if updatedPageIndex != currentPageIndex { + if resetZoom { + self.collectionView.reloadItems(at: [IndexPath(item: currentPageIndex, section: 0)]) + } currentPageIndex = updatedPageIndex thumbnailCollectionController?.currentPageIndex = currentPageIndex } } + + public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { + if navigationViewTop.constant != -navigationViewHeight.constant { + navigationViewTop.constant = -navigationViewHeight.constant + thumbnailCollectionControllerBottom.constant = -thumbnailCollectionControllerHeight.constant + } + UIView.animate(withDuration: 0.25) { + self.view.layoutIfNeeded() + } + } } diff --git a/Sources/Classes/PDFViewUIProperties.swift b/Sources/Classes/PDFViewUIProperties.swift new file mode 100644 index 0000000..8f420a9 --- /dev/null +++ b/Sources/Classes/PDFViewUIProperties.swift @@ -0,0 +1,63 @@ +// +// PDFViewUIProperties.swift +// PDFReader +// +// Created by Vrushali Wani on 26/06/2018. +// Copyright © 2018 mytrus. All rights reserved. +// + +import Foundation + +public struct PDFViewUIProperties { + /// Title for the pdf + public var title: String? + + /// font for the title label + public var titleFont: UIFont? + + /// subtitle for the pdf + public var subtitle: String? + + /// font for the subtitle label + public var subtitleFont: UIFont? + + /// image for back button + public var backButtonImage: UIImage? + + /// Whether or not the thumbnails bar should be enabled + public var isThumbnailsEnabled: Bool + + /// Color of the line view + public var lineViewColor: UIColor? + + /// Guid + public var guid: String + + /// specifies whether the pdf is accessible without subscription. Used for analytics + public var hasFreeUsagePolicy: Bool + + /** + Returns newly initialised PDFViewUIProperties + - guid: Guid of product + - title: Title for the pdf + - titleFont: font for the title label + - subtitle: subtitle for the pdf + - subtitleFont: font for the subtitle label + - backButtonImage: image for back button + - isThumbnailsEnabled: whether or not the thumbnails bar should be enabled + - lineViewColor: color for the line view + - hasFreeUsagePolicy: availability to users without subscription + returns: a `PDFViewUIProperties` + */ + public init(guid: String, title: String? = nil, titleFont: UIFont? = nil, subtitle: String? = nil, subtitleFont: UIFont? = nil, backButtonImage: UIImage? = nil, isThumbnailsEnabled: Bool = true, lineViewColor: UIColor? = nil, hasFreeUsagePolicy: Bool = false) { + self.guid = guid + self.title = title + self.titleFont = titleFont + self.subtitle = subtitle + self.subtitleFont = subtitleFont + self.backButtonImage = backButtonImage + self.isThumbnailsEnabled = isThumbnailsEnabled + self.lineViewColor = lineViewColor + self.hasFreeUsagePolicy = hasFreeUsagePolicy + } +}