├── .gitignore
├── .swift-version
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── Example
├── Example.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Example
│ ├── AppDelegate.swift
│ ├── Dummies
│ ├── DummyCell.swift
│ ├── DummyController.swift
│ └── MiddleView.swift
│ ├── Resources
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ ├── Contents.json
│ │ │ ├── Ramotion.png
│ │ │ ├── icon-120.png
│ │ │ ├── icon-152.png
│ │ │ ├── icon-167.png
│ │ │ ├── icon-180.png
│ │ │ ├── icon-20.png
│ │ │ ├── icon-29.png
│ │ │ ├── icon-40.png
│ │ │ ├── icon-58.png
│ │ │ ├── icon-60.png
│ │ │ ├── icon-76.png
│ │ │ ├── icon-80.png
│ │ │ └── icon-87.png
│ │ ├── Contents.json
│ │ ├── background.imageset
│ │ │ ├── Contents.json
│ │ │ ├── collection_bg-1.png
│ │ │ ├── collection_bg-2.png
│ │ │ └── collection_bg.png
│ │ └── controllers
│ │ │ ├── Contents.json
│ │ │ ├── image1.imageset
│ │ │ ├── Contents.json
│ │ │ └── image1.jpeg
│ │ │ ├── image10.imageset
│ │ │ ├── Contents.json
│ │ │ └── image10.jpeg
│ │ │ ├── image11.imageset
│ │ │ ├── Contents.json
│ │ │ └── image11.jpeg
│ │ │ ├── image12.imageset
│ │ │ ├── Contents.json
│ │ │ └── image12.jpeg
│ │ │ ├── image13.imageset
│ │ │ ├── Contents.json
│ │ │ └── image13.jpeg
│ │ │ ├── image14.imageset
│ │ │ ├── Contents.json
│ │ │ └── image14.jpeg
│ │ │ ├── image15.imageset
│ │ │ ├── Contents.json
│ │ │ └── image15.jpeg
│ │ │ ├── image2.imageset
│ │ │ ├── Contents.json
│ │ │ └── image2.jpeg
│ │ │ ├── image3.imageset
│ │ │ ├── Contents.json
│ │ │ └── image3.jpeg
│ │ │ ├── image4.imageset
│ │ │ ├── Contents.json
│ │ │ └── image4.jpeg
│ │ │ ├── image5.imageset
│ │ │ ├── Contents.json
│ │ │ └── image5.jpeg
│ │ │ ├── image6.imageset
│ │ │ ├── Contents.json
│ │ │ └── image6.jpeg
│ │ │ ├── image7.imageset
│ │ │ ├── Contents.json
│ │ │ └── image7.jpeg
│ │ │ ├── image8.imageset
│ │ │ ├── Contents.json
│ │ │ └── image8.jpeg
│ │ │ └── image9.imageset
│ │ │ ├── Contents.json
│ │ │ └── image9.jpeg
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
│ ├── Utilities
│ └── UIColor+HEX.swift
│ └── ViewController.swift
├── LICENSE
├── Navigation-Toolbar.podspec
├── NavigationToolbar.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── xcshareddata
│ └── xcschemes
│ └── NavigationToolbar.xcscheme
├── Package.swift
├── README.md
├── Sources
├── Components
│ ├── Label.swift
│ └── PanDirectionGestureRecognizer.swift
├── Extensions
│ └── UIImage+gradient.swift
├── Info.plist
├── NavigationToolbar.h
├── NavigationView.swift
├── Objects
│ └── ScreenObject.swift
├── Settings
│ └── Settings.swift
└── SubViews
│ ├── BottomView
│ └── BottomView.swift
│ ├── FullscreenView
│ ├── CellView.swift
│ ├── FulllscreenView.swift
│ └── LabelView.swift
│ └── TopView
│ ├── SizingView.swift
│ ├── TopView.swift
│ ├── TopViewAnimators.swift
│ ├── TopViewCells.swift
│ └── TopViewCollectionLayout.swift
├── header.png
└── iOS-Navigation-Toolbar-1x.gif
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | .build/
41 |
42 | # CocoaPods
43 | #
44 | # We recommend against adding the Pods directory to your .gitignore. However
45 | # you should judge for yourself, the pros and cons are mentioned at:
46 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
47 | #
48 | # Pods/
49 |
50 | # Carthage
51 | #
52 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
53 | # Carthage/Checkouts
54 |
55 | Carthage/Build
56 |
57 | # fastlane
58 | #
59 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
60 | # screenshots whenever they are needed.
61 | # For more information about the recommended setup visit:
62 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
63 |
64 | fastlane/report.xml
65 | fastlane/Preview.html
66 | fastlane/screenshots
67 | fastlane/test_output
68 | /NavigationToolBar/.DS_Store
69 | .DS_Store
70 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.1
2 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 393FDA3321132D6A00909225 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FDA2821132D6A00909225 /* ViewController.swift */; };
11 | 393FDA3421132D6A00909225 /* UIColor+HEX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FDA2921132D6A00909225 /* UIColor+HEX.swift */; };
12 | 393FDA3521132D6A00909225 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 393FDA2A21132D6A00909225 /* Assets.xcassets */; };
13 | 393FDA3621132D6A00909225 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 393FDA2B21132D6A00909225 /* LaunchScreen.storyboard */; };
14 | 393FDA3821132D6A00909225 /* DummyController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FDA2F21132D6A00909225 /* DummyController.swift */; };
15 | 393FDA3921132D6A00909225 /* DummyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FDA3021132D6A00909225 /* DummyCell.swift */; };
16 | 393FDA3A21132D6A00909225 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FDA3121132D6A00909225 /* AppDelegate.swift */; };
17 | 393FDA4421132F6200909225 /* NavigationToolbar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 393FDA4321132F5800909225 /* NavigationToolbar.framework */; };
18 | 393FDA4521132F6200909225 /* NavigationToolbar.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 393FDA4321132F5800909225 /* NavigationToolbar.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
19 | EE32E8C42119A85C00193C32 /* MiddleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE32E8C32119A85C00193C32 /* MiddleView.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 393FDA4221132F5800909225 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 393FDA3E21132F5700909225 /* NavigationToolbar.xcodeproj */;
26 | proxyType = 2;
27 | remoteGlobalIDString = 393FD9CF21132AD000909225;
28 | remoteInfo = NavigationToolbar;
29 | };
30 | 393FDA4621132F6200909225 /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 393FDA3E21132F5700909225 /* NavigationToolbar.xcodeproj */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 393FD9CE21132AD000909225;
35 | remoteInfo = NavigationToolbar;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXCopyFilesBuildPhase section */
40 | 393FDA4821132F6200909225 /* Embed Frameworks */ = {
41 | isa = PBXCopyFilesBuildPhase;
42 | buildActionMask = 2147483647;
43 | dstPath = "";
44 | dstSubfolderSpec = 10;
45 | files = (
46 | 393FDA4521132F6200909225 /* NavigationToolbar.framework in Embed Frameworks */,
47 | );
48 | name = "Embed Frameworks";
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | /* End PBXCopyFilesBuildPhase section */
52 |
53 | /* Begin PBXFileReference section */
54 | 393FDA1221132D2900909225 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
55 | 393FDA2821132D6A00909225 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
56 | 393FDA2921132D6A00909225 /* UIColor+HEX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+HEX.swift"; sourceTree = ""; };
57 | 393FDA2A21132D6A00909225 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
58 | 393FDA2C21132D6A00909225 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
59 | 393FDA2F21132D6A00909225 /* DummyController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DummyController.swift; sourceTree = ""; };
60 | 393FDA3021132D6A00909225 /* DummyCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DummyCell.swift; sourceTree = ""; };
61 | 393FDA3121132D6A00909225 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
62 | 393FDA3221132D6A00909225 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
63 | 393FDA3E21132F5700909225 /* NavigationToolbar.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = NavigationToolbar.xcodeproj; path = ../NavigationToolbar.xcodeproj; sourceTree = ""; };
64 | EE32E8C32119A85C00193C32 /* MiddleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MiddleView.swift; sourceTree = ""; };
65 | /* End PBXFileReference section */
66 |
67 | /* Begin PBXFrameworksBuildPhase section */
68 | 393FDA0F21132D2900909225 /* Frameworks */ = {
69 | isa = PBXFrameworksBuildPhase;
70 | buildActionMask = 2147483647;
71 | files = (
72 | 393FDA4421132F6200909225 /* NavigationToolbar.framework in Frameworks */,
73 | );
74 | runOnlyForDeploymentPostprocessing = 0;
75 | };
76 | /* End PBXFrameworksBuildPhase section */
77 |
78 | /* Begin PBXGroup section */
79 | 393FDA0921132D2900909225 = {
80 | isa = PBXGroup;
81 | children = (
82 | 393FDA2721132D6A00909225 /* Example */,
83 | 393FDA1321132D2900909225 /* Products */,
84 | 393FDA3E21132F5700909225 /* NavigationToolbar.xcodeproj */,
85 | );
86 | sourceTree = "";
87 | };
88 | 393FDA1321132D2900909225 /* Products */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 393FDA1221132D2900909225 /* Example.app */,
92 | );
93 | name = Products;
94 | sourceTree = "";
95 | };
96 | 393FDA2721132D6A00909225 /* Example */ = {
97 | isa = PBXGroup;
98 | children = (
99 | 393FDA3121132D6A00909225 /* AppDelegate.swift */,
100 | 393FDA2821132D6A00909225 /* ViewController.swift */,
101 | 393FDA3D21132F2600909225 /* Utilities */,
102 | 393FDA3C21132DD200909225 /* Resources */,
103 | 393FDA2E21132D6A00909225 /* Dummies */,
104 | );
105 | path = Example;
106 | sourceTree = "";
107 | };
108 | 393FDA2E21132D6A00909225 /* Dummies */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 393FDA2F21132D6A00909225 /* DummyController.swift */,
112 | 393FDA3021132D6A00909225 /* DummyCell.swift */,
113 | EE32E8C32119A85C00193C32 /* MiddleView.swift */,
114 | );
115 | path = Dummies;
116 | sourceTree = "";
117 | };
118 | 393FDA3C21132DD200909225 /* Resources */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 393FDA2A21132D6A00909225 /* Assets.xcassets */,
122 | 393FDA2B21132D6A00909225 /* LaunchScreen.storyboard */,
123 | 393FDA3221132D6A00909225 /* Info.plist */,
124 | );
125 | path = Resources;
126 | sourceTree = "";
127 | };
128 | 393FDA3D21132F2600909225 /* Utilities */ = {
129 | isa = PBXGroup;
130 | children = (
131 | 393FDA2921132D6A00909225 /* UIColor+HEX.swift */,
132 | );
133 | path = Utilities;
134 | sourceTree = "";
135 | };
136 | 393FDA3F21132F5700909225 /* Products */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 393FDA4321132F5800909225 /* NavigationToolbar.framework */,
140 | );
141 | name = Products;
142 | sourceTree = "";
143 | };
144 | /* End PBXGroup section */
145 |
146 | /* Begin PBXNativeTarget section */
147 | 393FDA1121132D2900909225 /* Example */ = {
148 | isa = PBXNativeTarget;
149 | buildConfigurationList = 393FDA2421132D2B00909225 /* Build configuration list for PBXNativeTarget "Example" */;
150 | buildPhases = (
151 | 393FDA0E21132D2900909225 /* Sources */,
152 | 393FDA0F21132D2900909225 /* Frameworks */,
153 | 393FDA1021132D2900909225 /* Resources */,
154 | 393FDA4821132F6200909225 /* Embed Frameworks */,
155 | );
156 | buildRules = (
157 | );
158 | dependencies = (
159 | 393FDA4721132F6200909225 /* PBXTargetDependency */,
160 | );
161 | name = Example;
162 | productName = Example;
163 | productReference = 393FDA1221132D2900909225 /* Example.app */;
164 | productType = "com.apple.product-type.application";
165 | };
166 | /* End PBXNativeTarget section */
167 |
168 | /* Begin PBXProject section */
169 | 393FDA0A21132D2900909225 /* Project object */ = {
170 | isa = PBXProject;
171 | attributes = {
172 | LastSwiftUpdateCheck = 0940;
173 | LastUpgradeCheck = 0940;
174 | ORGANIZATIONNAME = Ramotion;
175 | TargetAttributes = {
176 | 393FDA1121132D2900909225 = {
177 | CreatedOnToolsVersion = 9.4.1;
178 | };
179 | };
180 | };
181 | buildConfigurationList = 393FDA0D21132D2900909225 /* Build configuration list for PBXProject "Example" */;
182 | compatibilityVersion = "Xcode 9.3";
183 | developmentRegion = en;
184 | hasScannedForEncodings = 0;
185 | knownRegions = (
186 | en,
187 | Base,
188 | );
189 | mainGroup = 393FDA0921132D2900909225;
190 | productRefGroup = 393FDA1321132D2900909225 /* Products */;
191 | projectDirPath = "";
192 | projectReferences = (
193 | {
194 | ProductGroup = 393FDA3F21132F5700909225 /* Products */;
195 | ProjectRef = 393FDA3E21132F5700909225 /* NavigationToolbar.xcodeproj */;
196 | },
197 | );
198 | projectRoot = "";
199 | targets = (
200 | 393FDA1121132D2900909225 /* Example */,
201 | );
202 | };
203 | /* End PBXProject section */
204 |
205 | /* Begin PBXReferenceProxy section */
206 | 393FDA4321132F5800909225 /* NavigationToolbar.framework */ = {
207 | isa = PBXReferenceProxy;
208 | fileType = wrapper.framework;
209 | path = NavigationToolbar.framework;
210 | remoteRef = 393FDA4221132F5800909225 /* PBXContainerItemProxy */;
211 | sourceTree = BUILT_PRODUCTS_DIR;
212 | };
213 | /* End PBXReferenceProxy section */
214 |
215 | /* Begin PBXResourcesBuildPhase section */
216 | 393FDA1021132D2900909225 /* Resources */ = {
217 | isa = PBXResourcesBuildPhase;
218 | buildActionMask = 2147483647;
219 | files = (
220 | 393FDA3521132D6A00909225 /* Assets.xcassets in Resources */,
221 | 393FDA3621132D6A00909225 /* LaunchScreen.storyboard in Resources */,
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | };
225 | /* End PBXResourcesBuildPhase section */
226 |
227 | /* Begin PBXSourcesBuildPhase section */
228 | 393FDA0E21132D2900909225 /* Sources */ = {
229 | isa = PBXSourcesBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | 393FDA3821132D6A00909225 /* DummyController.swift in Sources */,
233 | 393FDA3921132D6A00909225 /* DummyCell.swift in Sources */,
234 | 393FDA3321132D6A00909225 /* ViewController.swift in Sources */,
235 | EE32E8C42119A85C00193C32 /* MiddleView.swift in Sources */,
236 | 393FDA3A21132D6A00909225 /* AppDelegate.swift in Sources */,
237 | 393FDA3421132D6A00909225 /* UIColor+HEX.swift in Sources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXSourcesBuildPhase section */
242 |
243 | /* Begin PBXTargetDependency section */
244 | 393FDA4721132F6200909225 /* PBXTargetDependency */ = {
245 | isa = PBXTargetDependency;
246 | name = NavigationToolbar;
247 | targetProxy = 393FDA4621132F6200909225 /* PBXContainerItemProxy */;
248 | };
249 | /* End PBXTargetDependency section */
250 |
251 | /* Begin PBXVariantGroup section */
252 | 393FDA2B21132D6A00909225 /* LaunchScreen.storyboard */ = {
253 | isa = PBXVariantGroup;
254 | children = (
255 | 393FDA2C21132D6A00909225 /* Base */,
256 | );
257 | name = LaunchScreen.storyboard;
258 | sourceTree = "";
259 | };
260 | /* End PBXVariantGroup section */
261 |
262 | /* Begin XCBuildConfiguration section */
263 | 393FDA2221132D2B00909225 /* Debug */ = {
264 | isa = XCBuildConfiguration;
265 | buildSettings = {
266 | ALWAYS_SEARCH_USER_PATHS = NO;
267 | CLANG_ANALYZER_NONNULL = YES;
268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
270 | CLANG_CXX_LIBRARY = "libc++";
271 | CLANG_ENABLE_MODULES = YES;
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | CLANG_ENABLE_OBJC_WEAK = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
281 | CLANG_WARN_EMPTY_BODY = YES;
282 | CLANG_WARN_ENUM_CONVERSION = YES;
283 | CLANG_WARN_INFINITE_RECURSION = YES;
284 | CLANG_WARN_INT_CONVERSION = YES;
285 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
287 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
289 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
290 | CLANG_WARN_STRICT_PROTOTYPES = YES;
291 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
292 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
293 | CLANG_WARN_UNREACHABLE_CODE = YES;
294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
295 | CODE_SIGN_IDENTITY = "iPhone Developer";
296 | COPY_PHASE_STRIP = NO;
297 | DEBUG_INFORMATION_FORMAT = dwarf;
298 | ENABLE_STRICT_OBJC_MSGSEND = YES;
299 | ENABLE_TESTABILITY = YES;
300 | GCC_C_LANGUAGE_STANDARD = gnu11;
301 | GCC_DYNAMIC_NO_PIC = NO;
302 | GCC_NO_COMMON_BLOCKS = YES;
303 | GCC_OPTIMIZATION_LEVEL = 0;
304 | GCC_PREPROCESSOR_DEFINITIONS = (
305 | "DEBUG=1",
306 | "$(inherited)",
307 | );
308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
310 | GCC_WARN_UNDECLARED_SELECTOR = YES;
311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
312 | GCC_WARN_UNUSED_FUNCTION = YES;
313 | GCC_WARN_UNUSED_VARIABLE = YES;
314 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
315 | MTL_ENABLE_DEBUG_INFO = YES;
316 | ONLY_ACTIVE_ARCH = YES;
317 | SDKROOT = iphoneos;
318 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
319 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
320 | };
321 | name = Debug;
322 | };
323 | 393FDA2321132D2B00909225 /* Release */ = {
324 | isa = XCBuildConfiguration;
325 | buildSettings = {
326 | ALWAYS_SEARCH_USER_PATHS = NO;
327 | CLANG_ANALYZER_NONNULL = YES;
328 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
329 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
330 | CLANG_CXX_LIBRARY = "libc++";
331 | CLANG_ENABLE_MODULES = YES;
332 | CLANG_ENABLE_OBJC_ARC = YES;
333 | CLANG_ENABLE_OBJC_WEAK = YES;
334 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
335 | CLANG_WARN_BOOL_CONVERSION = YES;
336 | CLANG_WARN_COMMA = YES;
337 | CLANG_WARN_CONSTANT_CONVERSION = YES;
338 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
340 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
341 | CLANG_WARN_EMPTY_BODY = YES;
342 | CLANG_WARN_ENUM_CONVERSION = YES;
343 | CLANG_WARN_INFINITE_RECURSION = YES;
344 | CLANG_WARN_INT_CONVERSION = YES;
345 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
346 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
347 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
348 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
349 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
350 | CLANG_WARN_STRICT_PROTOTYPES = YES;
351 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
352 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
353 | CLANG_WARN_UNREACHABLE_CODE = YES;
354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
355 | CODE_SIGN_IDENTITY = "iPhone Developer";
356 | COPY_PHASE_STRIP = NO;
357 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
358 | ENABLE_NS_ASSERTIONS = NO;
359 | ENABLE_STRICT_OBJC_MSGSEND = YES;
360 | GCC_C_LANGUAGE_STANDARD = gnu11;
361 | GCC_NO_COMMON_BLOCKS = YES;
362 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
363 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
364 | GCC_WARN_UNDECLARED_SELECTOR = YES;
365 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
366 | GCC_WARN_UNUSED_FUNCTION = YES;
367 | GCC_WARN_UNUSED_VARIABLE = YES;
368 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
369 | MTL_ENABLE_DEBUG_INFO = NO;
370 | SDKROOT = iphoneos;
371 | SWIFT_COMPILATION_MODE = wholemodule;
372 | SWIFT_OPTIMIZATION_LEVEL = "-O";
373 | VALIDATE_PRODUCT = YES;
374 | };
375 | name = Release;
376 | };
377 | 393FDA2521132D2B00909225 /* Debug */ = {
378 | isa = XCBuildConfiguration;
379 | buildSettings = {
380 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
381 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
382 | CODE_SIGN_STYLE = Automatic;
383 | DEVELOPMENT_TEAM = 34MUF9YXTA;
384 | INFOPLIST_FILE = Example/Resources/Info.plist;
385 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
386 | LD_RUNPATH_SEARCH_PATHS = (
387 | "$(inherited)",
388 | "@executable_path/Frameworks",
389 | );
390 | PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.Example;
391 | PRODUCT_NAME = "$(TARGET_NAME)";
392 | SWIFT_VERSION = 5.0;
393 | TARGETED_DEVICE_FAMILY = "1,2";
394 | };
395 | name = Debug;
396 | };
397 | 393FDA2621132D2B00909225 /* Release */ = {
398 | isa = XCBuildConfiguration;
399 | buildSettings = {
400 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
401 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
402 | CODE_SIGN_STYLE = Automatic;
403 | DEVELOPMENT_TEAM = 34MUF9YXTA;
404 | INFOPLIST_FILE = Example/Resources/Info.plist;
405 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
406 | LD_RUNPATH_SEARCH_PATHS = (
407 | "$(inherited)",
408 | "@executable_path/Frameworks",
409 | );
410 | PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.Example;
411 | PRODUCT_NAME = "$(TARGET_NAME)";
412 | SWIFT_VERSION = 5.0;
413 | TARGETED_DEVICE_FAMILY = "1,2";
414 | };
415 | name = Release;
416 | };
417 | /* End XCBuildConfiguration section */
418 |
419 | /* Begin XCConfigurationList section */
420 | 393FDA0D21132D2900909225 /* Build configuration list for PBXProject "Example" */ = {
421 | isa = XCConfigurationList;
422 | buildConfigurations = (
423 | 393FDA2221132D2B00909225 /* Debug */,
424 | 393FDA2321132D2B00909225 /* Release */,
425 | );
426 | defaultConfigurationIsVisible = 0;
427 | defaultConfigurationName = Release;
428 | };
429 | 393FDA2421132D2B00909225 /* Build configuration list for PBXNativeTarget "Example" */ = {
430 | isa = XCConfigurationList;
431 | buildConfigurations = (
432 | 393FDA2521132D2B00909225 /* Debug */,
433 | 393FDA2621132D2B00909225 /* Release */,
434 | );
435 | defaultConfigurationIsVisible = 0;
436 | defaultConfigurationName = Release;
437 | };
438 | /* End XCConfigurationList section */
439 | };
440 | rootObject = 393FDA0A21132D2900909225 /* Project object */;
441 | }
442 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 21/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 |
18 | window?.rootViewController = ViewController()
19 | window?.makeKeyAndVisible()
20 |
21 | return true
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Example/Example/Dummies/DummyCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DummyView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DummyCell: UITableViewCell {
12 |
13 | private var avatarImageView = UIImageView()
14 | private var titleLabel = UILabel()
15 | private var subtitleLabel = UILabel()
16 | private var separatorView = UIView()
17 | private var contentImageView = UIImageView()
18 |
19 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
20 | super.init(style: style, reuseIdentifier: reuseIdentifier)
21 | setup()
22 | }
23 |
24 | required init?(coder aDecoder: NSCoder) {
25 | super.init(coder: aDecoder)
26 | setup()
27 | }
28 |
29 | override func awakeFromNib() {
30 |
31 | }
32 |
33 | private func setup() {
34 | avatarImageView.contentMode = .scaleAspectFill
35 | avatarImageView.clipsToBounds = true
36 | avatarImageView.layer.cornerRadius = 4.0
37 |
38 | contentImageView.contentMode = .scaleAspectFill
39 | contentImageView.clipsToBounds = true
40 | contentImageView.layer.cornerRadius = 4.0
41 |
42 | titleLabel.font = UIFont.systemFont(ofSize: 15)
43 | titleLabel.textColor = UIColor.darkText
44 |
45 | subtitleLabel.font = UIFont.systemFont(ofSize: 13)
46 | subtitleLabel.textColor = UIColor.gray
47 |
48 | separatorView.backgroundColor = UIColor.gray
49 | separatorView.alpha = 0.5
50 |
51 | addSubview(avatarImageView)
52 | addSubview(titleLabel)
53 | addSubview(subtitleLabel)
54 | addSubview(separatorView)
55 | addSubview(contentImageView)
56 | }
57 |
58 | override func layoutSubviews() {
59 | super.layoutSubviews()
60 |
61 | let w = bounds.width
62 |
63 | avatarImageView.frame = CGRect(x: 16, y: 16, width: 40, height: 40)
64 | titleLabel.frame = CGRect(x: avatarImageView.frame.maxX + 16, y: 16, width: w - 40 - 48, height: 20)
65 | subtitleLabel.frame = CGRect(x: avatarImageView.frame.maxX + 16, y: titleLabel.frame.maxY, width: w - 40 - 48, height: 20)
66 | separatorView.frame = CGRect(x: 16, y: avatarImageView.frame.maxY + 16, width: w - 32, height: 0.5)
67 | contentImageView.frame = CGRect(x: 16, y: separatorView.frame.maxY + 8, width: w - 32, height: 250)
68 | }
69 |
70 | func setData(avatar: UIImage, title: String, subtitle: String, content: UIImage) {
71 | avatarImageView.image = avatar
72 | titleLabel.text = title
73 | subtitleLabel.text = subtitle
74 | contentImageView.image = content
75 | }
76 |
77 | override func setSelected(_ selected: Bool, animated: Bool) {
78 | selectionStyle = .none
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Example/Example/Dummies/DummyController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DummyController.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class DummyController: UIViewController {
12 |
13 | private var tableView = UITableView()
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | view.backgroundColor = UIColor.black
19 |
20 | tableView.delegate = self
21 | tableView.dataSource = self
22 | tableView.register(DummyCell.self, forCellReuseIdentifier: String(describing: DummyCell.self))
23 | tableView.separatorColor = .clear
24 | tableView.bounces = false
25 |
26 | view.addSubview(tableView)
27 | }
28 |
29 | override func viewDidLayoutSubviews() {
30 | super.viewDidLayoutSubviews()
31 | tableView.frame = view.bounds
32 | }
33 | }
34 |
35 | extension DummyController: UITableViewDelegate, UITableViewDataSource {
36 |
37 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
38 | return 100
39 | }
40 |
41 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
42 | let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: DummyCell.self), for: indexPath) as! DummyCell
43 | cell.setData(avatar: UIImage(named: "image14")!, title: "Jellyfish Cam offers Stunning Views", subtitle: "3k views • 5 days ago", content: UIImage(named: "image13")!)
44 |
45 | return cell
46 | }
47 |
48 | func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
49 | return 350
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Example/Example/Dummies/MiddleView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MiddleView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MiddleView: UIView {
12 |
13 | private var separatorView = UIView()
14 | private var leftButton = UIButton()
15 | private var rightButton = UIButton()
16 |
17 | override init(frame: CGRect) {
18 | super.init(frame: frame)
19 | setup()
20 | }
21 |
22 | required init?(coder aDecoder: NSCoder) {
23 | super.init(coder: aDecoder)
24 | setup()
25 | }
26 |
27 | private func setup() {
28 | backgroundColor = .white
29 |
30 | layer.shadowColor = UIColor.black.cgColor
31 | layer.shadowRadius = 10.0
32 | layer.shadowOpacity = 0.1
33 | layer.shadowOffset = CGSize.zero
34 | layer.masksToBounds = false
35 | clipsToBounds = false
36 |
37 | separatorView.backgroundColor = .lightGray
38 |
39 | leftButton.setTitle("Left", for: .normal)
40 | rightButton.setTitle("Right", for: .normal)
41 |
42 | leftButton.setTitleColor(.gray, for: .normal)
43 | rightButton.setTitleColor(.gray, for: .normal)
44 |
45 | self.addSubview(separatorView)
46 | self.addSubview(leftButton)
47 | self.addSubview(rightButton)
48 | }
49 |
50 | override func layoutSubviews() {
51 | super.layoutSubviews()
52 |
53 | let w = bounds.width
54 | let h = bounds.height
55 |
56 | let half = w / 2
57 |
58 |
59 | separatorView.frame = CGRect(x: half, y: 14, width: 1, height: h - 28)
60 | leftButton.frame = CGRect(x: half - 100, y: 0, width: 90, height: h)
61 | rightButton.frame = CGRect(x: separatorView.frame.maxX + 10, y: 0, width: 90, height: h)
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "icon-40.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "icon-60.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "icon-58.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "icon-87.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "40x40",
29 | "idiom" : "iphone",
30 | "filename" : "icon-80.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "icon-120.png",
37 | "scale" : "3x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "icon-120.png",
43 | "scale" : "2x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "icon-180.png",
49 | "scale" : "3x"
50 | },
51 | {
52 | "size" : "20x20",
53 | "idiom" : "ipad",
54 | "filename" : "icon-20.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "icon-40.png",
61 | "scale" : "2x"
62 | },
63 | {
64 | "size" : "29x29",
65 | "idiom" : "ipad",
66 | "filename" : "icon-29.png",
67 | "scale" : "1x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "icon-58.png",
73 | "scale" : "2x"
74 | },
75 | {
76 | "size" : "40x40",
77 | "idiom" : "ipad",
78 | "filename" : "icon-40.png",
79 | "scale" : "1x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "icon-80.png",
85 | "scale" : "2x"
86 | },
87 | {
88 | "size" : "76x76",
89 | "idiom" : "ipad",
90 | "filename" : "icon-76.png",
91 | "scale" : "1x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "icon-152.png",
97 | "scale" : "2x"
98 | },
99 | {
100 | "size" : "83.5x83.5",
101 | "idiom" : "ipad",
102 | "filename" : "icon-167.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "1024x1024",
107 | "idiom" : "ios-marketing",
108 | "filename" : "Ramotion.png",
109 | "scale" : "1x"
110 | }
111 | ],
112 | "info" : {
113 | "version" : 1,
114 | "author" : "xcode"
115 | },
116 | "properties" : {
117 | "pre-rendered" : true
118 | }
119 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/Ramotion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/Ramotion.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-120.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-152.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-167.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-180.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-20.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-29.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-40.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-58.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-60.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-76.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-80.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/AppIcon.appiconset/icon-87.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "collection_bg-2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "collection_bg.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "collection_bg-1.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg-1.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg-2.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/background.imageset/collection_bg.png
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image1.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image1.imageset/image1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image1.imageset/image1.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image10.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image10.imageset/image10.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image10.imageset/image10.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image11.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image11.imageset/image11.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image11.imageset/image11.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image12.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image12.imageset/image12.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image12.imageset/image12.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image13.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image13.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image13.imageset/image13.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image13.imageset/image13.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image14.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image14.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image14.imageset/image14.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image14.imageset/image14.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image15.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image15.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image15.imageset/image15.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image15.imageset/image15.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image2.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image2.imageset/image2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image2.imageset/image2.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image3.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image3.imageset/image3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image3.imageset/image3.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image4.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image4.imageset/image4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image4.imageset/image4.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image5.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image5.imageset/image5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image5.imageset/image5.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image6.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image6.imageset/image6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image6.imageset/image6.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image7.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image7.imageset/image7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image7.imageset/image7.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image8.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image8.imageset/image8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image8.imageset/image8.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "image9.jpeg"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/Example/Example/Resources/Assets.xcassets/controllers/image9.imageset/image9.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/Example/Example/Resources/Assets.xcassets/controllers/image9.imageset/image9.jpeg
--------------------------------------------------------------------------------
/Example/Example/Resources/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 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Example/Example/Resources/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 |
33 | UISupportedInterfaceOrientations~ipad
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationPortraitUpsideDown
37 | UIInterfaceOrientationLandscapeLeft
38 | UIInterfaceOrientationLandscapeRight
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Example/Example/Utilities/UIColor+HEX.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+HEX.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 |
12 | extension UIColor {
13 |
14 | convenience init(HEX: String) {
15 | let scanner = Scanner(string: HEX)
16 | scanner.scanLocation = 0
17 |
18 | var rgbValue: UInt64 = 0
19 |
20 | scanner.scanHexInt64(&rgbValue)
21 |
22 | let r = (rgbValue & 0xff0000) >> 16
23 | let g = (rgbValue & 0xff00) >> 8
24 | let b = rgbValue & 0xff
25 |
26 | self.init(
27 | red : CGFloat(r) / 0xff,
28 | green : CGFloat(g) / 0xff,
29 | blue : CGFloat(b) / 0xff, alpha : 1
30 | )
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Example/Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // NavigationToolbarDemo
4 | //
5 | // Created by Artem P. on 21/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import NavigationToolbar
11 |
12 | class ViewController: UIViewController {
13 |
14 | private var navigationView: NavigationView?
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | navigationView = NavigationView.init(frame: view.bounds, middleView: MiddleView(), screens: createObjects(), backgroundImage: #imageLiteral(resourceName: "background"))
20 | navigationView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
21 | view.addSubview(navigationView!)
22 | }
23 |
24 | override var prefersStatusBarHidden: Bool {
25 | return true
26 | }
27 |
28 | private func createObjects() -> [ScreenObject] {
29 | let obj01 = ScreenObject(title: "OBSESSION", startColor: UIColor.init(HEX: "FDEB71"), endColor: UIColor.init(HEX: "F8D800"), image: UIImage(named : "image1")!, controller: DummyController())
30 | let obj02 = ScreenObject(title: "RECREATION", startColor: UIColor.init(HEX: "ABDCFF"), endColor: UIColor.init(HEX: "0396FF"), image: UIImage(named : "image2")!, controller: DummyController())
31 | let obj03 = ScreenObject(title: "EDUCATION", startColor: UIColor.init(HEX: "FEB692"), endColor: UIColor.init(HEX: "EA5455"), image: UIImage(named : "image3")!, controller: DummyController())
32 | let obj04 = ScreenObject(title: "MOVIES", startColor: UIColor.init(HEX: "CE9FFC"), endColor: UIColor.init(HEX: "7367F0"), image: UIImage(named : "image4")!, controller: DummyController())
33 | let obj05 = ScreenObject(title: "PROGRAMMING", startColor: UIColor.init(HEX: "90F7EC"), endColor: UIColor.init(HEX: "32CCBC"), image: UIImage(named : "image5")!, controller: DummyController())
34 | let obj06 = ScreenObject(title: "SURFING", startColor: UIColor.init(HEX: "FFF6B7"), endColor: UIColor.init(HEX: "F6416C"), image: UIImage(named : "image6")!, controller: DummyController())
35 | let obj07 = ScreenObject(title: "FLIGHT", startColor: UIColor.init(HEX: "81FBB8"), endColor: UIColor.init(HEX: "28C76F"), image: UIImage(named : "image7")!, controller: DummyController())
36 | let obj08 = ScreenObject(title: "MINIMALISM", startColor: UIColor.init(HEX: "E2B0FF"), endColor: UIColor.init(HEX: "9F44D3"), image: UIImage(named : "image8")!, controller: DummyController())
37 |
38 | return [obj01,
39 | obj02,
40 | obj03,
41 | obj04,
42 | obj05,
43 | obj06,
44 | obj07,
45 | obj08
46 | ]
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Ramotion
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 |
--------------------------------------------------------------------------------
/Navigation-Toolbar.podspec:
--------------------------------------------------------------------------------
1 |
2 | Pod::Spec.new do |s|
3 |
4 | s.name = 'Navigation-Toolbar'
5 | s.version = '1.0.0'
6 | s.summary = 'Amazing navigation.'
7 | s.license = 'MIT'
8 | s.homepage = 'https://github.com/Ramotion/navigation-toolbar'
9 | s.author = { 'Juri Vasylenko' => 'juri.v@ramotion.com' }
10 | s.ios.deployment_target = '10.0'
11 | s.source = { :git => 'https://github.com/Ramotion/navigation-toolbar.git', :tag => s.version.to_s }
12 | s.source_files = 'Sources/**/*.swift'
13 | end
14 |
--------------------------------------------------------------------------------
/NavigationToolbar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 393FD9F721132B6F00909225 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9DC21132B6F00909225 /* Settings.swift */; };
11 | 393FD9F821132B6F00909225 /* NavigationToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 393FD9DE21132B6F00909225 /* NavigationToolbar.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | 393FD9FA21132B6F00909225 /* ScreenObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9E121132B6F00909225 /* ScreenObject.swift */; };
13 | 393FD9FC21132B6F00909225 /* TopViewCells.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9E621132B6F00909225 /* TopViewCells.swift */; };
14 | 393FD9FD21132B6F00909225 /* TopViewCollectionLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9E721132B6F00909225 /* TopViewCollectionLayout.swift */; };
15 | 393FD9FE21132B6F00909225 /* SizingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9E821132B6F00909225 /* SizingView.swift */; };
16 | 393FD9FF21132B6F00909225 /* TopViewAnimators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9E921132B6F00909225 /* TopViewAnimators.swift */; };
17 | 393FDA0021132B6F00909225 /* TopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9EA21132B6F00909225 /* TopView.swift */; };
18 | 393FDA0121132B6F00909225 /* CellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9EC21132B6F00909225 /* CellView.swift */; };
19 | 393FDA0221132B6F00909225 /* FulllscreenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9ED21132B6F00909225 /* FulllscreenView.swift */; };
20 | 393FDA0321132B6F00909225 /* LabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9EE21132B6F00909225 /* LabelView.swift */; };
21 | 393FDA0421132B6F00909225 /* BottomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9F021132B6F00909225 /* BottomView.swift */; };
22 | 393FDA0521132B6F00909225 /* UIImage+gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9F221132B6F00909225 /* UIImage+gradient.swift */; };
23 | 393FDA0621132B6F00909225 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9F421132B6F00909225 /* Label.swift */; };
24 | 393FDA0721132B6F00909225 /* PanDirectionGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9F521132B6F00909225 /* PanDirectionGestureRecognizer.swift */; };
25 | 393FDA0821132B6F00909225 /* NavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 393FD9F621132B6F00909225 /* NavigationView.swift */; };
26 | /* End PBXBuildFile section */
27 |
28 | /* Begin PBXFileReference section */
29 | 393FD9CF21132AD000909225 /* NavigationToolbar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NavigationToolbar.framework; sourceTree = BUILT_PRODUCTS_DIR; };
30 | 393FD9DC21132B6F00909225 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = ""; };
31 | 393FD9DE21132B6F00909225 /* NavigationToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationToolbar.h; sourceTree = ""; };
32 | 393FD9DF21132B6F00909225 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 393FD9E121132B6F00909225 /* ScreenObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScreenObject.swift; sourceTree = ""; };
34 | 393FD9E621132B6F00909225 /* TopViewCells.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopViewCells.swift; sourceTree = ""; };
35 | 393FD9E721132B6F00909225 /* TopViewCollectionLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopViewCollectionLayout.swift; sourceTree = ""; };
36 | 393FD9E821132B6F00909225 /* SizingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizingView.swift; sourceTree = ""; };
37 | 393FD9E921132B6F00909225 /* TopViewAnimators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopViewAnimators.swift; sourceTree = ""; };
38 | 393FD9EA21132B6F00909225 /* TopView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopView.swift; sourceTree = ""; };
39 | 393FD9EC21132B6F00909225 /* CellView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellView.swift; sourceTree = ""; };
40 | 393FD9ED21132B6F00909225 /* FulllscreenView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FulllscreenView.swift; sourceTree = ""; };
41 | 393FD9EE21132B6F00909225 /* LabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelView.swift; sourceTree = ""; };
42 | 393FD9F021132B6F00909225 /* BottomView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomView.swift; sourceTree = ""; };
43 | 393FD9F221132B6F00909225 /* UIImage+gradient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+gradient.swift"; sourceTree = ""; };
44 | 393FD9F421132B6F00909225 /* Label.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; };
45 | 393FD9F521132B6F00909225 /* PanDirectionGestureRecognizer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PanDirectionGestureRecognizer.swift; sourceTree = ""; };
46 | 393FD9F621132B6F00909225 /* NavigationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationView.swift; sourceTree = ""; };
47 | /* End PBXFileReference section */
48 |
49 | /* Begin PBXFrameworksBuildPhase section */
50 | 393FD9CB21132AD000909225 /* Frameworks */ = {
51 | isa = PBXFrameworksBuildPhase;
52 | buildActionMask = 2147483647;
53 | files = (
54 | );
55 | runOnlyForDeploymentPostprocessing = 0;
56 | };
57 | /* End PBXFrameworksBuildPhase section */
58 |
59 | /* Begin PBXGroup section */
60 | 393FD9C521132AD000909225 = {
61 | isa = PBXGroup;
62 | children = (
63 | 393FD9DA21132B6F00909225 /* Sources */,
64 | 393FD9D021132AD000909225 /* Products */,
65 | );
66 | sourceTree = "";
67 | };
68 | 393FD9D021132AD000909225 /* Products */ = {
69 | isa = PBXGroup;
70 | children = (
71 | 393FD9CF21132AD000909225 /* NavigationToolbar.framework */,
72 | );
73 | name = Products;
74 | sourceTree = "";
75 | };
76 | 393FD9DA21132B6F00909225 /* Sources */ = {
77 | isa = PBXGroup;
78 | children = (
79 | 393FD9F621132B6F00909225 /* NavigationView.swift */,
80 | 393FD9DB21132B6F00909225 /* Settings */,
81 | 393FD9E021132B6F00909225 /* Objects */,
82 | 393FD9E221132B6F00909225 /* SubViews */,
83 | 393FD9F121132B6F00909225 /* Extensions */,
84 | 393FD9F321132B6F00909225 /* Components */,
85 | 393FD9DE21132B6F00909225 /* NavigationToolbar.h */,
86 | 393FD9DF21132B6F00909225 /* Info.plist */,
87 | );
88 | path = Sources;
89 | sourceTree = "";
90 | };
91 | 393FD9DB21132B6F00909225 /* Settings */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 393FD9DC21132B6F00909225 /* Settings.swift */,
95 | );
96 | path = Settings;
97 | sourceTree = "";
98 | };
99 | 393FD9E021132B6F00909225 /* Objects */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 393FD9E121132B6F00909225 /* ScreenObject.swift */,
103 | );
104 | path = Objects;
105 | sourceTree = "";
106 | };
107 | 393FD9E221132B6F00909225 /* SubViews */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 393FD9E521132B6F00909225 /* TopView */,
111 | 393FD9EB21132B6F00909225 /* FullscreenView */,
112 | 393FD9EF21132B6F00909225 /* BottomView */,
113 | );
114 | path = SubViews;
115 | sourceTree = "";
116 | };
117 | 393FD9E521132B6F00909225 /* TopView */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 393FD9E621132B6F00909225 /* TopViewCells.swift */,
121 | 393FD9E721132B6F00909225 /* TopViewCollectionLayout.swift */,
122 | 393FD9E821132B6F00909225 /* SizingView.swift */,
123 | 393FD9E921132B6F00909225 /* TopViewAnimators.swift */,
124 | 393FD9EA21132B6F00909225 /* TopView.swift */,
125 | );
126 | path = TopView;
127 | sourceTree = "";
128 | };
129 | 393FD9EB21132B6F00909225 /* FullscreenView */ = {
130 | isa = PBXGroup;
131 | children = (
132 | 393FD9EC21132B6F00909225 /* CellView.swift */,
133 | 393FD9ED21132B6F00909225 /* FulllscreenView.swift */,
134 | 393FD9EE21132B6F00909225 /* LabelView.swift */,
135 | );
136 | path = FullscreenView;
137 | sourceTree = "";
138 | };
139 | 393FD9EF21132B6F00909225 /* BottomView */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 393FD9F021132B6F00909225 /* BottomView.swift */,
143 | );
144 | path = BottomView;
145 | sourceTree = "";
146 | };
147 | 393FD9F121132B6F00909225 /* Extensions */ = {
148 | isa = PBXGroup;
149 | children = (
150 | 393FD9F221132B6F00909225 /* UIImage+gradient.swift */,
151 | );
152 | path = Extensions;
153 | sourceTree = "";
154 | };
155 | 393FD9F321132B6F00909225 /* Components */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 393FD9F421132B6F00909225 /* Label.swift */,
159 | 393FD9F521132B6F00909225 /* PanDirectionGestureRecognizer.swift */,
160 | );
161 | path = Components;
162 | sourceTree = "";
163 | };
164 | /* End PBXGroup section */
165 |
166 | /* Begin PBXHeadersBuildPhase section */
167 | 393FD9CC21132AD000909225 /* Headers */ = {
168 | isa = PBXHeadersBuildPhase;
169 | buildActionMask = 2147483647;
170 | files = (
171 | 393FD9F821132B6F00909225 /* NavigationToolbar.h in Headers */,
172 | );
173 | runOnlyForDeploymentPostprocessing = 0;
174 | };
175 | /* End PBXHeadersBuildPhase section */
176 |
177 | /* Begin PBXNativeTarget section */
178 | 393FD9CE21132AD000909225 /* NavigationToolbar */ = {
179 | isa = PBXNativeTarget;
180 | buildConfigurationList = 393FD9D721132AD000909225 /* Build configuration list for PBXNativeTarget "NavigationToolbar" */;
181 | buildPhases = (
182 | 393FD9CA21132AD000909225 /* Sources */,
183 | 393FD9CB21132AD000909225 /* Frameworks */,
184 | 393FD9CC21132AD000909225 /* Headers */,
185 | 393FD9CD21132AD000909225 /* Resources */,
186 | );
187 | buildRules = (
188 | );
189 | dependencies = (
190 | );
191 | name = NavigationToolbar;
192 | productName = NavigationToolbar;
193 | productReference = 393FD9CF21132AD000909225 /* NavigationToolbar.framework */;
194 | productType = "com.apple.product-type.framework";
195 | };
196 | /* End PBXNativeTarget section */
197 |
198 | /* Begin PBXProject section */
199 | 393FD9C621132AD000909225 /* Project object */ = {
200 | isa = PBXProject;
201 | attributes = {
202 | LastUpgradeCheck = 0940;
203 | ORGANIZATIONNAME = Ramotion;
204 | TargetAttributes = {
205 | 393FD9CE21132AD000909225 = {
206 | CreatedOnToolsVersion = 9.4.1;
207 | LastSwiftMigration = 1010;
208 | };
209 | };
210 | };
211 | buildConfigurationList = 393FD9C921132AD000909225 /* Build configuration list for PBXProject "NavigationToolbar" */;
212 | compatibilityVersion = "Xcode 9.3";
213 | developmentRegion = en;
214 | hasScannedForEncodings = 0;
215 | knownRegions = (
216 | en,
217 | Base,
218 | );
219 | mainGroup = 393FD9C521132AD000909225;
220 | productRefGroup = 393FD9D021132AD000909225 /* Products */;
221 | projectDirPath = "";
222 | projectRoot = "";
223 | targets = (
224 | 393FD9CE21132AD000909225 /* NavigationToolbar */,
225 | );
226 | };
227 | /* End PBXProject section */
228 |
229 | /* Begin PBXResourcesBuildPhase section */
230 | 393FD9CD21132AD000909225 /* Resources */ = {
231 | isa = PBXResourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | };
237 | /* End PBXResourcesBuildPhase section */
238 |
239 | /* Begin PBXSourcesBuildPhase section */
240 | 393FD9CA21132AD000909225 /* Sources */ = {
241 | isa = PBXSourcesBuildPhase;
242 | buildActionMask = 2147483647;
243 | files = (
244 | 393FD9FD21132B6F00909225 /* TopViewCollectionLayout.swift in Sources */,
245 | 393FD9FF21132B6F00909225 /* TopViewAnimators.swift in Sources */,
246 | 393FDA0421132B6F00909225 /* BottomView.swift in Sources */,
247 | 393FD9FA21132B6F00909225 /* ScreenObject.swift in Sources */,
248 | 393FDA0521132B6F00909225 /* UIImage+gradient.swift in Sources */,
249 | 393FDA0221132B6F00909225 /* FulllscreenView.swift in Sources */,
250 | 393FDA0721132B6F00909225 /* PanDirectionGestureRecognizer.swift in Sources */,
251 | 393FD9FC21132B6F00909225 /* TopViewCells.swift in Sources */,
252 | 393FD9FE21132B6F00909225 /* SizingView.swift in Sources */,
253 | 393FDA0821132B6F00909225 /* NavigationView.swift in Sources */,
254 | 393FDA0321132B6F00909225 /* LabelView.swift in Sources */,
255 | 393FDA0021132B6F00909225 /* TopView.swift in Sources */,
256 | 393FD9F721132B6F00909225 /* Settings.swift in Sources */,
257 | 393FDA0621132B6F00909225 /* Label.swift in Sources */,
258 | 393FDA0121132B6F00909225 /* CellView.swift in Sources */,
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | };
262 | /* End PBXSourcesBuildPhase section */
263 |
264 | /* Begin XCBuildConfiguration section */
265 | 393FD9D521132AD000909225 /* Debug */ = {
266 | isa = XCBuildConfiguration;
267 | buildSettings = {
268 | ALWAYS_SEARCH_USER_PATHS = NO;
269 | CLANG_ANALYZER_NONNULL = YES;
270 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
271 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
272 | CLANG_CXX_LIBRARY = "libc++";
273 | CLANG_ENABLE_MODULES = YES;
274 | CLANG_ENABLE_OBJC_ARC = YES;
275 | CLANG_ENABLE_OBJC_WEAK = YES;
276 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
277 | CLANG_WARN_BOOL_CONVERSION = YES;
278 | CLANG_WARN_COMMA = YES;
279 | CLANG_WARN_CONSTANT_CONVERSION = YES;
280 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
281 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
282 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
283 | CLANG_WARN_EMPTY_BODY = YES;
284 | CLANG_WARN_ENUM_CONVERSION = YES;
285 | CLANG_WARN_INFINITE_RECURSION = YES;
286 | CLANG_WARN_INT_CONVERSION = YES;
287 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
289 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
291 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
292 | CLANG_WARN_STRICT_PROTOTYPES = YES;
293 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
294 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
295 | CLANG_WARN_UNREACHABLE_CODE = YES;
296 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
297 | CODE_SIGN_IDENTITY = "iPhone Developer";
298 | COPY_PHASE_STRIP = NO;
299 | CURRENT_PROJECT_VERSION = 1;
300 | DEBUG_INFORMATION_FORMAT = dwarf;
301 | ENABLE_STRICT_OBJC_MSGSEND = YES;
302 | ENABLE_TESTABILITY = YES;
303 | GCC_C_LANGUAGE_STANDARD = gnu11;
304 | GCC_DYNAMIC_NO_PIC = NO;
305 | GCC_NO_COMMON_BLOCKS = YES;
306 | GCC_OPTIMIZATION_LEVEL = 0;
307 | GCC_PREPROCESSOR_DEFINITIONS = (
308 | "DEBUG=1",
309 | "$(inherited)",
310 | );
311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
313 | GCC_WARN_UNDECLARED_SELECTOR = YES;
314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
315 | GCC_WARN_UNUSED_FUNCTION = YES;
316 | GCC_WARN_UNUSED_VARIABLE = YES;
317 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
318 | MTL_ENABLE_DEBUG_INFO = YES;
319 | ONLY_ACTIVE_ARCH = YES;
320 | SDKROOT = iphoneos;
321 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
322 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
323 | VERSIONING_SYSTEM = "apple-generic";
324 | VERSION_INFO_PREFIX = "";
325 | };
326 | name = Debug;
327 | };
328 | 393FD9D621132AD000909225 /* Release */ = {
329 | isa = XCBuildConfiguration;
330 | buildSettings = {
331 | ALWAYS_SEARCH_USER_PATHS = NO;
332 | CLANG_ANALYZER_NONNULL = YES;
333 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
334 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
335 | CLANG_CXX_LIBRARY = "libc++";
336 | CLANG_ENABLE_MODULES = YES;
337 | CLANG_ENABLE_OBJC_ARC = YES;
338 | CLANG_ENABLE_OBJC_WEAK = YES;
339 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
340 | CLANG_WARN_BOOL_CONVERSION = YES;
341 | CLANG_WARN_COMMA = YES;
342 | CLANG_WARN_CONSTANT_CONVERSION = YES;
343 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
344 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
345 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
346 | CLANG_WARN_EMPTY_BODY = YES;
347 | CLANG_WARN_ENUM_CONVERSION = YES;
348 | CLANG_WARN_INFINITE_RECURSION = YES;
349 | CLANG_WARN_INT_CONVERSION = YES;
350 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
351 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
353 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
355 | CLANG_WARN_STRICT_PROTOTYPES = YES;
356 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
357 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
358 | CLANG_WARN_UNREACHABLE_CODE = YES;
359 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
360 | CODE_SIGN_IDENTITY = "iPhone Developer";
361 | COPY_PHASE_STRIP = NO;
362 | CURRENT_PROJECT_VERSION = 1;
363 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
364 | ENABLE_NS_ASSERTIONS = NO;
365 | ENABLE_STRICT_OBJC_MSGSEND = YES;
366 | GCC_C_LANGUAGE_STANDARD = gnu11;
367 | GCC_NO_COMMON_BLOCKS = YES;
368 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
369 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
370 | GCC_WARN_UNDECLARED_SELECTOR = YES;
371 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
372 | GCC_WARN_UNUSED_FUNCTION = YES;
373 | GCC_WARN_UNUSED_VARIABLE = YES;
374 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
375 | MTL_ENABLE_DEBUG_INFO = NO;
376 | SDKROOT = iphoneos;
377 | SWIFT_COMPILATION_MODE = wholemodule;
378 | SWIFT_OPTIMIZATION_LEVEL = "-O";
379 | VALIDATE_PRODUCT = YES;
380 | VERSIONING_SYSTEM = "apple-generic";
381 | VERSION_INFO_PREFIX = "";
382 | };
383 | name = Release;
384 | };
385 | 393FD9D821132AD000909225 /* Debug */ = {
386 | isa = XCBuildConfiguration;
387 | buildSettings = {
388 | CODE_SIGN_IDENTITY = "";
389 | CODE_SIGN_STYLE = Automatic;
390 | DEFINES_MODULE = YES;
391 | DEVELOPMENT_TEAM = 34MUF9YXTA;
392 | DYLIB_COMPATIBILITY_VERSION = 1;
393 | DYLIB_CURRENT_VERSION = 1;
394 | DYLIB_INSTALL_NAME_BASE = "@rpath";
395 | INFOPLIST_FILE = Sources/Info.plist;
396 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
397 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
398 | LD_RUNPATH_SEARCH_PATHS = (
399 | "$(inherited)",
400 | "@executable_path/Frameworks",
401 | "@loader_path/Frameworks",
402 | );
403 | PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.NavigationToolbar;
404 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
405 | SKIP_INSTALL = YES;
406 | SWIFT_VERSION = 5.0;
407 | TARGETED_DEVICE_FAMILY = "1,2";
408 | };
409 | name = Debug;
410 | };
411 | 393FD9D921132AD000909225 /* Release */ = {
412 | isa = XCBuildConfiguration;
413 | buildSettings = {
414 | CODE_SIGN_IDENTITY = "";
415 | CODE_SIGN_STYLE = Automatic;
416 | DEFINES_MODULE = YES;
417 | DEVELOPMENT_TEAM = 34MUF9YXTA;
418 | DYLIB_COMPATIBILITY_VERSION = 1;
419 | DYLIB_CURRENT_VERSION = 1;
420 | DYLIB_INSTALL_NAME_BASE = "@rpath";
421 | INFOPLIST_FILE = Sources/Info.plist;
422 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
423 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
424 | LD_RUNPATH_SEARCH_PATHS = (
425 | "$(inherited)",
426 | "@executable_path/Frameworks",
427 | "@loader_path/Frameworks",
428 | );
429 | PRODUCT_BUNDLE_IDENTIFIER = com.ramotion.NavigationToolbar;
430 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
431 | SKIP_INSTALL = YES;
432 | SWIFT_VERSION = 5.0;
433 | TARGETED_DEVICE_FAMILY = "1,2";
434 | };
435 | name = Release;
436 | };
437 | /* End XCBuildConfiguration section */
438 |
439 | /* Begin XCConfigurationList section */
440 | 393FD9C921132AD000909225 /* Build configuration list for PBXProject "NavigationToolbar" */ = {
441 | isa = XCConfigurationList;
442 | buildConfigurations = (
443 | 393FD9D521132AD000909225 /* Debug */,
444 | 393FD9D621132AD000909225 /* Release */,
445 | );
446 | defaultConfigurationIsVisible = 0;
447 | defaultConfigurationName = Release;
448 | };
449 | 393FD9D721132AD000909225 /* Build configuration list for PBXNativeTarget "NavigationToolbar" */ = {
450 | isa = XCConfigurationList;
451 | buildConfigurations = (
452 | 393FD9D821132AD000909225 /* Debug */,
453 | 393FD9D921132AD000909225 /* Release */,
454 | );
455 | defaultConfigurationIsVisible = 0;
456 | defaultConfigurationName = Release;
457 | };
458 | /* End XCConfigurationList section */
459 | };
460 | rootObject = 393FD9C621132AD000909225 /* Project object */;
461 | }
462 |
--------------------------------------------------------------------------------
/NavigationToolbar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/NavigationToolbar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/NavigationToolbar.xcodeproj/xcshareddata/xcschemes/NavigationToolbar.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 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.1
2 | //
3 | // Package.swift
4 | //
5 | // Copyright (c) Ramotion (https://www.ramotion.com/)
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy
8 | // of this software and associated documentation files (the "Software"), to deal
9 | // in the Software without restriction, including without limitation the rights
10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | // copies of the Software, and to permit persons to whom the Software is
12 | // furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in
15 | // all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | // THE SOFTWARE.
24 | //
25 |
26 | import PackageDescription
27 |
28 |
29 | let package = Package(
30 | name: "NavigationToolbar",
31 | platforms: [
32 | .iOS(.v9)
33 | ],
34 | products: [
35 | .library(name: "NavigationToolbar",
36 | targets: ["NavigationToolbar"]),
37 | ],
38 | targets: [
39 | .target(name: "NavigationToolbar",
40 | path: "Sources")
41 | ],
42 | swiftLanguageVersions: [.v5]
43 | )
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NAVIGATION TOOLBAR
7 |
8 | Navigation toolbar is a Swift slide-modeled UI navigation controller.
9 |
10 |
11 | ___
12 |
13 |
14 |
15 | We specialize in the designing and coding of custom UI for Mobile Apps and Websites.
16 |
17 |
18 |
19 | Stay tuned for the latest updates:
20 |
21 |
22 |
23 |
24 |
25 | [](http://twitter.com/Ramotion)
26 | [](https://cocoapods.org/pods/Navigation-Toolbar)
27 | [](http://cocoapods.org/pods/Navigation-Toolbar)
28 | [](https://github.com/Ramotion/navigation-toolbar)
29 | [](https://codebeat.co/projects/github-com-ramotion-navigation-toolbar-master)
30 | [](https://paypal.me/Ramotion)
31 |
32 |
33 | ## Requirements
34 |
35 | - iOS 10.0+
36 | - Xcode 9
37 |
38 | ## Installation
39 |
40 | Just add the Source folder to your project.
41 |
42 | or use [CocoaPods](https://cocoapods.org) with Podfile:
43 |
44 | ``` ruby
45 | pod 'Navigation-Toolbar'
46 | ```
47 |
48 | or [Carthage](https://github.com/Carthage/Carthage) users can simply add to their `Cartfile`:
49 | ```
50 | github "Ramotion/navigation-toolbar"
51 | ```
52 |
53 | ## Usage
54 |
55 | #### Storyboard
56 |
57 | 1) Create a new UIView inheriting from ```NavigationView```
58 |
59 | 2) Create ScreenObject for every required screen with configuration, see example:
60 |
61 | ``` swift
62 | class ViewController: UIViewController {
63 |
64 | private var navigationView: NavigationView?
65 |
66 | override func viewDidLoad() {
67 | super.viewDidLoad()
68 |
69 | navigationView = NavigationView.init(frame: view.bounds,
70 | middleView: MiddleView(),
71 | screens: [
72 | ScreenObject(title: "MUSIC",
73 | startColor: .red,
74 | endColor: .blue,
75 | image: UIImage(named : "image1")!,
76 | controller: YourFirstViewController()),
77 |
78 | ScreenObject(title: "EDUCATION",
79 | startColor: .black,
80 | endColor: .white,
81 | image: UIImage(named : "image2")!,
82 | controller: YourSecondViewController()),
83 | ],
84 | backgroundImage: #imageLiteral(resourceName: "background"))
85 |
86 | navigationView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]
87 | view.addSubview(navigationView!)
88 | }
89 |
90 | }
91 | ```
92 |
93 |
94 | ## 🗂 Check this library on other language:
95 |
96 |
97 |
98 |
99 | ## 📄 License
100 |
101 | Navigation Toolbar is released under the MIT license.
102 | See [LICENSE](./LICENSE) for details.
103 |
104 | This library is a part of a selection of our best UI open-source projects.
105 |
106 | If you use the open-source library in your project, please make sure to credit and backlink to www.ramotion.com
107 |
108 | ## 📱 Get the Showroom App for iOS to give it a try
109 | Try this UI component and more like this in our iOS app. Contact us if interested.
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/Sources/Components/Label.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Label.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class Label: UILabel {
12 |
13 | class func topViewCellLabel() -> UILabel {
14 | let label = UILabel()
15 | label.clipsToBounds = false
16 | label.textColor = .white
17 | label.font = UIFont.systemFont(ofSize: Settings.Sizes.labelFontSize)
18 | label.textAlignment = .center
19 |
20 | return label
21 | }
22 |
23 | class func sideLabel() -> UILabel {
24 | let label = UILabel()
25 | label.clipsToBounds = false
26 | label.textColor = .white
27 | label.font = UIFont.systemFont(ofSize: Settings.Sizes.labelFontSize)
28 | label.textAlignment = .center
29 |
30 | return label
31 | }
32 |
33 | class func menuCellLabel() -> UILabel {
34 | let label = UILabel()
35 | label.textAlignment = .left
36 | label.clipsToBounds = false
37 | label.textColor = .white
38 | label.font = UIFont.systemFont(ofSize: Settings.Sizes.labelFontSize)
39 |
40 | return label
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/Components/PanDirectionGestureRecognizer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PanGestureRecognizer.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit.UIGestureRecognizerSubclass
11 |
12 | enum PanDirection {
13 | case vertical
14 | case horizontal
15 | }
16 |
17 | class PanDirectionGestureRecognizer: UIPanGestureRecognizer {
18 |
19 | let direction: PanDirection
20 |
21 | init(direction: PanDirection, target: AnyObject, action: Selector) {
22 | self.direction = direction
23 | super.init(target: target, action: action)
24 | }
25 |
26 | override func touchesMoved(_ touches: Set, with event: UIEvent) {
27 | super.touchesMoved(touches, with: event)
28 |
29 | if state == .began {
30 | let vel = velocity(in: view)
31 | switch direction {
32 | case .horizontal where abs(vel.y) > abs(vel.x):
33 | state = .cancelled
34 | case .vertical where abs(vel.x) > abs(vel.y):
35 | state = .cancelled
36 | default:
37 | break
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Sources/Extensions/UIImage+gradient.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+gradient.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIImage {
12 |
13 | static func makeImageWithGradient(image: UIImage = UIImage(), imageAlpha: CGFloat = Settings.imageAlpha, startColor: UIColor = UIColor.red, endColor: UIColor = UIColor.blue) -> UIImage {
14 | let layer = CAGradientLayer()
15 | layer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: Settings.Sizes.middleSize)
16 | layer.colors = [startColor.cgColor, endColor.cgColor]
17 | layer.startPoint = CGPoint(x: 0, y: 0.5)
18 | layer.endPoint = CGPoint(x: 1, y: 0.5)
19 |
20 | UIGraphicsBeginImageContext(CGSize(width: layer.frame.width, height: layer.frame.height))
21 | layer.render(in: UIGraphicsGetCurrentContext()!)
22 | let gradientImage = UIGraphicsGetImageFromCurrentImageContext()
23 | UIGraphicsEndImageContext()
24 |
25 | return mergeImages(bottom: gradientImage!, top: image, alpha: imageAlpha)
26 | }
27 |
28 | static func mergeImages(bottom: UIImage, top: UIImage, alpha: CGFloat) -> UIImage {
29 | let bottomImage = bottom
30 | let topImage = top
31 |
32 | let size = CGSize(width: Settings.Sizes.screenWidth, height: Settings.Sizes.middleSize)
33 | UIGraphicsBeginImageContext(size)
34 |
35 | let areaSize = CGRect(x: 0, y: 0, width: size.width, height: size.height)
36 | bottomImage.draw(in: areaSize)
37 |
38 | topImage.draw(in: areaSize, blendMode: .normal, alpha: alpha)
39 |
40 | let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
41 | UIGraphicsEndImageContext()
42 |
43 | return newImage
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Sources/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Sources/NavigationToolbar.h:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationToolbar.h
3 | // NavigationToolbar
4 | //
5 | // Created by Xorosho on 8/2/18.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for NavigationToolbar.
12 | FOUNDATION_EXPORT double NavigationToolbarVersionNumber;
13 |
14 | //! Project version string for NavigationToolbar.
15 | FOUNDATION_EXPORT const unsigned char NavigationToolbarVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Sources/NavigationView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | enum State {
12 | case horizontal
13 | case vertical
14 | }
15 |
16 | open class NavigationView: UIView {
17 |
18 | private var backGroundImageView = UIImageView()
19 | private var topView = TopView()
20 | private var middleView: UIView!
21 | private var bottomView = BottomView()
22 | private var fullscreenView = FulllscreenView()
23 | private var panRecognizer: PanDirectionGestureRecognizer!
24 | private var screens: [ScreenObject]!
25 | private var backgroundImage: UIImage!
26 |
27 | public var currentIndex: Int = 0 {
28 | didSet {
29 | topView.currentIndex = currentIndex
30 | fullscreenView.currentIndex = currentIndex
31 | bottomView.currentIndex = currentIndex
32 | }
33 | }
34 |
35 | private var middleOriginY: CGFloat = Settings.Sizes.navbarSize {
36 | didSet {
37 | setNeedsLayout()
38 | layoutIfNeeded()
39 | }
40 | }
41 |
42 | public init(frame: CGRect, middleView: UIView, screens: [ScreenObject], backgroundImage: UIImage) {
43 | self.middleView = middleView
44 | self.screens = screens
45 | self.backgroundImage = backgroundImage
46 |
47 | super.init(frame: frame)
48 |
49 | setup()
50 | }
51 |
52 | required public init?(coder aDecoder: NSCoder) {
53 | super.init(coder: aDecoder)
54 | setup()
55 | }
56 |
57 | private func setup() {
58 | setData()
59 |
60 | backGroundImageView.image = UIImage(named: "background")
61 |
62 | topView.backgroundColor = .clear
63 | bottomView.backgroundColor = .white
64 | bottomView.delegate = self
65 | topView.delegate = self
66 |
67 | fullscreenView.delegate = self
68 |
69 | addSubview(backGroundImageView)
70 | addSubview(fullscreenView)
71 | addSubview(topView)
72 | addSubview(bottomView)
73 | addSubview(middleView)
74 |
75 | panRecognizer = PanDirectionGestureRecognizer(direction: .vertical,
76 | target: self,
77 | action: #selector(processPan))
78 |
79 | panRecognizer.delaysTouchesBegan = false
80 | panRecognizer.delaysTouchesEnded = false
81 |
82 | panRecognizer.delegate = self
83 | addGestureRecognizer(panRecognizer!)
84 | }
85 |
86 | override open func layoutSubviews() {
87 | super.layoutSubviews()
88 |
89 | if middleOriginY < Settings.Sizes.navbarSize { middleOriginY = Settings.Sizes.navbarSize }
90 |
91 | backGroundImageView.frame = bounds
92 |
93 | topView.frame = CGRect(x: 0,
94 | y: 0,
95 | width: bounds.width,
96 | height: Settings.Sizes.middleSize)
97 |
98 | middleView.frame = CGRect(x: 0,
99 | y: middleOriginY,
100 | width: bounds.width,
101 | height: Settings.Sizes.middleViewSize)
102 |
103 | topView.setSizingViewHeight(height: middleView.frame.minY)
104 |
105 | bottomView.frame = CGRect(x: 0,
106 | y: middleView.frame.maxY,
107 | width: bounds.width,
108 | height: bounds.height - middleView.frame.maxY)
109 |
110 | fullscreenView.frame = bounds
111 |
112 | fullscreenView.progress = getNormalizedProgress()
113 |
114 | topView.setSizingViewProgress(progress: (middleView.frame.origin.y - Settings.Sizes.navbarSize) / (Settings.Sizes.middleSize - Settings.Sizes.navbarSize))
115 |
116 | if fullscreenView.state == .vertical {
117 | fullscreenView.setScrollOffset()
118 | }
119 |
120 | if middleOriginY > bounds.height {
121 | panRecognizer.isEnabled = false
122 | fullscreenView.updateVerticalScrollInsets()
123 | }
124 | }
125 |
126 | public func setMiddleView(middleView: UIView) {
127 | self.middleView = middleView
128 | self.setNeedsLayout()
129 | self.setNeedsDisplay()
130 | self.layoutIfNeeded()
131 | }
132 |
133 | public func setData() {
134 | var titles: [String] = []
135 | var images: [UIImage] = []
136 | var controllers: [UIViewController] = []
137 |
138 | for screen in screens {
139 | titles.append(screen.title)
140 | images.append(UIImage.makeImageWithGradient(image: screen.image,
141 | imageAlpha: Settings.imageAlpha,
142 | startColor: screen.startColor,
143 | endColor: screen.endColor))
144 | controllers.append(screen.controller)
145 | }
146 |
147 | topView.setData(titles: titles, images: images)
148 | fullscreenView.setData(titles: titles, images: images)
149 | bottomView.setData(controllers: controllers)
150 |
151 | backGroundImageView.image = backgroundImage
152 | }
153 |
154 | }
155 |
156 | extension NavigationView {
157 |
158 | @objc private func processPan() {
159 | var translation = panRecognizer.translation(in: self)
160 |
161 | var canPan: Bool = false
162 |
163 | let controlRect: CGRect = CGRect(x: 0,
164 | y: 0,
165 | width: bounds.width,
166 | height: middleOriginY + Settings.Sizes.middleViewSize)
167 |
168 | let touchLocation = panRecognizer.location(in: self)
169 |
170 | let velocity = panRecognizer.velocity(in: self)
171 |
172 | if controlRect.contains(touchLocation) {
173 | canPan = true
174 | }
175 |
176 | if bottomView.canScrollDown {
177 | canPan = true
178 | }
179 |
180 | var currentDirection: Int = 0
181 |
182 | if velocity.y > 0 {
183 | currentDirection = 2
184 | } else {
185 | currentDirection = 1
186 | }
187 |
188 | if currentDirection == 1 && middleOriginY >= Settings.Sizes.middleSize {
189 | bottomView.canScroll = false
190 | } else {
191 | bottomView.canScroll = true
192 | }
193 |
194 | switch panRecognizer.state {
195 | case .began, .changed:
196 | if canPan {
197 | topView.isScrollingEnabled = false
198 | bottomView.isScrollingEnabled = false
199 | middleOriginY = middleView.frame.origin.y + translation.y
200 | if middleOriginY < Settings.Sizes.navbarSize { middleOriginY = Settings.Sizes.navbarSize }
201 | if translation.y < Settings.Sizes.navbarSize { translation.y = Settings.Sizes.navbarSize }
202 |
203 | if 0...Settings.Sizes.navbarSize ~= middleOriginY {
204 | topView.isHidden = false
205 | topView.hideSizingView()
206 | topView.toggleTopStateViews()
207 | fullscreenView.state = .horizontal
208 | fullscreenView.updateHorizontalScrollInsets()
209 | } else if Settings.Sizes.navbarSize + 1.. bounds.height {
231 | fullscreenView.isHidden = false
232 | panRecognizer.isEnabled = false
233 | fullscreenView.updateVerticalScrollInsets()
234 | canPan = false
235 | fullscreenView.resetAlpha()
236 | }
237 | }
238 |
239 | case .possible, .ended, .cancelled, .failed:
240 | topView.isScrollingEnabled = true
241 | bottomView.isScrollingEnabled = true
242 | if 0...Settings.Sizes.middleSizeHalf ~= middleOriginY {
243 | UIView.animate(withDuration: Settings.animationsDuration, animations: {
244 | self.middleOriginY = Settings.Sizes.navbarSize
245 | self.topView.setSizingViewProgress(progress: 0.0)
246 | }) { _ in
247 | self.topView.hideSizingView()
248 | self.topView.isHidden = false
249 | self.topView.toggleTopStateViews()
250 | self.fullscreenView.updateHorizontalScrollInsets()
251 | }
252 | } else if Settings.Sizes.middleSizeHalf + 1...Settings.Sizes.middleSize ~= middleOriginY {
253 | UIView.animate(withDuration: Settings.animationsDuration, animations: {
254 | self.middleOriginY = Settings.Sizes.middleSize
255 | self.topView.setSizingViewProgress(progress: 1.0)
256 | }) { _ in
257 | self.topView.hideSizingView()
258 | self.topView.isHidden = false
259 | self.topView.toggleMiddleStateViews()
260 | self.fullscreenView.updateHorizontalScrollInsets()
261 | }
262 | } else if Settings.Sizes.middleSize + 1...bounds.height * 0.75 ~= middleOriginY {
263 | UIView.animate(withDuration: Settings.animationsDuration, animations: {
264 | self.middleOriginY = Settings.Sizes.middleSize
265 | }) { _ in
266 | self.topView.hideSizingView()
267 | self.topView.isHidden = false
268 | self.fullscreenView.isHidden = true
269 | self.topView.toggleMiddleStateViews()
270 | self.fullscreenView.updateVerticalScrollInsets()
271 | }
272 | } else if bounds.height * 0.75 + 1...bounds.height ~= middleOriginY {
273 | UIView.animate(withDuration: Settings.animationsDuration, animations: {
274 | self.middleOriginY = self.bounds.height
275 | }) { _ in
276 | self.topView.hideSizingView()
277 | self.fullscreenView.updateVerticalScrollInsets()
278 | self.panRecognizer.isEnabled = false
279 | }
280 | }
281 |
282 | @unknown default:
283 | break
284 | }
285 | panRecognizer.setTranslation(CGPoint.zero, in: self)
286 | }
287 |
288 | }
289 |
290 | extension NavigationView: UIGestureRecognizerDelegate {
291 |
292 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }
293 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { return false }
294 | public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { return false }
295 |
296 | override open func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
297 | let velocity = panRecognizer.velocity(in: self)
298 | return abs(velocity.y) > abs(velocity.x)
299 | }
300 |
301 | }
302 |
303 | extension NavigationView: FulllscreenViewDelegate {
304 |
305 | func didTapCell(index: Int) {
306 | currentIndex = index
307 | topView.updateOffsets()
308 | bottomView.updateOffsets()
309 | panRecognizer.isEnabled = true
310 |
311 | UIView.animate(withDuration: Settings.animationsDuration, delay: 0.0, options: .curveEaseOut, animations: {
312 | self.middleOriginY = Settings.Sizes.middleSize
313 | self.setNeedsLayout()
314 | self.layoutIfNeeded()
315 | }) { completed in
316 | if completed {
317 | self.topView.isHidden = false
318 | self.fullscreenView.isHidden = true
319 | self.topView.toggleMiddleStateViews()
320 | self.fullscreenView.updateHorizontalScrollInsets()
321 | }
322 | }
323 | }
324 |
325 | }
326 |
327 | extension NavigationView {
328 |
329 | private func getNormalizedProgress() -> CGFloat {
330 | if Settings.Sizes.middleSize...bounds.height ~= middleView.frame.origin.y {
331 | let diff: CGFloat = bounds.height - Settings.Sizes.middleSize
332 |
333 | return (middleView.frame.minY - Settings.Sizes.middleSize) / diff > 1.0 ? 1.0 : (middleView.frame.minY - Settings.Sizes.middleSize) / diff
334 | }
335 | if middleView.frame.origin.y > bounds.height {
336 | return 1.0
337 | }
338 |
339 | return 0.0
340 | }
341 | }
342 |
343 | extension NavigationView: BottomViewDelegate {
344 |
345 | func bottomDidScroll(offset: CGFloat) {
346 | topView.currentOffset = offset
347 | topView.updateIndex()
348 | }
349 | }
350 |
351 | extension NavigationView: TopViewDelegate {
352 |
353 | func topDidScroll(offset: CGFloat) {
354 | bottomView.currentOffset = offset
355 | topView.updateIndex()
356 | }
357 | }
358 |
--------------------------------------------------------------------------------
/Sources/Objects/ScreenObject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScreenObject.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | open class ScreenObject {
13 |
14 | public let title: String
15 | public let startColor: UIColor
16 | public let endColor: UIColor
17 | public let image: UIImage
18 | public let controller: UIViewController
19 |
20 | public init(title: String = "Screen Title",
21 | startColor: UIColor = .red,
22 | endColor: UIColor = .green,
23 | image: UIImage = UIImage(),
24 | controller: UIViewController = UIViewController()) {
25 |
26 | self.title = title
27 | self.startColor = startColor
28 | self.endColor = endColor
29 | self.image = image
30 | self.controller = controller
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Sources/Settings/Settings.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Settings.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | public struct Settings {
13 |
14 | public struct Sizes {
15 | public static let isX: Bool = UIScreen.main.nativeBounds.height == 2436 ? true : false
16 | public static let statusbarSize: CGFloat = UIApplication.shared.statusBarFrame.height
17 | public static let navbarSize: CGFloat = isX ? 88 : 64
18 | public static let middleSize: CGFloat = Settings.Sizes.screenHeight / 2 - middleViewSize / 2
19 | public static let middleSizeHalf: CGFloat = (Settings.Sizes.screenHeight / 2 - middleViewSize / 2) / 2
20 | public static let fullSize: CGFloat = Settings.Sizes.screenHeight
21 | public static let middleViewSize: CGFloat = 65.5
22 | public static let menuItemsSize: CGFloat = 120.0
23 | public static let screenWidth = UIScreen.main.bounds.width
24 | public static let screenHeight = UIScreen.main.bounds.height
25 | public static let labelFontSize: CGFloat = 23
26 | public static let yOffset: CGFloat = isX ? 32 : 20
27 | public static let mainOffset: CGFloat = 200
28 | }
29 |
30 | public static var animationsDuration: TimeInterval = 0.35
31 | public static var imageCrossOffset: CGFloat = 20
32 | public static var imageAlpha: CGFloat = 0.33
33 | public static var menuItemsSpacing: CGFloat = 4
34 | public static var menuItemTextMargin: CGFloat = 40
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/SubViews/BottomView/BottomView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BottomView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView {
12 |
13 | func subViews(type: T.Type) -> [T] {
14 | var all = [T]()
15 | for view in self.subviews {
16 | if let aView = view as? T {
17 | all.append(aView)
18 | }
19 | }
20 | return all
21 | }
22 |
23 | func allSubViewsOf(type: T.Type) -> [T] {
24 | var all = [T]()
25 | func getSubview(view: UIView) {
26 | if let aView = view as? T {
27 | all.append(aView)
28 | }
29 | guard view.subviews.count>0 else { return }
30 | view.subviews.forEach { getSubview(view: $0) }
31 | }
32 | getSubview(view: self)
33 |
34 | return all
35 | }
36 | }
37 |
38 | protocol BottomViewDelegate {
39 | func bottomDidScroll(offset: CGFloat)
40 | }
41 |
42 | class BottomView: UIView {
43 |
44 | private var scrollView: UIScrollView = UIScrollView()
45 | private var controllers: [UIViewController] = []
46 |
47 | var delegate: BottomViewDelegate?
48 |
49 | var isScrollingEnabled: Bool = true {
50 | didSet {
51 | scrollView.isScrollEnabled = isScrollingEnabled
52 | }
53 | }
54 |
55 | var canScroll: Bool = true {
56 | didSet {
57 | let needle = getRequiredView()
58 | needle.isScrollEnabled = canScroll
59 | }
60 | }
61 |
62 | var canScrollDown: Bool {
63 | get {
64 | let needle = getRequiredView()
65 | if needle.contentOffset.y <= 0 {
66 | return true
67 | }
68 | return false
69 | }
70 | }
71 |
72 | var currentOffset: CGFloat = 0.0 {
73 | didSet {
74 | self.scrollView.contentOffset.x = currentOffset
75 | }
76 | }
77 |
78 | var currentIndex: Int = 0
79 |
80 | override init(frame: CGRect) {
81 | super.init(frame: frame)
82 | setup()
83 | }
84 |
85 | required init?(coder aDecoder: NSCoder) {
86 | super.init(coder: aDecoder)
87 | setup()
88 | }
89 |
90 | private func getRequiredView() -> UIScrollView {
91 | let allSubviews = scrollView.allSubViewsOf(type: UIScrollView.self)
92 |
93 | var i = 0
94 | for view in allSubviews {
95 | if view.contentSize.width == bounds.width {
96 | let frame = (view.convert(view.frame, to: self))
97 | if frame.origin.x == 0 {
98 | return view
99 | }
100 | i += 1
101 | }
102 | }
103 |
104 | return UIScrollView()
105 | }
106 |
107 | private func setup() {
108 | scrollView.showsVerticalScrollIndicator = false
109 | scrollView.showsHorizontalScrollIndicator = false
110 | scrollView.isPagingEnabled = true
111 | scrollView.delegate = self
112 |
113 | addSubview(scrollView)
114 | }
115 |
116 | override func layoutSubviews() {
117 | super.layoutSubviews()
118 |
119 | scrollView.frame = bounds
120 | scrollView.contentSize = CGSize(width : CGFloat(controllers.count) * bounds.width, height : bounds.height)
121 |
122 | for (i, controller) in controllers.enumerated() {
123 | controller.view.frame = CGRect(x: CGFloat(i) * bounds.width, y: 0, width: bounds.width, height: bounds.height)
124 | }
125 | }
126 |
127 | func setData(controllers: [UIViewController]) {
128 | self.controllers = controllers
129 |
130 | for controller in self.controllers {
131 | scrollView.addSubview(controller.view)
132 | }
133 | setNeedsLayout()
134 | layoutIfNeeded()
135 | }
136 |
137 | func updateOffsets() {
138 | scrollView.setContentOffset(CGPoint(x: CGFloat(currentIndex) * Settings.Sizes.screenWidth, y: 0), animated: false)
139 | }
140 |
141 | }
142 |
143 | extension BottomView: UIScrollViewDelegate {
144 |
145 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
146 | if scrollView == self.scrollView {
147 | delegate?.bottomDidScroll(offset: scrollView.contentOffset.x)
148 | }
149 | }
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/Sources/SubViews/FullscreenView/CellView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AnimatedView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol CellViewDelegate: class {
12 | func didTapCell(index: Int, cell: CellView)
13 | }
14 |
15 | class CellView: UIView {
16 |
17 | private var imageView: UIImageView = UIImageView()
18 | private var label: UILabel = UILabel()
19 | private var view: UIView = UIView()
20 |
21 | private var imageLeftOffsetMax: CGFloat = 100
22 | private var imageLeftOffsetCurrent: CGFloat = 0
23 | private var tapGest: UITapGestureRecognizer = UITapGestureRecognizer()
24 |
25 | private var progress: CGFloat = 0.0
26 |
27 | weak var delegate: CellViewDelegate?
28 |
29 | var index: Int = 0
30 |
31 | override init(frame: CGRect) {
32 | super.init(frame: frame)
33 | setup()
34 | }
35 |
36 | required init?(coder aDecoder: NSCoder) {
37 | super.init(coder: aDecoder)
38 | setup()
39 | }
40 |
41 | private func setup() {
42 | self.backgroundColor = .clear
43 |
44 | self.clipsToBounds = true
45 |
46 | imageView.contentMode = .scaleAspectFill
47 | imageView.clipsToBounds = true
48 | imageView.isHidden = false
49 |
50 | view.backgroundColor = .white
51 |
52 | label.textAlignment = .left
53 | label.clipsToBounds = false
54 | label.textColor = .white
55 | label.font = UIFont.systemFont(ofSize : 23)
56 |
57 | label.isHidden = false
58 |
59 | tapGest.addTarget(self, action: #selector(tapCell))
60 | self.addGestureRecognizer(tapGest)
61 |
62 | self.addSubview(imageView)
63 | self.addSubview(view)
64 | }
65 |
66 | override func layoutSubviews() {
67 | super.layoutSubviews()
68 |
69 | let w = self.bounds.width
70 | let h = self.bounds.height
71 |
72 | let half = w / 2 - label.intrinsicContentSize.width / 2
73 |
74 | label.frame = CGRect(x: half - (half - Settings.menuItemTextMargin) * progress,
75 | y: 0,
76 | width: label.intrinsicContentSize.width,
77 | height: h)
78 |
79 | imageView.frame = CGRect(x: -Settings.imageCrossOffset + imageLeftOffsetCurrent,
80 | y: 0,
81 | width: bounds.width + 2 * Settings.imageCrossOffset,
82 | height: bounds.height)
83 | }
84 |
85 | @objc private func tapCell() {
86 | self.delegate?.didTapCell(index: index, cell: self)
87 | }
88 |
89 | func setData(title: String, image: UIImage, index: Int) {
90 | label.text = title
91 | imageView.image = image
92 | self.index = index
93 | }
94 |
95 | func setState(progress: CGFloat, state: State) {
96 | imageLeftOffsetCurrent = imageLeftOffsetMax * progress
97 | self.progress = progress
98 |
99 | self.setNeedsLayout()
100 | self.layoutIfNeeded()
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/Sources/SubViews/FullscreenView/FulllscreenView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FulllscreenView.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol FulllscreenViewDelegate {
12 | func didTapCell(index: Int)
13 | }
14 |
15 | class FulllscreenView: UIView {
16 |
17 | var scrollView: UIScrollView = UIScrollView()
18 |
19 | var delegate: FulllscreenViewDelegate?
20 |
21 | private var animatedViews: [CellView] = []
22 | private var labelViews: [LabelView] = []
23 |
24 | private var images: [UIImage] = []
25 | private var titles: [String] = []
26 |
27 | var progress: CGFloat = 0 {
28 | didSet {
29 | setNeedsLayout()
30 | layoutIfNeeded()
31 | }
32 | }
33 |
34 | var currentIndex: Int = 0
35 |
36 | var state: State = .horizontal {
37 | didSet {
38 | setNeedsLayout()
39 | layoutIfNeeded()
40 | }
41 | }
42 |
43 | override init(frame: CGRect) {
44 | super.init(frame: frame)
45 | setup()
46 | }
47 |
48 | required init?(coder aDecoder: NSCoder) {
49 | super.init(coder: aDecoder)
50 | setup()
51 | }
52 |
53 | private func setup() {
54 | backgroundColor = .clear
55 | scrollView.showsHorizontalScrollIndicator = false
56 | scrollView.showsVerticalScrollIndicator = false
57 | scrollView.alwaysBounceHorizontal = false
58 |
59 | addSubview(scrollView)
60 | }
61 |
62 | override func layoutSubviews() {
63 | super.layoutSubviews()
64 |
65 | scrollView.frame = bounds
66 | scrollView.contentSize = CGSize(width: bounds.width * CGFloat(images.count),
67 | height: CGFloat(images.count) * (Settings.menuItemsSpacing + Settings.Sizes.menuItemsSize))
68 |
69 | for i in 0..= 0 {
78 | prevLabel = labelViews[currentIndex - 1].label
79 | }
80 | if currentIndex + 1 <= labelViews.count - 1 {
81 | nextLabel = labelViews[currentIndex + 1].label
82 | }
83 |
84 | var right: CGFloat {
85 | get {
86 | switch Settings.Sizes.screenWidth {
87 | case 320: return 128
88 | case 375: return 150
89 | case 414: return 166
90 | default: return 0
91 | }
92 | }
93 | }
94 |
95 | for labelView in labelViews {
96 | if labelView != labelViews[currentIndex] {
97 | labelView.label.alpha = 0.3 + progress * 0.7
98 | }
99 | labelViews[currentIndex].label.alpha = 1.0
100 | }
101 |
102 | prevLabel.frame = CGRect(x: prevLabel.frame.origin.x + right * (1 - progress),
103 | y: prevLabel.frame.origin.y,
104 | width: prevLabel.frame.width,
105 | height: prevLabel.frame.height)
106 |
107 | nextLabel.frame = CGRect(x: nextLabel.frame.origin.x - right + right * progress,
108 | y: nextLabel.frame.origin.y,
109 | width: nextLabel.frame.width,
110 | height: nextLabel.frame.height)
111 | }
112 |
113 | func resetAlpha() {
114 | for label in labelViews {
115 | label.alpha = 1.0
116 | }
117 | }
118 |
119 | private func makeViews() {
120 | for i in 0.. [CGRect] {
147 | var frames: [CGRect] = []
148 |
149 | if state == .horizontal {
150 | for i in 0.. Int {
188 | return images.count
189 | }
190 |
191 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
192 | switch collectionView {
193 | case collectionViewTop:
194 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TopViewCellOne.self), for: indexPath) as! TopViewCellOne
195 | cell.setData(title: titles[indexPath.row], image: images[indexPath.row])
196 | return cell
197 | case collectionViewMiddleImage:
198 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TopViewCellTwo.self), for: indexPath) as! TopViewCellTwo
199 | cell.setImage(image: images[indexPath.row])
200 | return cell
201 | case collectionViewMiddleText:
202 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TopViewCellThree.self), for: indexPath) as! TopViewCellThree
203 | cell.setTitle(title: titles[indexPath.row])
204 | return cell
205 | default:
206 | break
207 | }
208 |
209 | return UICollectionViewCell()
210 | }
211 |
212 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
213 | return CGSize(width: bounds.width, height: collectionView.frame.height)
214 | }
215 |
216 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
217 | return .zero
218 | }
219 |
220 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
221 | return 0
222 | }
223 |
224 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
225 | return 0
226 | }
227 |
228 | }
229 |
230 | extension TopView: UIScrollViewDelegate {
231 |
232 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
233 | updateIndex()
234 | }
235 |
236 | func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) {
237 | updateIndex()
238 | }
239 |
240 | func updateIndex() {
241 | currentIndex = Int(collectionViewMiddleImage.contentOffset.x / Settings.Sizes.screenWidth)
242 | guard let navView = superview as? NavigationView else { return }
243 | navView.currentIndex = currentIndex
244 | }
245 |
246 | func scrollViewDidScroll(_ scrollView: UIScrollView) {
247 | if collectionViewMiddleText.isTracking {
248 | collectionViewTop.contentOffset.x = collectionViewMiddleText.contentOffset.x
249 | collectionViewMiddleImage.contentOffset.x = collectionViewMiddleText.contentOffset.x
250 | delegate?.topDidScroll(offset: collectionViewMiddleText.contentOffset.x)
251 | }
252 | if collectionViewMiddleText.isDragging {
253 | collectionViewTop.contentOffset.x = collectionViewMiddleText.contentOffset.x
254 | collectionViewMiddleImage.contentOffset.x = collectionViewMiddleText.contentOffset.x
255 | delegate?.topDidScroll(offset: collectionViewMiddleText.contentOffset.x)
256 | }
257 | if collectionViewMiddleText.isDecelerating {
258 | collectionViewTop.contentOffset.x = collectionViewMiddleText.contentOffset.x
259 | collectionViewMiddleImage.contentOffset.x = collectionViewMiddleText.contentOffset.x
260 | delegate?.topDidScroll(offset: collectionViewMiddleText.contentOffset.x)
261 | }
262 |
263 | if collectionViewTop.isTracking {
264 | collectionViewMiddleText.contentOffset.x = collectionViewTop.contentOffset.x
265 | collectionViewMiddleImage.contentOffset.x = collectionViewTop.contentOffset.x
266 | delegate?.topDidScroll(offset: collectionViewTop.contentOffset.x)
267 | }
268 | if collectionViewTop.isDragging {
269 | collectionViewMiddleText.contentOffset.x = collectionViewTop.contentOffset.x
270 | collectionViewMiddleImage.contentOffset.x = collectionViewTop.contentOffset.x
271 | delegate?.topDidScroll(offset: collectionViewTop.contentOffset.x)
272 | }
273 | if collectionViewTop.isDecelerating {
274 | collectionViewMiddleText.contentOffset.x = collectionViewTop.contentOffset.x
275 | collectionViewMiddleImage.contentOffset.x = collectionViewTop.contentOffset.x
276 | delegate?.topDidScroll(offset: collectionViewTop.contentOffset.x)
277 | }
278 | }
279 |
280 | }
281 |
282 | extension TopView {
283 |
284 | func setData(titles: [String], images: [UIImage]) {
285 | self.titles = titles
286 | self.images = images
287 |
288 | collectionViewTop.reloadData()
289 | collectionViewMiddleImage.reloadData()
290 | collectionViewMiddleText.reloadData()
291 | updateIndex()
292 | }
293 |
294 | private func updateSizingView(index: Int) {
295 | var previousTitle: String = ""
296 | var nextTitle: String = ""
297 |
298 | if index - 1 >= 0 {
299 | previousTitle = titles[index - 1]
300 | }
301 | if index + 1 <= titles.count - 1 {
302 | nextTitle = titles[index + 1]
303 | }
304 |
305 | sizingView.setData(title: titles[index],
306 | image: images[index],
307 | previousTitle: previousTitle,
308 | nextTitle: nextTitle)
309 | }
310 |
311 | func updateOffsets() {
312 | let collectionContentOffset = CGPoint(x: CGFloat(currentIndex) * Settings.Sizes.screenWidth, y: 0)
313 |
314 | collectionViewTop.setContentOffset(collectionContentOffset, animated: false)
315 | collectionViewMiddleImage.setContentOffset(collectionContentOffset, animated: false)
316 | collectionViewMiddleText.setContentOffset(collectionContentOffset, animated: false)
317 | }
318 |
319 | }
320 |
--------------------------------------------------------------------------------
/Sources/SubViews/TopView/TopViewAnimators.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TopViewAnimators.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | protocol LayoutAttributesAnimator {
12 | func animate(collectionView: UICollectionView, attributes: AnimatedCollectionViewLayoutAttributes)
13 | }
14 |
15 | struct FadeAnimator: LayoutAttributesAnimator {
16 | init() {}
17 |
18 | func animate(collectionView: UICollectionView, attributes: AnimatedCollectionViewLayoutAttributes) {
19 | let position = attributes.middleOffset
20 | let contentOffset = collectionView.contentOffset
21 |
22 | attributes.frame = CGRect(x: contentOffset.x + abs(position) * 5, y: contentOffset.y, width: attributes.frame.width, height: attributes.frame.height)
23 | attributes.alpha = 1 - abs(position)
24 | }
25 | }
26 |
27 | struct MovementAnimator: LayoutAttributesAnimator {
28 | var minAlpha: CGFloat
29 | var itemSpacing: CGFloat
30 | var scaleRate: CGFloat
31 |
32 | public init(minAlpha: CGFloat = 0.33,
33 | itemSpacing: CGFloat = 0.4,
34 | scaleRate: CGFloat = 1) {
35 | self.minAlpha = minAlpha
36 | self.itemSpacing = itemSpacing
37 | self.scaleRate = scaleRate
38 | }
39 |
40 | func animate(collectionView: UICollectionView, attributes: AnimatedCollectionViewLayoutAttributes) {
41 | let position = attributes.middleOffset
42 | let scaleFactor = scaleRate
43 | let scaleTransform = CGAffineTransform(scaleX : scaleFactor, y : scaleFactor)
44 |
45 | let translationTransform: CGAffineTransform
46 |
47 | if attributes.scrollDirection == .horizontal {
48 | let width = collectionView.frame.width
49 | let translationX = -(width * itemSpacing * position)
50 | translationTransform = CGAffineTransform(translationX : translationX, y : 0)
51 | } else {
52 | let height = collectionView.frame.height
53 | let translationY = -(height * itemSpacing * position)
54 | translationTransform = CGAffineTransform(translationX : 0, y : translationY)
55 | }
56 |
57 | attributes.alpha = 1.0 - abs(position) + minAlpha
58 | attributes.transform = translationTransform.concatenating(scaleTransform)
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Sources/SubViews/TopView/TopViewCells.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TopViewCells.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class TopViewCellOne: UICollectionViewCell {
13 |
14 | var imageView = UIImageView()
15 | var label = Label.topViewCellLabel()
16 |
17 | override init(frame: CGRect) {
18 | super.init(frame: frame)
19 | setup()
20 | }
21 |
22 | required init?(coder aDecoder: NSCoder) {
23 | super.init(coder: aDecoder)
24 | setup()
25 | }
26 |
27 | private func setup() {
28 | backgroundColor = .clear
29 |
30 | imageView.contentMode = .scaleAspectFill
31 | imageView.clipsToBounds = true
32 |
33 | self.addSubview(imageView)
34 | self.addSubview(label)
35 | }
36 |
37 | override func layoutSubviews() {
38 | super.layoutSubviews()
39 |
40 |
41 | label.frame = CGRect(x: 0,
42 | y: Settings.Sizes.yOffset,
43 | width: bounds.width,
44 | height: bounds.height - Settings.Sizes.yOffset)
45 |
46 | imageView.frame = CGRect(x: -Settings.imageCrossOffset,
47 | y: 0,
48 | width: bounds.width + 2 * Settings.imageCrossOffset,
49 | height: bounds.height)
50 | }
51 |
52 | func setData(title: String, image: UIImage) {
53 | label.text = title
54 | imageView.image = image
55 | }
56 |
57 | }
58 |
59 | class TopViewCellTwo: UICollectionViewCell {
60 |
61 | var imageView = UIImageView()
62 |
63 | override init(frame: CGRect) {
64 | super.init(frame: frame)
65 | setup()
66 | }
67 |
68 | required init?(coder aDecoder: NSCoder) {
69 | super.init(coder: aDecoder)
70 | setup()
71 | }
72 |
73 | private func setup() {
74 | imageView.contentMode = .scaleAspectFill
75 | imageView.clipsToBounds = true
76 |
77 | self.addSubview(imageView)
78 | }
79 |
80 | override func layoutSubviews() {
81 | super.layoutSubviews()
82 |
83 | imageView.frame = CGRect(x: -Settings.imageCrossOffset,
84 | y: 0,
85 | width: bounds.width + 2 * Settings.imageCrossOffset,
86 | height: bounds.height)
87 | }
88 |
89 | func setImage(image: UIImage) {
90 | imageView.image = image
91 | }
92 |
93 | }
94 |
95 | class TopViewCellThree: UICollectionViewCell {
96 |
97 | var label = Label.topViewCellLabel()
98 |
99 | override init(frame: CGRect) {
100 | super.init(frame: frame)
101 | setup()
102 | }
103 |
104 | required init?(coder aDecoder: NSCoder) {
105 | super.init(coder: aDecoder)
106 | setup()
107 | }
108 |
109 | private func setup() {
110 | self.addSubview(label)
111 | }
112 |
113 | override func layoutSubviews() {
114 | super.layoutSubviews()
115 |
116 | label.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height)
117 | }
118 |
119 | func setTitle(title: String) {
120 | label.text = title
121 | }
122 |
123 | }
124 |
--------------------------------------------------------------------------------
/Sources/SubViews/TopView/TopViewCollectionLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TopViewCollectionLayout.swift
3 | // NavigationToolbar
4 | //
5 | // Created by Artem P. on 22/05/2018.
6 | // Copyright © 2018 Ramotion. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class AnimatedCollectionViewLayout: UICollectionViewFlowLayout {
13 |
14 | var animator: LayoutAttributesAnimator?
15 |
16 | override class var layoutAttributesClass: AnyClass { return AnimatedCollectionViewLayoutAttributes.self }
17 |
18 | override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
19 | guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
20 | return attributes.compactMap { $0.copy() as? AnimatedCollectionViewLayoutAttributes }.map { self.transformLayoutAttributes($0) }
21 | }
22 |
23 | override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true }
24 |
25 | private func transformLayoutAttributes(_ attributes: AnimatedCollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
26 | guard let collectionView = self.collectionView else { return attributes }
27 |
28 | let attrs = attributes
29 |
30 | let distance: CGFloat
31 | let itemOffset: CGFloat
32 |
33 | if scrollDirection == .horizontal {
34 | distance = collectionView.frame.width
35 | itemOffset = attrs.center.x - collectionView.contentOffset.x
36 | attrs.startOffset = (attrs.frame.origin.x - collectionView.contentOffset.x) / attrs.frame.width
37 | attrs.endOffset = (attrs.frame.origin.x - collectionView.contentOffset.x - collectionView.frame.width) / attrs.frame.width
38 | } else {
39 | distance = collectionView.frame.height
40 | itemOffset = attrs.center.y - collectionView.contentOffset.y
41 | attrs.startOffset = (attrs.frame.origin.y - collectionView.contentOffset.y) / attrs.frame.height
42 | attrs.endOffset = (attrs.frame.origin.y - collectionView.contentOffset.y - collectionView.frame.height) / attrs.frame.height
43 | }
44 |
45 | attrs.scrollDirection = scrollDirection
46 | attrs.middleOffset = itemOffset / distance - 0.5
47 |
48 | if attrs.contentView == nil,
49 | let c = collectionView.cellForItem(at: attributes.indexPath)?.contentView {
50 | attrs.contentView = c
51 | }
52 |
53 | animator?.animate(collectionView: collectionView, attributes: attrs)
54 |
55 | return attrs
56 | }
57 |
58 | }
59 |
60 | public class AnimatedCollectionViewLayoutAttributes: UICollectionViewLayoutAttributes {
61 |
62 | var contentView: UIView?
63 | var scrollDirection: UICollectionView.ScrollDirection = .vertical
64 |
65 | var startOffset: CGFloat = 0
66 | var middleOffset: CGFloat = 0
67 | var endOffset: CGFloat = 0
68 |
69 | public override func copy(with zone: NSZone? = nil) -> Any {
70 | let copy = super.copy(with: zone) as! AnimatedCollectionViewLayoutAttributes
71 | copy.contentView = contentView
72 | copy.scrollDirection = scrollDirection
73 | copy.startOffset = startOffset
74 | copy.middleOffset = middleOffset
75 | copy.endOffset = endOffset
76 | return copy
77 | }
78 |
79 | public override func isEqual(_ object: Any?) -> Bool {
80 | guard let o = object as? AnimatedCollectionViewLayoutAttributes else { return false }
81 |
82 | return super.isEqual(o)
83 | && o.contentView == contentView
84 | && o.scrollDirection == scrollDirection
85 | && o.startOffset == startOffset
86 | && o.middleOffset == middleOffset
87 | && o.endOffset == endOffset
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/header.png
--------------------------------------------------------------------------------
/iOS-Navigation-Toolbar-1x.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Ramotion/navigation-toolbar/6d917775fb4f72fea8f2706a4bb0ba0db4787332/iOS-Navigation-Toolbar-1x.gif
--------------------------------------------------------------------------------