├── .gitignore ├── Classes └── PageMaster.swift ├── Demo ├── Demo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Demo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Extension │ │ └── UIView+.swift │ ├── Info.plist │ └── ViewController.swift ├── DemoTests │ ├── DemoTests.swift │ └── Info.plist └── DemoUITests │ ├── DemoUITests.swift │ └── Info.plist ├── LICENSE ├── PageMaster.podspec ├── PageMaster.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── PageMaster.xcscheme ├── PageMaster ├── Info.plist └── PageMaster.h ├── PageMasterTests ├── Info.plist └── PageMasterTests.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode (from gitignore.io) 2 | build/ 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | *.xccheckout 13 | *.moved-aside 14 | DerivedData 15 | *.hmap 16 | *.ipa 17 | *.xcuserstate 18 | 19 | # CocoaPod 20 | Pods/* 21 | Podfile.lock 22 | 23 | # Carthage 24 | Carthage/Build 25 | 26 | # others 27 | *.swp 28 | !.gitkeep 29 | .DS_Store 30 | UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Classes/PageMaster.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageMaster.swift 3 | // PageMaster 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | /** 10 | [PageMaster] 11 | 12 | Copyright (c) [2019] [Tomosuke Okada] 13 | 14 | This software is released under the MIT License. 15 | http://opensource.org/licenses/mit-license.ph 16 | */ 17 | 18 | import UIKit 19 | 20 | public protocol PageMasterDelegate: class { 21 | func pageMaster(_ master: PageMaster, didChangePage page: Int) 22 | } 23 | 24 | public final class PageMaster: UIPageViewController { 25 | 26 | public private(set) var vcList = [UIViewController]() 27 | 28 | public private(set) var currentPage = 0 { 29 | didSet { 30 | self.pageDelegate?.pageMaster(self, didChangePage: self.currentPage) 31 | } 32 | } 33 | 34 | public var currentViewController: UIViewController { 35 | return self.vcList[currentPage] 36 | } 37 | 38 | public var isInfinite = false 39 | 40 | public weak var pageDelegate: PageMasterDelegate? 41 | 42 | public init(_ vcList: [UIViewController] = [], transitionStyle: UIPageViewController.TransitionStyle = .scroll, navigationOrientation: UIPageViewController.NavigationOrientation = .horizontal) { 43 | super.init(transitionStyle: transitionStyle, navigationOrientation: navigationOrientation, options: nil) 44 | self.view.subviews.forEach { ($0 as? UIScrollView)?.delaysContentTouches = false } 45 | self.dataSource = self 46 | self.delegate = self 47 | self.setup(vcList) 48 | } 49 | 50 | required init?(coder: NSCoder) { 51 | fatalError("init(coder:) has not been implemented") 52 | } 53 | } 54 | 55 | // MARK: - Public 56 | extension PageMaster { 57 | 58 | public func setup(_ vcList: [UIViewController]) { 59 | guard !vcList.isEmpty else { 60 | return 61 | } 62 | self.vcList = vcList 63 | self.setViewControllers([self.vcList[self.currentPage]], direction: .forward, animated: false, completion: nil) 64 | } 65 | 66 | public func setPage(_ page: Int, animated: Bool = false) { 67 | guard self.currentPage != page else { 68 | return 69 | } 70 | self.setViewControllers([self.vcList[page]], direction: self.pageDirection(from: page), animated: animated, completion: nil) 71 | self.currentPage = page 72 | } 73 | } 74 | 75 | // MARK: - Direction 76 | extension PageMaster { 77 | 78 | private func pageDirection(from page: Int) -> UIPageViewController.NavigationDirection { 79 | if self.isInfinite { 80 | return self.infinitePageDirection(from: page) 81 | } 82 | else { 83 | return self.normalPageDirection(from: page) 84 | } 85 | } 86 | 87 | private func normalPageDirection(from page: Int) -> UIPageViewController.NavigationDirection { 88 | if self.currentPage < page { 89 | return .forward 90 | } 91 | else { 92 | return .reverse 93 | } 94 | } 95 | 96 | private func infinitePageDirection(from page: Int) -> UIPageViewController.NavigationDirection { 97 | let lastPage = self.vcList.count - 1 98 | if self.currentPage == lastPage && page == 0 { 99 | return .forward 100 | } 101 | 102 | if self.currentPage == 0 && page == lastPage { 103 | return .reverse 104 | } 105 | 106 | return self.normalPageDirection(from: page) 107 | } 108 | } 109 | 110 | // MARK: - Index 111 | extension PageMaster { 112 | 113 | private func nextIndex(from current: UIViewController) -> Int? { 114 | guard let currentIndex = self.vcList.index(of: current) else { 115 | return nil 116 | } 117 | 118 | if self.isInfinite { 119 | return self.infiniteNextIndex(from: currentIndex) 120 | } 121 | else { 122 | return self.normalNextIndex(from: currentIndex) 123 | } 124 | } 125 | 126 | private func normalNextIndex(from currentIndex: Int) -> Int? { 127 | let nextIndex = currentIndex + 1 128 | if nextIndex >= self.vcList.count { 129 | return nil 130 | } 131 | else { 132 | return nextIndex 133 | } 134 | } 135 | 136 | private func infiniteNextIndex(from currentIndex: Int) -> Int? { 137 | let nextIndex = currentIndex + 1 138 | if nextIndex >= self.vcList.count { 139 | return 0 140 | } 141 | else { 142 | return nextIndex 143 | } 144 | } 145 | 146 | private func previousIndex(from current: UIViewController) -> Int? { 147 | guard let currentIndex = self.vcList.index(of: current) else { 148 | return nil 149 | } 150 | 151 | if self.isInfinite { 152 | return self.infinitePreviousIndex(from: currentIndex) 153 | } 154 | else { 155 | return self.normalPreviousIndex(from: currentIndex) 156 | } 157 | } 158 | 159 | private func normalPreviousIndex(from currentIndex: Int) -> Int? { 160 | let previousIndex = currentIndex - 1 161 | if previousIndex < 0 { 162 | return nil 163 | } 164 | else { 165 | return previousIndex 166 | } 167 | } 168 | 169 | private func infinitePreviousIndex(from currentIndex: Int) -> Int? { 170 | let previousIndex = currentIndex - 1 171 | if previousIndex < 0 { 172 | return self.vcList.count - 1 173 | } 174 | else { 175 | return previousIndex 176 | } 177 | } 178 | } 179 | 180 | // MARK: - UIPageViewControllerDataSource 181 | extension PageMaster: UIPageViewControllerDataSource { 182 | 183 | public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 184 | if let previousIndex = self.previousIndex(from: viewController) { 185 | return self.vcList[previousIndex] 186 | } 187 | return nil 188 | } 189 | 190 | public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 191 | if let nextIndex = self.nextIndex(from: viewController) { 192 | return self.vcList[nextIndex] 193 | } 194 | return nil 195 | } 196 | } 197 | 198 | // MARK: - UIPageViewControllerDelegate 199 | extension PageMaster: UIPageViewControllerDelegate { 200 | 201 | public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 202 | let current = pageViewController.viewControllers![0] 203 | self.currentPage = self.vcList.index(of: current)! 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0416A189221077AC002DDF4D /* PageMaster.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0416A18222106CB3002DDF4D /* PageMaster.framework */; }; 11 | 0416A18A221077AC002DDF4D /* PageMaster.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0416A18222106CB3002DDF4D /* PageMaster.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 12 | 04765E2F220EAAFF000AC346 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E2E220EAAFF000AC346 /* AppDelegate.swift */; }; 13 | 04765E31220EAAFF000AC346 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E30220EAAFF000AC346 /* ViewController.swift */; }; 14 | 04765E34220EAAFF000AC346 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 04765E32220EAAFF000AC346 /* Main.storyboard */; }; 15 | 04765E36220EAB01000AC346 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 04765E35220EAB01000AC346 /* Assets.xcassets */; }; 16 | 04765E39220EAB01000AC346 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 04765E37220EAB01000AC346 /* LaunchScreen.storyboard */; }; 17 | 04765E44220EAB01000AC346 /* DemoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E43220EAB01000AC346 /* DemoTests.swift */; }; 18 | 04765E4F220EAB02000AC346 /* DemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E4E220EAB02000AC346 /* DemoUITests.swift */; }; 19 | 04765E78220EB0CC000AC346 /* UIView+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E77220EB0CC000AC346 /* UIView+.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 0416A18122106CB3002DDF4D /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */; 26 | proxyType = 2; 27 | remoteGlobalIDString = 04765E08220EAAE2000AC346; 28 | remoteInfo = PageMaster; 29 | }; 30 | 0416A18322106CB3002DDF4D /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */; 33 | proxyType = 2; 34 | remoteGlobalIDString = 04765E11220EAAE2000AC346; 35 | remoteInfo = PageMasterTests; 36 | }; 37 | 0416A18B221077AC002DDF4D /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 04765E07220EAAE2000AC346; 42 | remoteInfo = PageMaster; 43 | }; 44 | 04765E40220EAB01000AC346 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = 04765E23220EAAFF000AC346 /* Project object */; 47 | proxyType = 1; 48 | remoteGlobalIDString = 04765E2A220EAAFF000AC346; 49 | remoteInfo = Demo; 50 | }; 51 | 04765E4B220EAB02000AC346 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = 04765E23220EAAFF000AC346 /* Project object */; 54 | proxyType = 1; 55 | remoteGlobalIDString = 04765E2A220EAAFF000AC346; 56 | remoteInfo = Demo; 57 | }; 58 | /* End PBXContainerItemProxy section */ 59 | 60 | /* Begin PBXCopyFilesBuildPhase section */ 61 | 04765E75220EAE04000AC346 /* Embed Frameworks */ = { 62 | isa = PBXCopyFilesBuildPhase; 63 | buildActionMask = 2147483647; 64 | dstPath = ""; 65 | dstSubfolderSpec = 10; 66 | files = ( 67 | 0416A18A221077AC002DDF4D /* PageMaster.framework in Embed Frameworks */, 68 | ); 69 | name = "Embed Frameworks"; 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | /* End PBXCopyFilesBuildPhase section */ 73 | 74 | /* Begin PBXFileReference section */ 75 | 04765E2B220EAAFF000AC346 /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | 04765E2E220EAAFF000AC346 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 77 | 04765E30220EAAFF000AC346 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 78 | 04765E33220EAAFF000AC346 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 79 | 04765E35220EAB01000AC346 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 80 | 04765E38220EAB01000AC346 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 81 | 04765E3A220EAB01000AC346 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 82 | 04765E3F220EAB01000AC346 /* DemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | 04765E43220EAB01000AC346 /* DemoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoTests.swift; sourceTree = ""; }; 84 | 04765E45220EAB01000AC346 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85 | 04765E4A220EAB02000AC346 /* DemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 86 | 04765E4E220EAB02000AC346 /* DemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoUITests.swift; sourceTree = ""; }; 87 | 04765E50220EAB02000AC346 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 88 | 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PageMaster.xcodeproj; path = ../PageMaster.xcodeproj; sourceTree = ""; }; 89 | 04765E77220EB0CC000AC346 /* UIView+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+.swift"; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 04765E28220EAAFF000AC346 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 0416A189221077AC002DDF4D /* PageMaster.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | 04765E3C220EAB01000AC346 /* Frameworks */ = { 102 | isa = PBXFrameworksBuildPhase; 103 | buildActionMask = 2147483647; 104 | files = ( 105 | ); 106 | runOnlyForDeploymentPostprocessing = 0; 107 | }; 108 | 04765E47220EAB02000AC346 /* Frameworks */ = { 109 | isa = PBXFrameworksBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | /* End PBXFrameworksBuildPhase section */ 116 | 117 | /* Begin PBXGroup section */ 118 | 0416A17D22106CB2002DDF4D /* Products */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 0416A18222106CB3002DDF4D /* PageMaster.framework */, 122 | 0416A18422106CB3002DDF4D /* PageMasterTests.xctest */, 123 | ); 124 | name = Products; 125 | sourceTree = ""; 126 | }; 127 | 04765E22220EAAFF000AC346 = { 128 | isa = PBXGroup; 129 | children = ( 130 | 04765E2D220EAAFF000AC346 /* Demo */, 131 | 04765E42220EAB01000AC346 /* DemoTests */, 132 | 04765E4D220EAB02000AC346 /* DemoUITests */, 133 | 04765E2C220EAAFF000AC346 /* Products */, 134 | 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */, 135 | ); 136 | sourceTree = ""; 137 | }; 138 | 04765E2C220EAAFF000AC346 /* Products */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 04765E2B220EAAFF000AC346 /* Demo.app */, 142 | 04765E3F220EAB01000AC346 /* DemoTests.xctest */, 143 | 04765E4A220EAB02000AC346 /* DemoUITests.xctest */, 144 | ); 145 | name = Products; 146 | sourceTree = ""; 147 | }; 148 | 04765E2D220EAAFF000AC346 /* Demo */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 04765E2E220EAAFF000AC346 /* AppDelegate.swift */, 152 | 04765E30220EAAFF000AC346 /* ViewController.swift */, 153 | 04765E32220EAAFF000AC346 /* Main.storyboard */, 154 | 04765E76220EB0BC000AC346 /* Extension */, 155 | 04765E35220EAB01000AC346 /* Assets.xcassets */, 156 | 04765E37220EAB01000AC346 /* LaunchScreen.storyboard */, 157 | 04765E3A220EAB01000AC346 /* Info.plist */, 158 | ); 159 | path = Demo; 160 | sourceTree = ""; 161 | }; 162 | 04765E42220EAB01000AC346 /* DemoTests */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 04765E43220EAB01000AC346 /* DemoTests.swift */, 166 | 04765E45220EAB01000AC346 /* Info.plist */, 167 | ); 168 | path = DemoTests; 169 | sourceTree = ""; 170 | }; 171 | 04765E4D220EAB02000AC346 /* DemoUITests */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 04765E4E220EAB02000AC346 /* DemoUITests.swift */, 175 | 04765E50220EAB02000AC346 /* Info.plist */, 176 | ); 177 | path = DemoUITests; 178 | sourceTree = ""; 179 | }; 180 | 04765E76220EB0BC000AC346 /* Extension */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | 04765E77220EB0CC000AC346 /* UIView+.swift */, 184 | ); 185 | path = Extension; 186 | sourceTree = ""; 187 | }; 188 | /* End PBXGroup section */ 189 | 190 | /* Begin PBXNativeTarget section */ 191 | 04765E2A220EAAFF000AC346 /* Demo */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 04765E53220EAB02000AC346 /* Build configuration list for PBXNativeTarget "Demo" */; 194 | buildPhases = ( 195 | 04765E27220EAAFF000AC346 /* Sources */, 196 | 04765E28220EAAFF000AC346 /* Frameworks */, 197 | 04765E29220EAAFF000AC346 /* Resources */, 198 | 04765E75220EAE04000AC346 /* Embed Frameworks */, 199 | ); 200 | buildRules = ( 201 | ); 202 | dependencies = ( 203 | 0416A18C221077AC002DDF4D /* PBXTargetDependency */, 204 | ); 205 | name = Demo; 206 | productName = Demo; 207 | productReference = 04765E2B220EAAFF000AC346 /* Demo.app */; 208 | productType = "com.apple.product-type.application"; 209 | }; 210 | 04765E3E220EAB01000AC346 /* DemoTests */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 04765E56220EAB02000AC346 /* Build configuration list for PBXNativeTarget "DemoTests" */; 213 | buildPhases = ( 214 | 04765E3B220EAB01000AC346 /* Sources */, 215 | 04765E3C220EAB01000AC346 /* Frameworks */, 216 | 04765E3D220EAB01000AC346 /* Resources */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | 04765E41220EAB01000AC346 /* PBXTargetDependency */, 222 | ); 223 | name = DemoTests; 224 | productName = DemoTests; 225 | productReference = 04765E3F220EAB01000AC346 /* DemoTests.xctest */; 226 | productType = "com.apple.product-type.bundle.unit-test"; 227 | }; 228 | 04765E49220EAB02000AC346 /* DemoUITests */ = { 229 | isa = PBXNativeTarget; 230 | buildConfigurationList = 04765E59220EAB02000AC346 /* Build configuration list for PBXNativeTarget "DemoUITests" */; 231 | buildPhases = ( 232 | 04765E46220EAB02000AC346 /* Sources */, 233 | 04765E47220EAB02000AC346 /* Frameworks */, 234 | 04765E48220EAB02000AC346 /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | 04765E4C220EAB02000AC346 /* PBXTargetDependency */, 240 | ); 241 | name = DemoUITests; 242 | productName = DemoUITests; 243 | productReference = 04765E4A220EAB02000AC346 /* DemoUITests.xctest */; 244 | productType = "com.apple.product-type.bundle.ui-testing"; 245 | }; 246 | /* End PBXNativeTarget section */ 247 | 248 | /* Begin PBXProject section */ 249 | 04765E23220EAAFF000AC346 /* Project object */ = { 250 | isa = PBXProject; 251 | attributes = { 252 | LastSwiftUpdateCheck = 1010; 253 | LastUpgradeCheck = 1010; 254 | ORGANIZATIONNAME = TomosukeOkada; 255 | TargetAttributes = { 256 | 04765E2A220EAAFF000AC346 = { 257 | CreatedOnToolsVersion = 10.1; 258 | }; 259 | 04765E3E220EAB01000AC346 = { 260 | CreatedOnToolsVersion = 10.1; 261 | TestTargetID = 04765E2A220EAAFF000AC346; 262 | }; 263 | 04765E49220EAB02000AC346 = { 264 | CreatedOnToolsVersion = 10.1; 265 | TestTargetID = 04765E2A220EAAFF000AC346; 266 | }; 267 | }; 268 | }; 269 | buildConfigurationList = 04765E26220EAAFF000AC346 /* Build configuration list for PBXProject "Demo" */; 270 | compatibilityVersion = "Xcode 9.3"; 271 | developmentRegion = en; 272 | hasScannedForEncodings = 0; 273 | knownRegions = ( 274 | en, 275 | Base, 276 | ); 277 | mainGroup = 04765E22220EAAFF000AC346; 278 | productRefGroup = 04765E2C220EAAFF000AC346 /* Products */; 279 | projectDirPath = ""; 280 | projectReferences = ( 281 | { 282 | ProductGroup = 0416A17D22106CB2002DDF4D /* Products */; 283 | ProjectRef = 04765E65220EAB4B000AC346 /* PageMaster.xcodeproj */; 284 | }, 285 | ); 286 | projectRoot = ""; 287 | targets = ( 288 | 04765E2A220EAAFF000AC346 /* Demo */, 289 | 04765E3E220EAB01000AC346 /* DemoTests */, 290 | 04765E49220EAB02000AC346 /* DemoUITests */, 291 | ); 292 | }; 293 | /* End PBXProject section */ 294 | 295 | /* Begin PBXReferenceProxy section */ 296 | 0416A18222106CB3002DDF4D /* PageMaster.framework */ = { 297 | isa = PBXReferenceProxy; 298 | fileType = wrapper.framework; 299 | path = PageMaster.framework; 300 | remoteRef = 0416A18122106CB3002DDF4D /* PBXContainerItemProxy */; 301 | sourceTree = BUILT_PRODUCTS_DIR; 302 | }; 303 | 0416A18422106CB3002DDF4D /* PageMasterTests.xctest */ = { 304 | isa = PBXReferenceProxy; 305 | fileType = wrapper.cfbundle; 306 | path = PageMasterTests.xctest; 307 | remoteRef = 0416A18322106CB3002DDF4D /* PBXContainerItemProxy */; 308 | sourceTree = BUILT_PRODUCTS_DIR; 309 | }; 310 | /* End PBXReferenceProxy section */ 311 | 312 | /* Begin PBXResourcesBuildPhase section */ 313 | 04765E29220EAAFF000AC346 /* Resources */ = { 314 | isa = PBXResourcesBuildPhase; 315 | buildActionMask = 2147483647; 316 | files = ( 317 | 04765E39220EAB01000AC346 /* LaunchScreen.storyboard in Resources */, 318 | 04765E36220EAB01000AC346 /* Assets.xcassets in Resources */, 319 | 04765E34220EAAFF000AC346 /* Main.storyboard in Resources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | 04765E3D220EAB01000AC346 /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | 04765E48220EAB02000AC346 /* Resources */ = { 331 | isa = PBXResourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXResourcesBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | 04765E27220EAAFF000AC346 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | 04765E78220EB0CC000AC346 /* UIView+.swift in Sources */, 345 | 04765E31220EAAFF000AC346 /* ViewController.swift in Sources */, 346 | 04765E2F220EAAFF000AC346 /* AppDelegate.swift in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | 04765E3B220EAB01000AC346 /* Sources */ = { 351 | isa = PBXSourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | 04765E44220EAB01000AC346 /* DemoTests.swift in Sources */, 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | }; 358 | 04765E46220EAB02000AC346 /* Sources */ = { 359 | isa = PBXSourcesBuildPhase; 360 | buildActionMask = 2147483647; 361 | files = ( 362 | 04765E4F220EAB02000AC346 /* DemoUITests.swift in Sources */, 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | /* End PBXSourcesBuildPhase section */ 367 | 368 | /* Begin PBXTargetDependency section */ 369 | 0416A18C221077AC002DDF4D /* PBXTargetDependency */ = { 370 | isa = PBXTargetDependency; 371 | name = PageMaster; 372 | targetProxy = 0416A18B221077AC002DDF4D /* PBXContainerItemProxy */; 373 | }; 374 | 04765E41220EAB01000AC346 /* PBXTargetDependency */ = { 375 | isa = PBXTargetDependency; 376 | target = 04765E2A220EAAFF000AC346 /* Demo */; 377 | targetProxy = 04765E40220EAB01000AC346 /* PBXContainerItemProxy */; 378 | }; 379 | 04765E4C220EAB02000AC346 /* PBXTargetDependency */ = { 380 | isa = PBXTargetDependency; 381 | target = 04765E2A220EAAFF000AC346 /* Demo */; 382 | targetProxy = 04765E4B220EAB02000AC346 /* PBXContainerItemProxy */; 383 | }; 384 | /* End PBXTargetDependency section */ 385 | 386 | /* Begin PBXVariantGroup section */ 387 | 04765E32220EAAFF000AC346 /* Main.storyboard */ = { 388 | isa = PBXVariantGroup; 389 | children = ( 390 | 04765E33220EAAFF000AC346 /* Base */, 391 | ); 392 | name = Main.storyboard; 393 | sourceTree = ""; 394 | }; 395 | 04765E37220EAB01000AC346 /* LaunchScreen.storyboard */ = { 396 | isa = PBXVariantGroup; 397 | children = ( 398 | 04765E38220EAB01000AC346 /* Base */, 399 | ); 400 | name = LaunchScreen.storyboard; 401 | sourceTree = ""; 402 | }; 403 | /* End PBXVariantGroup section */ 404 | 405 | /* Begin XCBuildConfiguration section */ 406 | 04765E51220EAB02000AC346 /* Debug */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | ALWAYS_SEARCH_USER_PATHS = NO; 410 | CLANG_ANALYZER_NONNULL = YES; 411 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 413 | CLANG_CXX_LIBRARY = "libc++"; 414 | CLANG_ENABLE_MODULES = YES; 415 | CLANG_ENABLE_OBJC_ARC = YES; 416 | CLANG_ENABLE_OBJC_WEAK = YES; 417 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 418 | CLANG_WARN_BOOL_CONVERSION = YES; 419 | CLANG_WARN_COMMA = YES; 420 | CLANG_WARN_CONSTANT_CONVERSION = YES; 421 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 422 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 423 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 424 | CLANG_WARN_EMPTY_BODY = YES; 425 | CLANG_WARN_ENUM_CONVERSION = YES; 426 | CLANG_WARN_INFINITE_RECURSION = YES; 427 | CLANG_WARN_INT_CONVERSION = YES; 428 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 429 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 430 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 431 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 432 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 433 | CLANG_WARN_STRICT_PROTOTYPES = YES; 434 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 435 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 436 | CLANG_WARN_UNREACHABLE_CODE = YES; 437 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 438 | CODE_SIGN_IDENTITY = "iPhone Developer"; 439 | COPY_PHASE_STRIP = NO; 440 | DEBUG_INFORMATION_FORMAT = dwarf; 441 | ENABLE_STRICT_OBJC_MSGSEND = YES; 442 | ENABLE_TESTABILITY = YES; 443 | GCC_C_LANGUAGE_STANDARD = gnu11; 444 | GCC_DYNAMIC_NO_PIC = NO; 445 | GCC_NO_COMMON_BLOCKS = YES; 446 | GCC_OPTIMIZATION_LEVEL = 0; 447 | GCC_PREPROCESSOR_DEFINITIONS = ( 448 | "DEBUG=1", 449 | "$(inherited)", 450 | ); 451 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 452 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 453 | GCC_WARN_UNDECLARED_SELECTOR = YES; 454 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 455 | GCC_WARN_UNUSED_FUNCTION = YES; 456 | GCC_WARN_UNUSED_VARIABLE = YES; 457 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 458 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 459 | MTL_FAST_MATH = YES; 460 | ONLY_ACTIVE_ARCH = YES; 461 | SDKROOT = iphoneos; 462 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 463 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 464 | }; 465 | name = Debug; 466 | }; 467 | 04765E52220EAB02000AC346 /* Release */ = { 468 | isa = XCBuildConfiguration; 469 | buildSettings = { 470 | ALWAYS_SEARCH_USER_PATHS = NO; 471 | CLANG_ANALYZER_NONNULL = YES; 472 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 473 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 474 | CLANG_CXX_LIBRARY = "libc++"; 475 | CLANG_ENABLE_MODULES = YES; 476 | CLANG_ENABLE_OBJC_ARC = YES; 477 | CLANG_ENABLE_OBJC_WEAK = YES; 478 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 479 | CLANG_WARN_BOOL_CONVERSION = YES; 480 | CLANG_WARN_COMMA = YES; 481 | CLANG_WARN_CONSTANT_CONVERSION = YES; 482 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 483 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 484 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 485 | CLANG_WARN_EMPTY_BODY = YES; 486 | CLANG_WARN_ENUM_CONVERSION = YES; 487 | CLANG_WARN_INFINITE_RECURSION = YES; 488 | CLANG_WARN_INT_CONVERSION = YES; 489 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 490 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 491 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 492 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 493 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 494 | CLANG_WARN_STRICT_PROTOTYPES = YES; 495 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 496 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 497 | CLANG_WARN_UNREACHABLE_CODE = YES; 498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 499 | CODE_SIGN_IDENTITY = "iPhone Developer"; 500 | COPY_PHASE_STRIP = NO; 501 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 502 | ENABLE_NS_ASSERTIONS = NO; 503 | ENABLE_STRICT_OBJC_MSGSEND = YES; 504 | GCC_C_LANGUAGE_STANDARD = gnu11; 505 | GCC_NO_COMMON_BLOCKS = YES; 506 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 507 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 508 | GCC_WARN_UNDECLARED_SELECTOR = YES; 509 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 510 | GCC_WARN_UNUSED_FUNCTION = YES; 511 | GCC_WARN_UNUSED_VARIABLE = YES; 512 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 513 | MTL_ENABLE_DEBUG_INFO = NO; 514 | MTL_FAST_MATH = YES; 515 | SDKROOT = iphoneos; 516 | SWIFT_COMPILATION_MODE = wholemodule; 517 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 518 | VALIDATE_PRODUCT = YES; 519 | }; 520 | name = Release; 521 | }; 522 | 04765E54220EAB02000AC346 /* Debug */ = { 523 | isa = XCBuildConfiguration; 524 | buildSettings = { 525 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 526 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 527 | CODE_SIGN_IDENTITY = "iPhone Developer"; 528 | CODE_SIGN_STYLE = Automatic; 529 | DEVELOPMENT_TEAM = NG4PAUE398; 530 | INFOPLIST_FILE = Demo/Info.plist; 531 | LD_RUNPATH_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "@executable_path/Frameworks", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = PageMasterDemoApplication; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | PROVISIONING_PROFILE_SPECIFIER = ""; 538 | SWIFT_VERSION = 4.2; 539 | TARGETED_DEVICE_FAMILY = "1,2"; 540 | }; 541 | name = Debug; 542 | }; 543 | 04765E55220EAB02000AC346 /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 547 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 548 | CODE_SIGN_IDENTITY = "iPhone Developer"; 549 | CODE_SIGN_STYLE = Automatic; 550 | DEVELOPMENT_TEAM = NG4PAUE398; 551 | INFOPLIST_FILE = Demo/Info.plist; 552 | LD_RUNPATH_SEARCH_PATHS = ( 553 | "$(inherited)", 554 | "@executable_path/Frameworks", 555 | ); 556 | PRODUCT_BUNDLE_IDENTIFIER = PageMasterDemoApplication; 557 | PRODUCT_NAME = "$(TARGET_NAME)"; 558 | PROVISIONING_PROFILE_SPECIFIER = ""; 559 | SWIFT_VERSION = 4.2; 560 | TARGETED_DEVICE_FAMILY = "1,2"; 561 | }; 562 | name = Release; 563 | }; 564 | 04765E57220EAB02000AC346 /* Debug */ = { 565 | isa = XCBuildConfiguration; 566 | buildSettings = { 567 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 568 | BUNDLE_LOADER = "$(TEST_HOST)"; 569 | CODE_SIGN_STYLE = Automatic; 570 | INFOPLIST_FILE = DemoTests/Info.plist; 571 | LD_RUNPATH_SEARCH_PATHS = ( 572 | "$(inherited)", 573 | "@executable_path/Frameworks", 574 | "@loader_path/Frameworks", 575 | ); 576 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.DemoTests; 577 | PRODUCT_NAME = "$(TARGET_NAME)"; 578 | SWIFT_VERSION = 4.2; 579 | TARGETED_DEVICE_FAMILY = "1,2"; 580 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo.app/Demo"; 581 | }; 582 | name = Debug; 583 | }; 584 | 04765E58220EAB02000AC346 /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 588 | BUNDLE_LOADER = "$(TEST_HOST)"; 589 | CODE_SIGN_STYLE = Automatic; 590 | INFOPLIST_FILE = DemoTests/Info.plist; 591 | LD_RUNPATH_SEARCH_PATHS = ( 592 | "$(inherited)", 593 | "@executable_path/Frameworks", 594 | "@loader_path/Frameworks", 595 | ); 596 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.DemoTests; 597 | PRODUCT_NAME = "$(TARGET_NAME)"; 598 | SWIFT_VERSION = 4.2; 599 | TARGETED_DEVICE_FAMILY = "1,2"; 600 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo.app/Demo"; 601 | }; 602 | name = Release; 603 | }; 604 | 04765E5A220EAB02000AC346 /* Debug */ = { 605 | isa = XCBuildConfiguration; 606 | buildSettings = { 607 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 608 | CODE_SIGN_STYLE = Automatic; 609 | INFOPLIST_FILE = DemoUITests/Info.plist; 610 | LD_RUNPATH_SEARCH_PATHS = ( 611 | "$(inherited)", 612 | "@executable_path/Frameworks", 613 | "@loader_path/Frameworks", 614 | ); 615 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.DemoUITests; 616 | PRODUCT_NAME = "$(TARGET_NAME)"; 617 | SWIFT_VERSION = 4.2; 618 | TARGETED_DEVICE_FAMILY = "1,2"; 619 | TEST_TARGET_NAME = Demo; 620 | }; 621 | name = Debug; 622 | }; 623 | 04765E5B220EAB02000AC346 /* Release */ = { 624 | isa = XCBuildConfiguration; 625 | buildSettings = { 626 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 627 | CODE_SIGN_STYLE = Automatic; 628 | INFOPLIST_FILE = DemoUITests/Info.plist; 629 | LD_RUNPATH_SEARCH_PATHS = ( 630 | "$(inherited)", 631 | "@executable_path/Frameworks", 632 | "@loader_path/Frameworks", 633 | ); 634 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.DemoUITests; 635 | PRODUCT_NAME = "$(TARGET_NAME)"; 636 | SWIFT_VERSION = 4.2; 637 | TARGETED_DEVICE_FAMILY = "1,2"; 638 | TEST_TARGET_NAME = Demo; 639 | }; 640 | name = Release; 641 | }; 642 | /* End XCBuildConfiguration section */ 643 | 644 | /* Begin XCConfigurationList section */ 645 | 04765E26220EAAFF000AC346 /* Build configuration list for PBXProject "Demo" */ = { 646 | isa = XCConfigurationList; 647 | buildConfigurations = ( 648 | 04765E51220EAB02000AC346 /* Debug */, 649 | 04765E52220EAB02000AC346 /* Release */, 650 | ); 651 | defaultConfigurationIsVisible = 0; 652 | defaultConfigurationName = Release; 653 | }; 654 | 04765E53220EAB02000AC346 /* Build configuration list for PBXNativeTarget "Demo" */ = { 655 | isa = XCConfigurationList; 656 | buildConfigurations = ( 657 | 04765E54220EAB02000AC346 /* Debug */, 658 | 04765E55220EAB02000AC346 /* Release */, 659 | ); 660 | defaultConfigurationIsVisible = 0; 661 | defaultConfigurationName = Release; 662 | }; 663 | 04765E56220EAB02000AC346 /* Build configuration list for PBXNativeTarget "DemoTests" */ = { 664 | isa = XCConfigurationList; 665 | buildConfigurations = ( 666 | 04765E57220EAB02000AC346 /* Debug */, 667 | 04765E58220EAB02000AC346 /* Release */, 668 | ); 669 | defaultConfigurationIsVisible = 0; 670 | defaultConfigurationName = Release; 671 | }; 672 | 04765E59220EAB02000AC346 /* Build configuration list for PBXNativeTarget "DemoUITests" */ = { 673 | isa = XCConfigurationList; 674 | buildConfigurations = ( 675 | 04765E5A220EAB02000AC346 /* Debug */, 676 | 04765E5B220EAB02000AC346 /* Release */, 677 | ); 678 | defaultConfigurationIsVisible = 0; 679 | defaultConfigurationName = Release; 680 | }; 681 | /* End XCConfigurationList section */ 682 | }; 683 | rootObject = 04765E23220EAAFF000AC346 /* Project object */; 684 | } 685 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | func applicationWillResignActive(_ application: UIApplication) { 21 | } 22 | 23 | func applicationDidEnterBackground(_ application: UIApplication) { 24 | } 25 | 26 | func applicationWillEnterForeground(_ application: UIApplication) { 27 | } 28 | 29 | func applicationDidBecomeActive(_ application: UIApplication) { 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Demo/Demo/Extension/UIView+.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+.swift 3 | // Demo 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | // MARK: - xib 12 | extension UIView { 13 | 14 | func fitToSelf(childView: UIView) { 15 | childView.translatesAutoresizingMaskIntoConstraints = false 16 | let bindings = ["childView": childView] 17 | self.addConstraints( 18 | NSLayoutConstraint.constraints( 19 | withVisualFormat : "H:|[childView]|", 20 | options : [], 21 | metrics : nil, 22 | views : bindings 23 | )) 24 | self.addConstraints( 25 | NSLayoutConstraint.constraints( 26 | withVisualFormat : "V:|[childView]|", 27 | options : [], 28 | metrics : nil, 29 | views : bindings 30 | )) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Demo/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | PageMaster 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Demo/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Demo 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PageMaster 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet private weak var pageFrameView: UIView! { 15 | willSet { 16 | self.addChild(self.pageMaster) 17 | newValue.addSubview(self.pageMaster.view) 18 | newValue.fitToSelf(childView: self.pageMaster.view) 19 | self.pageMaster.didMove(toParent: self) 20 | } 21 | } 22 | 23 | @IBOutlet private weak var pageControl: UIPageControl! 24 | 25 | @IBOutlet private weak var switchInfiniteButton: UIButton! 26 | 27 | private let pageMaster = PageMaster([]) 28 | 29 | override func viewDidLoad() { 30 | super.viewDidLoad() 31 | self.setupPageViewController() 32 | } 33 | 34 | @IBAction private func didTapInfiniteButton(_ sender: UIButton) { 35 | sender.isSelected.toggle() 36 | self.pageMaster.isInfinite.toggle() 37 | } 38 | } 39 | 40 | // MARK: - Setup 41 | extension ViewController { 42 | 43 | private func setupPageViewController() { 44 | self.pageMaster.pageDelegate = self 45 | let vcList = [self.generateViewController(color: .red), 46 | self.generateViewController(color: .blue), 47 | self.generateViewController(color: .green)] 48 | self.pageControl.numberOfPages = vcList.count 49 | self.pageMaster.setup(vcList) 50 | } 51 | 52 | private func generateViewController(color: UIColor) -> UIViewController { 53 | let vc = UIViewController() 54 | vc.view.backgroundColor = color 55 | return vc 56 | } 57 | } 58 | 59 | // MARK: - PageMasterDelegate 60 | extension ViewController: PageMasterDelegate { 61 | 62 | func pageMaster(_ master: PageMaster, didChangePage page: Int) { 63 | self.pageControl.currentPage = page 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /Demo/DemoTests/DemoTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTests.swift 3 | // DemoTests 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Demo 11 | 12 | class DemoTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Demo/DemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/DemoUITests/DemoUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoUITests.swift 3 | // DemoUITests 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class DemoUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 20 | XCUIApplication().launch() 21 | 22 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 23 | } 24 | 25 | override func tearDown() { 26 | // Put teardown code here. This method is called after the invocation of each test method in the class. 27 | } 28 | 29 | func testExample() { 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Demo/DemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tomosuke Okada 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PageMaster.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "PageMaster" 4 | s.version = "1.0" 5 | s.summary = "PageMaster is a wrapper class for easier use of UIPageViewController." 6 | s.homepage = "https://github.com/PKPK-Carnage/PageMaster" 7 | s.license = { :type => "MIT", :file => "LICENSE" } 8 | s.author = { "Tomosuke Okada" => "pkpkcarnage@gmail.com" } 9 | s.social_media_url = "https://github.com/PKPK-Carnage" 10 | s.platform = :ios, "8.0" 11 | s.swift_version = "4.2" 12 | s.source = { :git => "https://github.com/PKPK-Carnage/PageMaster.git", :tag => "#{s.version}" } 13 | s.source_files = "Classes", "Classes/*.{swift}" 14 | s.requires_arc = true 15 | 16 | end 17 | -------------------------------------------------------------------------------- /PageMaster.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04765E12220EAAE2000AC346 /* PageMaster.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04765E08220EAAE2000AC346 /* PageMaster.framework */; }; 11 | 04765E17220EAAE2000AC346 /* PageMasterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E16220EAAE2000AC346 /* PageMasterTests.swift */; }; 12 | 04765E19220EAAE2000AC346 /* PageMaster.h in Headers */ = {isa = PBXBuildFile; fileRef = 04765E0B220EAAE2000AC346 /* PageMaster.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 04765E70220EABC8000AC346 /* PageMaster.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04765E6F220EABC8000AC346 /* PageMaster.swift */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXContainerItemProxy section */ 17 | 04765E13220EAAE2000AC346 /* PBXContainerItemProxy */ = { 18 | isa = PBXContainerItemProxy; 19 | containerPortal = 04765DFF220EAAE2000AC346 /* Project object */; 20 | proxyType = 1; 21 | remoteGlobalIDString = 04765E07220EAAE2000AC346; 22 | remoteInfo = PageViewController; 23 | }; 24 | /* End PBXContainerItemProxy section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 04765E08220EAAE2000AC346 /* PageMaster.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PageMaster.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 04765E0B220EAAE2000AC346 /* PageMaster.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PageMaster.h; sourceTree = ""; }; 29 | 04765E0C220EAAE2000AC346 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | 04765E11220EAAE2000AC346 /* PageMasterTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PageMasterTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 04765E16220EAAE2000AC346 /* PageMasterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageMasterTests.swift; sourceTree = ""; }; 32 | 04765E18220EAAE2000AC346 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 04765E6F220EABC8000AC346 /* PageMaster.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageMaster.swift; sourceTree = ""; }; 34 | /* End PBXFileReference section */ 35 | 36 | /* Begin PBXFrameworksBuildPhase section */ 37 | 04765E05220EAAE2000AC346 /* Frameworks */ = { 38 | isa = PBXFrameworksBuildPhase; 39 | buildActionMask = 2147483647; 40 | files = ( 41 | ); 42 | runOnlyForDeploymentPostprocessing = 0; 43 | }; 44 | 04765E0E220EAAE2000AC346 /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 04765E12220EAAE2000AC346 /* PageMaster.framework in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 04765DFE220EAAE2000AC346 = { 56 | isa = PBXGroup; 57 | children = ( 58 | 04765E6E220EABB6000AC346 /* Classes */, 59 | 04765E0A220EAAE2000AC346 /* PageMaster */, 60 | 04765E15220EAAE2000AC346 /* PageMasterTests */, 61 | 04765E09220EAAE2000AC346 /* Products */, 62 | ); 63 | sourceTree = ""; 64 | }; 65 | 04765E09220EAAE2000AC346 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 04765E08220EAAE2000AC346 /* PageMaster.framework */, 69 | 04765E11220EAAE2000AC346 /* PageMasterTests.xctest */, 70 | ); 71 | name = Products; 72 | sourceTree = ""; 73 | }; 74 | 04765E0A220EAAE2000AC346 /* PageMaster */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 04765E0B220EAAE2000AC346 /* PageMaster.h */, 78 | 04765E0C220EAAE2000AC346 /* Info.plist */, 79 | ); 80 | path = PageMaster; 81 | sourceTree = ""; 82 | }; 83 | 04765E15220EAAE2000AC346 /* PageMasterTests */ = { 84 | isa = PBXGroup; 85 | children = ( 86 | 04765E16220EAAE2000AC346 /* PageMasterTests.swift */, 87 | 04765E18220EAAE2000AC346 /* Info.plist */, 88 | ); 89 | path = PageMasterTests; 90 | sourceTree = ""; 91 | }; 92 | 04765E6E220EABB6000AC346 /* Classes */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 04765E6F220EABC8000AC346 /* PageMaster.swift */, 96 | ); 97 | path = Classes; 98 | sourceTree = ""; 99 | }; 100 | /* End PBXGroup section */ 101 | 102 | /* Begin PBXHeadersBuildPhase section */ 103 | 04765E03220EAAE2000AC346 /* Headers */ = { 104 | isa = PBXHeadersBuildPhase; 105 | buildActionMask = 2147483647; 106 | files = ( 107 | 04765E19220EAAE2000AC346 /* PageMaster.h in Headers */, 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | /* End PBXHeadersBuildPhase section */ 112 | 113 | /* Begin PBXNativeTarget section */ 114 | 04765E07220EAAE2000AC346 /* PageMaster */ = { 115 | isa = PBXNativeTarget; 116 | buildConfigurationList = 04765E1C220EAAE2000AC346 /* Build configuration list for PBXNativeTarget "PageMaster" */; 117 | buildPhases = ( 118 | 04765E03220EAAE2000AC346 /* Headers */, 119 | 04765E04220EAAE2000AC346 /* Sources */, 120 | 04765E05220EAAE2000AC346 /* Frameworks */, 121 | 04765E06220EAAE2000AC346 /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = PageMaster; 128 | productName = PageViewController; 129 | productReference = 04765E08220EAAE2000AC346 /* PageMaster.framework */; 130 | productType = "com.apple.product-type.framework"; 131 | }; 132 | 04765E10220EAAE2000AC346 /* PageMasterTests */ = { 133 | isa = PBXNativeTarget; 134 | buildConfigurationList = 04765E1F220EAAE2000AC346 /* Build configuration list for PBXNativeTarget "PageMasterTests" */; 135 | buildPhases = ( 136 | 04765E0D220EAAE2000AC346 /* Sources */, 137 | 04765E0E220EAAE2000AC346 /* Frameworks */, 138 | 04765E0F220EAAE2000AC346 /* Resources */, 139 | ); 140 | buildRules = ( 141 | ); 142 | dependencies = ( 143 | 04765E14220EAAE2000AC346 /* PBXTargetDependency */, 144 | ); 145 | name = PageMasterTests; 146 | productName = PageViewControllerTests; 147 | productReference = 04765E11220EAAE2000AC346 /* PageMasterTests.xctest */; 148 | productType = "com.apple.product-type.bundle.unit-test"; 149 | }; 150 | /* End PBXNativeTarget section */ 151 | 152 | /* Begin PBXProject section */ 153 | 04765DFF220EAAE2000AC346 /* Project object */ = { 154 | isa = PBXProject; 155 | attributes = { 156 | LastSwiftUpdateCheck = 1010; 157 | LastUpgradeCheck = 1010; 158 | ORGANIZATIONNAME = TomosukeOkada; 159 | TargetAttributes = { 160 | 04765E07220EAAE2000AC346 = { 161 | CreatedOnToolsVersion = 10.1; 162 | LastSwiftMigration = 1010; 163 | }; 164 | 04765E10220EAAE2000AC346 = { 165 | CreatedOnToolsVersion = 10.1; 166 | }; 167 | }; 168 | }; 169 | buildConfigurationList = 04765E02220EAAE2000AC346 /* Build configuration list for PBXProject "PageMaster" */; 170 | compatibilityVersion = "Xcode 9.3"; 171 | developmentRegion = en; 172 | hasScannedForEncodings = 0; 173 | knownRegions = ( 174 | en, 175 | ); 176 | mainGroup = 04765DFE220EAAE2000AC346; 177 | productRefGroup = 04765E09220EAAE2000AC346 /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 04765E07220EAAE2000AC346 /* PageMaster */, 182 | 04765E10220EAAE2000AC346 /* PageMasterTests */, 183 | ); 184 | }; 185 | /* End PBXProject section */ 186 | 187 | /* Begin PBXResourcesBuildPhase section */ 188 | 04765E06220EAAE2000AC346 /* Resources */ = { 189 | isa = PBXResourcesBuildPhase; 190 | buildActionMask = 2147483647; 191 | files = ( 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | 04765E0F220EAAE2000AC346 /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | ); 200 | runOnlyForDeploymentPostprocessing = 0; 201 | }; 202 | /* End PBXResourcesBuildPhase section */ 203 | 204 | /* Begin PBXSourcesBuildPhase section */ 205 | 04765E04220EAAE2000AC346 /* Sources */ = { 206 | isa = PBXSourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 04765E70220EABC8000AC346 /* PageMaster.swift in Sources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | 04765E0D220EAAE2000AC346 /* Sources */ = { 214 | isa = PBXSourcesBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 04765E17220EAAE2000AC346 /* PageMasterTests.swift in Sources */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | /* End PBXSourcesBuildPhase section */ 222 | 223 | /* Begin PBXTargetDependency section */ 224 | 04765E14220EAAE2000AC346 /* PBXTargetDependency */ = { 225 | isa = PBXTargetDependency; 226 | target = 04765E07220EAAE2000AC346 /* PageMaster */; 227 | targetProxy = 04765E13220EAAE2000AC346 /* PBXContainerItemProxy */; 228 | }; 229 | /* End PBXTargetDependency section */ 230 | 231 | /* Begin XCBuildConfiguration section */ 232 | 04765E1A220EAAE2000AC346 /* Debug */ = { 233 | isa = XCBuildConfiguration; 234 | buildSettings = { 235 | ALWAYS_SEARCH_USER_PATHS = NO; 236 | CLANG_ANALYZER_NONNULL = YES; 237 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 238 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 239 | CLANG_CXX_LIBRARY = "libc++"; 240 | CLANG_ENABLE_MODULES = YES; 241 | CLANG_ENABLE_OBJC_ARC = YES; 242 | CLANG_ENABLE_OBJC_WEAK = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 250 | CLANG_WARN_EMPTY_BODY = YES; 251 | CLANG_WARN_ENUM_CONVERSION = YES; 252 | CLANG_WARN_INFINITE_RECURSION = YES; 253 | CLANG_WARN_INT_CONVERSION = YES; 254 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 255 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 256 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 257 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 258 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 259 | CLANG_WARN_STRICT_PROTOTYPES = YES; 260 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 261 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 262 | CLANG_WARN_UNREACHABLE_CODE = YES; 263 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 264 | CODE_SIGN_IDENTITY = "iPhone Developer"; 265 | COPY_PHASE_STRIP = NO; 266 | CURRENT_PROJECT_VERSION = 1; 267 | DEBUG_INFORMATION_FORMAT = dwarf; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | ENABLE_TESTABILITY = YES; 270 | GCC_C_LANGUAGE_STANDARD = gnu11; 271 | GCC_DYNAMIC_NO_PIC = NO; 272 | GCC_NO_COMMON_BLOCKS = YES; 273 | GCC_OPTIMIZATION_LEVEL = 0; 274 | GCC_PREPROCESSOR_DEFINITIONS = ( 275 | "DEBUG=1", 276 | "$(inherited)", 277 | ); 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 285 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 286 | MTL_FAST_MATH = YES; 287 | ONLY_ACTIVE_ARCH = YES; 288 | SDKROOT = iphoneos; 289 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 290 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 291 | VERSIONING_SYSTEM = "apple-generic"; 292 | VERSION_INFO_PREFIX = ""; 293 | }; 294 | name = Debug; 295 | }; 296 | 04765E1B220EAAE2000AC346 /* Release */ = { 297 | isa = XCBuildConfiguration; 298 | buildSettings = { 299 | ALWAYS_SEARCH_USER_PATHS = NO; 300 | CLANG_ANALYZER_NONNULL = YES; 301 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 302 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 303 | CLANG_CXX_LIBRARY = "libc++"; 304 | CLANG_ENABLE_MODULES = YES; 305 | CLANG_ENABLE_OBJC_ARC = YES; 306 | CLANG_ENABLE_OBJC_WEAK = YES; 307 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 308 | CLANG_WARN_BOOL_CONVERSION = YES; 309 | CLANG_WARN_COMMA = YES; 310 | CLANG_WARN_CONSTANT_CONVERSION = YES; 311 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 312 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 313 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 314 | CLANG_WARN_EMPTY_BODY = YES; 315 | CLANG_WARN_ENUM_CONVERSION = YES; 316 | CLANG_WARN_INFINITE_RECURSION = YES; 317 | CLANG_WARN_INT_CONVERSION = YES; 318 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 319 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 320 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 321 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 322 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 323 | CLANG_WARN_STRICT_PROTOTYPES = YES; 324 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 325 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 326 | CLANG_WARN_UNREACHABLE_CODE = YES; 327 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 328 | CODE_SIGN_IDENTITY = "iPhone Developer"; 329 | COPY_PHASE_STRIP = NO; 330 | CURRENT_PROJECT_VERSION = 1; 331 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 332 | ENABLE_NS_ASSERTIONS = NO; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | GCC_C_LANGUAGE_STANDARD = gnu11; 335 | GCC_NO_COMMON_BLOCKS = YES; 336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 338 | GCC_WARN_UNDECLARED_SELECTOR = YES; 339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 340 | GCC_WARN_UNUSED_FUNCTION = YES; 341 | GCC_WARN_UNUSED_VARIABLE = YES; 342 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 343 | MTL_ENABLE_DEBUG_INFO = NO; 344 | MTL_FAST_MATH = YES; 345 | SDKROOT = iphoneos; 346 | SWIFT_COMPILATION_MODE = wholemodule; 347 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 348 | VALIDATE_PRODUCT = YES; 349 | VERSIONING_SYSTEM = "apple-generic"; 350 | VERSION_INFO_PREFIX = ""; 351 | }; 352 | name = Release; 353 | }; 354 | 04765E1D220EAAE2000AC346 /* Debug */ = { 355 | isa = XCBuildConfiguration; 356 | buildSettings = { 357 | CLANG_ENABLE_MODULES = YES; 358 | CODE_SIGN_IDENTITY = "iPhone Developer"; 359 | CODE_SIGN_STYLE = Automatic; 360 | DEFINES_MODULE = YES; 361 | DEVELOPMENT_TEAM = NG4PAUE398; 362 | DYLIB_COMPATIBILITY_VERSION = 1; 363 | DYLIB_CURRENT_VERSION = 1; 364 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 365 | INFOPLIST_FILE = "$(SRCROOT)/PageMaster/Info.plist"; 366 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 367 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 368 | LD_RUNPATH_SEARCH_PATHS = ( 369 | "$(inherited)", 370 | "@executable_path/Frameworks", 371 | "@loader_path/Frameworks", 372 | ); 373 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.PageMaster; 374 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 375 | SKIP_INSTALL = YES; 376 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 377 | SWIFT_VERSION = 4.2; 378 | TARGETED_DEVICE_FAMILY = "1,2"; 379 | }; 380 | name = Debug; 381 | }; 382 | 04765E1E220EAAE2000AC346 /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | CLANG_ENABLE_MODULES = YES; 386 | CODE_SIGN_IDENTITY = ""; 387 | CODE_SIGN_STYLE = Automatic; 388 | DEFINES_MODULE = YES; 389 | DEVELOPMENT_TEAM = NG4PAUE398; 390 | DYLIB_COMPATIBILITY_VERSION = 1; 391 | DYLIB_CURRENT_VERSION = 1; 392 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 393 | INFOPLIST_FILE = "$(SRCROOT)/PageMaster/Info.plist"; 394 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 395 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 396 | LD_RUNPATH_SEARCH_PATHS = ( 397 | "$(inherited)", 398 | "@executable_path/Frameworks", 399 | "@loader_path/Frameworks", 400 | ); 401 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.PageMaster; 402 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 403 | SKIP_INSTALL = YES; 404 | SWIFT_VERSION = 4.2; 405 | TARGETED_DEVICE_FAMILY = "1,2"; 406 | }; 407 | name = Release; 408 | }; 409 | 04765E20220EAAE2000AC346 /* Debug */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 413 | CODE_SIGN_STYLE = Automatic; 414 | INFOPLIST_FILE = PageViewControllerTests/Info.plist; 415 | LD_RUNPATH_SEARCH_PATHS = ( 416 | "$(inherited)", 417 | "@executable_path/Frameworks", 418 | "@loader_path/Frameworks", 419 | ); 420 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.PageViewControllerTests; 421 | PRODUCT_NAME = "$(TARGET_NAME)"; 422 | SWIFT_VERSION = 4.2; 423 | TARGETED_DEVICE_FAMILY = "1,2"; 424 | }; 425 | name = Debug; 426 | }; 427 | 04765E21220EAAE2000AC346 /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 431 | CODE_SIGN_STYLE = Automatic; 432 | INFOPLIST_FILE = PageViewControllerTests/Info.plist; 433 | LD_RUNPATH_SEARCH_PATHS = ( 434 | "$(inherited)", 435 | "@executable_path/Frameworks", 436 | "@loader_path/Frameworks", 437 | ); 438 | PRODUCT_BUNDLE_IDENTIFIER = TomosukeOkada.PageViewControllerTests; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | SWIFT_VERSION = 4.2; 441 | TARGETED_DEVICE_FAMILY = "1,2"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 04765E02220EAAE2000AC346 /* Build configuration list for PBXProject "PageMaster" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 04765E1A220EAAE2000AC346 /* Debug */, 452 | 04765E1B220EAAE2000AC346 /* Release */, 453 | ); 454 | defaultConfigurationIsVisible = 0; 455 | defaultConfigurationName = Release; 456 | }; 457 | 04765E1C220EAAE2000AC346 /* Build configuration list for PBXNativeTarget "PageMaster" */ = { 458 | isa = XCConfigurationList; 459 | buildConfigurations = ( 460 | 04765E1D220EAAE2000AC346 /* Debug */, 461 | 04765E1E220EAAE2000AC346 /* Release */, 462 | ); 463 | defaultConfigurationIsVisible = 0; 464 | defaultConfigurationName = Release; 465 | }; 466 | 04765E1F220EAAE2000AC346 /* Build configuration list for PBXNativeTarget "PageMasterTests" */ = { 467 | isa = XCConfigurationList; 468 | buildConfigurations = ( 469 | 04765E20220EAAE2000AC346 /* Debug */, 470 | 04765E21220EAAE2000AC346 /* Release */, 471 | ); 472 | defaultConfigurationIsVisible = 0; 473 | defaultConfigurationName = Release; 474 | }; 475 | /* End XCConfigurationList section */ 476 | }; 477 | rootObject = 04765DFF220EAAE2000AC346 /* Project object */; 478 | } 479 | -------------------------------------------------------------------------------- /PageMaster.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PageMaster.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PageMaster.xcodeproj/xcshareddata/xcschemes/PageMaster.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /PageMaster/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | PageMaster 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | 24 | 25 | -------------------------------------------------------------------------------- /PageMaster/PageMaster.h: -------------------------------------------------------------------------------- 1 | // 2 | // PageMaster.h 3 | // PageMaster 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | /** 10 | [PageMaster] 11 | 12 | Copyright (c) [2019] [Tomosuke Okada] 13 | 14 | This software is released under the MIT License. 15 | http://opensource.org/licenses/mit-license.ph 16 | */ 17 | 18 | #import 19 | 20 | //! Project version number for PageViewController. 21 | FOUNDATION_EXPORT double PageViewControllerVersionNumber; 22 | 23 | //! Project version string for PageViewController. 24 | FOUNDATION_EXPORT const unsigned char PageViewControllerVersionString[]; 25 | 26 | // In this header, you should import all the public headers of your framework using statements like #import 27 | 28 | 29 | -------------------------------------------------------------------------------- /PageMasterTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PageMasterTests/PageMasterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PageMasterTests.swift 3 | // PageMaster 4 | // 5 | // Created by Tomosuke Okada on 2019/02/09. 6 | // Copyright © 2019 TomosukeOkada. All rights reserved. 7 | // 8 | 9 | /** 10 | [PageMaster] 11 | 12 | Copyright (c) [2019] [Tomosuke Okada] 13 | 14 | This software is released under the MIT License. 15 | http://opensource.org/licenses/mit-license.ph 16 | */ 17 | 18 | import XCTest 19 | @testable import PageMaster 20 | 21 | class PageMasterTests: XCTestCase { 22 | 23 | override func setUp() { 24 | // Put setup code here. This method is called before the invocation of each test method in the class. 25 | } 26 | 27 | override func tearDown() { 28 | // Put teardown code here. This method is called after the invocation of each test method in the class. 29 | } 30 | 31 | func testExample() { 32 | // This is an example of a functional test case. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | func testPerformanceExample() { 37 | // This is an example of a performance test case. 38 | self.measure { 39 | // Put the code you want to measure the time of here. 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PageMaster 2 | 3 | ## Description 4 | PageMaster is a wrapper class for easier use of UIPageViewController. 5 | 6 | ## Feature 7 | - Easier than UIPageViewController 8 | - Infinite paging 9 | 10 | ## Requirements 11 | - iOS 8.0+ 12 | - Xcode 10.1+ 13 | - Swift 4.2+ 14 | 15 | ## Demo 16 | ![PageMaster](https://user-images.githubusercontent.com/20692907/52523149-86087900-2cd1-11e9-8acc-085115bef937.gif) 17 | 18 | ## Usage 19 | 20 | ### Setup 21 | ```swift 22 | import PageMaster 23 | 24 | private let pageMaster = PageMaster([]) 25 | 26 | private func setupPageMaster() { 27 | self.pageMaster.pageDelegate = self 28 | let vcList: [UIViewController] = [ /** Set your UIViewControllers */ ] 29 | self.pageMaster.setup(vcList) 30 | self.addChild(self.pageMaster) 31 | self.view.addSubview(self.pageMaster.view) 32 | self.pageMaster.view.frame = self.view.bounds 33 | self.pageMaster.didMove(toParent: self) 34 | } 35 | ``` 36 | 37 | ### PageDelegate 38 | ```swift 39 | extension ViewController: PageMasterDelegate { 40 | 41 | func pageMaster(_ master: PageMaster, didChangePage page: Int) { 42 | // Here you can create a process after changing the page. 43 | } 44 | } 45 | ``` 46 | 47 | ## Install 48 | 49 | ### CocoaPods 50 | Add this to your Podfile. 51 | 52 | ```PodFile 53 | pod 'PageMaster' 54 | ``` 55 | 56 | ### Carthage 57 | Add this to your Cartfile. 58 | 59 | ```Cartfile 60 | github "PKPK-Carnage/PageMaster" 61 | ``` 62 | 63 | ## Help 64 | 65 | If you want to support this framework, you can do these things. 66 | 67 | - Please let us know if you have any requests for me. 68 | 69 | I will do my best to live up to your expectations. 70 | 71 | - You can make contribute code, issues and pull requests. 72 | 73 | I promise to confirm them. 74 | 75 | ## Licence 76 | 77 | [MIT](https://github.com/PKPK-Carnage/PageViewController/blob/master/LICENSE) 78 | 79 | ## Author 80 | 81 | [PKPK-Carnage🦎](https://github.com/PKPK-Carnage) 82 | --------------------------------------------------------------------------------