├── .gitignore
├── .readme
├── logo.png
└── tinderbar.gif
├── LICENSE
├── README.md
├── Sources
├── Tinderbar.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Tinderbar
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── app_icon-1.png
│ │ ├── app_icon-2.png
│ │ └── app_icon.png
│ ├── Contents.json
│ ├── ic_launch_logo.imageset
│ │ ├── Contents.json
│ │ ├── ic_launch_logo.png
│ │ ├── ic_launch_logo@2x.png
│ │ └── ic_launch_logo@3x.png
│ ├── ic_matches.imageset
│ │ ├── Contents.json
│ │ └── ic_tinder.pdf
│ ├── ic_messages.imageset
│ │ ├── Contents.json
│ │ └── ic_messages.pdf
│ └── ic_profile.imageset
│ │ ├── Contents.json
│ │ └── ic_profile.pdf
│ ├── Bars
│ ├── MessagesBar
│ │ └── MessagesBar.swift
│ └── TinderBar
│ │ ├── TinderBar.swift
│ │ ├── TinderBarButton.swift
│ │ ├── TinderBarButtonContainer.swift
│ │ └── TinderBarLayout.swift
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Root.storyboard
│ ├── Info.plist
│ ├── RootTabViewController.swift
│ ├── TinderColors.swift
│ ├── Utilities
│ └── UIColor+Interpolation.swift
│ └── ViewControllers
│ ├── Matches
│ ├── Matches.storyboard
│ └── MatchesViewController.swift
│ ├── Messages
│ ├── Messages.storyboard
│ ├── MessagesFeedViewController.swift
│ ├── MessagesTabViewController.swift
│ ├── MessagesViewController.swift
│ └── Views
│ │ ├── MessagesFeedCell.swift
│ │ ├── MessagesFeedCell.xib
│ │ ├── MessagesMessageCell.swift
│ │ └── MessagesMessageCell.xib
│ └── Profile
│ ├── Profile.storyboard
│ └── ProfileViewController.swift
├── Tinderbar.sketch
└── Tinderbar.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
├── IDEWorkspaceChecks.plist
└── swiftpm
└── Package.resolved
/.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 | # Package.resolved
41 | .build/
42 |
43 | # CocoaPods
44 | #
45 | # We recommend against adding the Pods directory to your .gitignore. However
46 | # you should judge for yourself, the pros and cons are mentioned at:
47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
48 | #
49 | # Pods/
50 |
51 | # Carthage
52 | #
53 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
54 | # Carthage/Checkouts
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/**/*.png
67 | fastlane/test_output
68 |
--------------------------------------------------------------------------------
/.readme/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/.readme/logo.png
--------------------------------------------------------------------------------
/.readme/tinderbar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/.readme/tinderbar.gif
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 UI At Six
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ## 🤔 About
7 | Tinderbar is a recreation of the Tinder iOS app's navigation hierarchy using [Tabman](https://github.com/uias/Tabman), a showcase of creating custom Tabman components.
8 |
9 | ### Requirements
10 | Latest version of Xcode.
11 |
12 | ## 🚀 Components
13 | Tinderbar uses Tabman for its primary navigation bar and also sub navigation within the Messages section.
14 |
15 | ### 🔥 TinderBar
16 | A `TMBarView` embedded in a `TMSystemBar`, added to the `.top`.
17 | ```swift
18 | TMBarView
19 | ```
20 |
21 | It uses a custom layout in the form of [`TinderBarLayout`](./Sources/Tinderbar/Bars/TinderBar/TinderBarLayout.swift) and custom [`TinderBarButton`](./Sources/Tinderbar/Bars/TinderBar/TinderBarButton.swift) bar buttons.
22 |
23 | #### TinderBarLayout
24 | - Uses a horizontal stack view for buttons.
25 | - Buttons are inserted into a container, which is constrained to be `0.5x` the width of the `layoutGuide`.
26 | - Padding views of `0.25x` the `layoutGuide` are inserted at the leading and trailing edges of the stack.
27 | - Buttons are centered along the X-axis of their container, with a constant that is updated as the layout `focusArea` is adjusted (they are centered when selected, and offsetted when unselected to ensure they don't venture off screen).
28 |
29 | #### TinderBarButton
30 | - A `TMBarButton` which consists of an image view.
31 | - Image view tint color transitions between `unselectedTintColor` and `tintColor`.
32 | - Image view scales to `1.0` when selected and `0.8` when unselected.
33 |
34 | ### MessageBar
35 | A more regular `TMBarView` using stock Tabman components, added to the `.top`.
36 | ```swift
37 | TMBarView
38 | ```
39 | - `contentMode` of the layout is set to `.fit`.
40 |
41 | ## 👨🏻💻 About
42 | - Created by [Merrick Sapsford](https://github.com/msaps) ([@MerrickSapsford](https://twitter.com/MerrickSapsford)).
43 |
44 | ## 👮🏻♂️ License
45 | The library is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
46 |
--------------------------------------------------------------------------------
/Sources/Tinderbar.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 53;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4612CD4D217E439400C1B4F7 /* RootTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD4C217E439400C1B4F7 /* RootTabViewController.swift */; };
11 | 4612CD51217E5BF500C1B4F7 /* TinderBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD50217E5BF500C1B4F7 /* TinderBar.swift */; };
12 | 4612CD53217E5C0400C1B4F7 /* TinderBarLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD52217E5C0400C1B4F7 /* TinderBarLayout.swift */; };
13 | 4612CD632180E70B00C1B4F7 /* TinderBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD622180E70B00C1B4F7 /* TinderBarButton.swift */; };
14 | 4612CD652180EB7800C1B4F7 /* TinderBarButtonContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD642180EB7800C1B4F7 /* TinderBarButtonContainer.swift */; };
15 | 4612CD672180FFE900C1B4F7 /* TinderColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD662180FFE900C1B4F7 /* TinderColors.swift */; };
16 | 4612CD6A218101EC00C1B4F7 /* UIColor+Interpolation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD69218101EC00C1B4F7 /* UIColor+Interpolation.swift */; };
17 | 4612CD6C2181058900C1B4F7 /* MessagesTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD6B2181058900C1B4F7 /* MessagesTabViewController.swift */; };
18 | 4612CD6E218105AC00C1B4F7 /* MessagesFeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD6D218105AC00C1B4F7 /* MessagesFeedViewController.swift */; };
19 | 4612CD70218106CF00C1B4F7 /* MessagesBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4612CD6F218106CF00C1B4F7 /* MessagesBar.swift */; };
20 | 464264EF217E3FCD0001C4AF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464264EE217E3FCD0001C4AF /* AppDelegate.swift */; };
21 | 464264F4217E3FCD0001C4AF /* Root.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 464264F2217E3FCD0001C4AF /* Root.storyboard */; };
22 | 464264F6217E3FCF0001C4AF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 464264F5217E3FCF0001C4AF /* Assets.xcassets */; };
23 | 464264F9217E3FCF0001C4AF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 464264F7217E3FCF0001C4AF /* LaunchScreen.storyboard */; };
24 | 46426509217E41E10001C4AF /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46426508217E41E10001C4AF /* MessagesViewController.swift */; };
25 | 4642650E217E42270001C4AF /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4642650D217E42270001C4AF /* ProfileViewController.swift */; };
26 | 46426510217E42A60001C4AF /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4642650F217E42A60001C4AF /* Profile.storyboard */; };
27 | 46426512217E42BA0001C4AF /* Messages.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 46426511217E42BA0001C4AF /* Messages.storyboard */; };
28 | 46426515217E42F20001C4AF /* MatchesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46426514217E42F20001C4AF /* MatchesViewController.swift */; };
29 | 46426517217E43040001C4AF /* Matches.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 46426516217E43040001C4AF /* Matches.storyboard */; };
30 | 46D36A4D218614CC0013635D /* MessagesMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D36A4C218614CC0013635D /* MessagesMessageCell.swift */; };
31 | 46D36A4F218614D40013635D /* MessagesMessageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 46D36A4E218614D40013635D /* MessagesMessageCell.xib */; };
32 | 46D36A51218617ED0013635D /* MessagesFeedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D36A50218617ED0013635D /* MessagesFeedCell.swift */; };
33 | 46D36A53218617F60013635D /* MessagesFeedCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 46D36A52218617F60013635D /* MessagesFeedCell.xib */; };
34 | 46F12DF823292C3B000EC76A /* Tabman in Frameworks */ = {isa = PBXBuildFile; productRef = 46F12DF723292C3B000EC76A /* Tabman */; };
35 | /* End PBXBuildFile section */
36 |
37 | /* Begin PBXFileReference section */
38 | 4612CD4C217E439400C1B4F7 /* RootTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootTabViewController.swift; sourceTree = ""; };
39 | 4612CD50217E5BF500C1B4F7 /* TinderBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinderBar.swift; sourceTree = ""; };
40 | 4612CD52217E5C0400C1B4F7 /* TinderBarLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinderBarLayout.swift; sourceTree = ""; };
41 | 4612CD622180E70B00C1B4F7 /* TinderBarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinderBarButton.swift; sourceTree = ""; };
42 | 4612CD642180EB7800C1B4F7 /* TinderBarButtonContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinderBarButtonContainer.swift; sourceTree = ""; };
43 | 4612CD662180FFE900C1B4F7 /* TinderColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TinderColors.swift; sourceTree = ""; };
44 | 4612CD69218101EC00C1B4F7 /* UIColor+Interpolation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Interpolation.swift"; sourceTree = ""; };
45 | 4612CD6B2181058900C1B4F7 /* MessagesTabViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesTabViewController.swift; sourceTree = ""; };
46 | 4612CD6D218105AC00C1B4F7 /* MessagesFeedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesFeedViewController.swift; sourceTree = ""; };
47 | 4612CD6F218106CF00C1B4F7 /* MessagesBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesBar.swift; sourceTree = ""; };
48 | 464264EB217E3FCD0001C4AF /* Tinderbar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tinderbar.app; sourceTree = BUILT_PRODUCTS_DIR; };
49 | 464264EE217E3FCD0001C4AF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
50 | 464264F3217E3FCD0001C4AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Root.storyboard; sourceTree = ""; };
51 | 464264F5217E3FCF0001C4AF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
52 | 464264F8217E3FCF0001C4AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
53 | 464264FA217E3FCF0001C4AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 46426501217E40B00001C4AF /* Pageboy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pageboy.framework; path = ../Carthage/Build/iOS/Pageboy.framework; sourceTree = ""; };
55 | 46426502217E40B00001C4AF /* AutoInsetter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AutoInsetter.framework; path = ../Carthage/Build/iOS/AutoInsetter.framework; sourceTree = ""; };
56 | 46426503217E40B00001C4AF /* Tabman.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Tabman.framework; path = ../Carthage/Build/iOS/Tabman.framework; sourceTree = ""; };
57 | 46426508217E41E10001C4AF /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; };
58 | 4642650D217E42270001C4AF /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; };
59 | 4642650F217E42A60001C4AF /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = ""; };
60 | 46426511217E42BA0001C4AF /* Messages.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Messages.storyboard; sourceTree = ""; };
61 | 46426514217E42F20001C4AF /* MatchesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchesViewController.swift; sourceTree = ""; };
62 | 46426516217E43040001C4AF /* Matches.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Matches.storyboard; sourceTree = ""; };
63 | 46D36A4C218614CC0013635D /* MessagesMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesMessageCell.swift; sourceTree = ""; };
64 | 46D36A4E218614D40013635D /* MessagesMessageCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MessagesMessageCell.xib; sourceTree = ""; };
65 | 46D36A50218617ED0013635D /* MessagesFeedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesFeedCell.swift; sourceTree = ""; };
66 | 46D36A52218617F60013635D /* MessagesFeedCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MessagesFeedCell.xib; sourceTree = ""; };
67 | /* End PBXFileReference section */
68 |
69 | /* Begin PBXFrameworksBuildPhase section */
70 | 464264E8217E3FCD0001C4AF /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | 46F12DF823292C3B000EC76A /* Tabman in Frameworks */,
75 | );
76 | runOnlyForDeploymentPostprocessing = 0;
77 | };
78 | /* End PBXFrameworksBuildPhase section */
79 |
80 | /* Begin PBXGroup section */
81 | 4612CD4E217E43C600C1B4F7 /* Resources */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 464264F5217E3FCF0001C4AF /* Assets.xcassets */,
85 | 464264F7217E3FCF0001C4AF /* LaunchScreen.storyboard */,
86 | 464264FA217E3FCF0001C4AF /* Info.plist */,
87 | 4612CD662180FFE900C1B4F7 /* TinderColors.swift */,
88 | );
89 | name = Resources;
90 | sourceTree = "";
91 | };
92 | 4612CD4F217E5BE600C1B4F7 /* Bars */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 46D36A5421861BE90013635D /* TinderBar */,
96 | 46D36A5521861BF40013635D /* MessagesBar */,
97 | );
98 | path = Bars;
99 | sourceTree = "";
100 | };
101 | 4612CD68218101CD00C1B4F7 /* Utilities */ = {
102 | isa = PBXGroup;
103 | children = (
104 | 4612CD69218101EC00C1B4F7 /* UIColor+Interpolation.swift */,
105 | );
106 | path = Utilities;
107 | sourceTree = "";
108 | };
109 | 464264E2217E3FCD0001C4AF = {
110 | isa = PBXGroup;
111 | children = (
112 | 464264ED217E3FCD0001C4AF /* Tinderbar */,
113 | 464264EC217E3FCD0001C4AF /* Products */,
114 | 46426500217E40B00001C4AF /* Frameworks */,
115 | );
116 | sourceTree = "";
117 | };
118 | 464264EC217E3FCD0001C4AF /* Products */ = {
119 | isa = PBXGroup;
120 | children = (
121 | 464264EB217E3FCD0001C4AF /* Tinderbar.app */,
122 | );
123 | name = Products;
124 | sourceTree = "";
125 | };
126 | 464264ED217E3FCD0001C4AF /* Tinderbar */ = {
127 | isa = PBXGroup;
128 | children = (
129 | 464264EE217E3FCD0001C4AF /* AppDelegate.swift */,
130 | 464264F2217E3FCD0001C4AF /* Root.storyboard */,
131 | 4612CD4C217E439400C1B4F7 /* RootTabViewController.swift */,
132 | 4612CD4F217E5BE600C1B4F7 /* Bars */,
133 | 4642650A217E41F30001C4AF /* ViewControllers */,
134 | 4612CD68218101CD00C1B4F7 /* Utilities */,
135 | 4612CD4E217E43C600C1B4F7 /* Resources */,
136 | );
137 | path = Tinderbar;
138 | sourceTree = "";
139 | };
140 | 46426500217E40B00001C4AF /* Frameworks */ = {
141 | isa = PBXGroup;
142 | children = (
143 | 46426502217E40B00001C4AF /* AutoInsetter.framework */,
144 | 46426501217E40B00001C4AF /* Pageboy.framework */,
145 | 46426503217E40B00001C4AF /* Tabman.framework */,
146 | );
147 | name = Frameworks;
148 | sourceTree = "";
149 | };
150 | 4642650A217E41F30001C4AF /* ViewControllers */ = {
151 | isa = PBXGroup;
152 | children = (
153 | 4642650C217E42110001C4AF /* Profile */,
154 | 46426513217E42DB0001C4AF /* Matches */,
155 | 4642650B217E41FC0001C4AF /* Messages */,
156 | );
157 | path = ViewControllers;
158 | sourceTree = "";
159 | };
160 | 4642650B217E41FC0001C4AF /* Messages */ = {
161 | isa = PBXGroup;
162 | children = (
163 | 46426511217E42BA0001C4AF /* Messages.storyboard */,
164 | 4612CD6B2181058900C1B4F7 /* MessagesTabViewController.swift */,
165 | 46426508217E41E10001C4AF /* MessagesViewController.swift */,
166 | 4612CD6D218105AC00C1B4F7 /* MessagesFeedViewController.swift */,
167 | 46D36A4B218614BF0013635D /* Views */,
168 | );
169 | path = Messages;
170 | sourceTree = "";
171 | };
172 | 4642650C217E42110001C4AF /* Profile */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 4642650F217E42A60001C4AF /* Profile.storyboard */,
176 | 4642650D217E42270001C4AF /* ProfileViewController.swift */,
177 | );
178 | path = Profile;
179 | sourceTree = "";
180 | };
181 | 46426513217E42DB0001C4AF /* Matches */ = {
182 | isa = PBXGroup;
183 | children = (
184 | 46426516217E43040001C4AF /* Matches.storyboard */,
185 | 46426514217E42F20001C4AF /* MatchesViewController.swift */,
186 | );
187 | path = Matches;
188 | sourceTree = "";
189 | };
190 | 46D36A4B218614BF0013635D /* Views */ = {
191 | isa = PBXGroup;
192 | children = (
193 | 46D36A4C218614CC0013635D /* MessagesMessageCell.swift */,
194 | 46D36A4E218614D40013635D /* MessagesMessageCell.xib */,
195 | 46D36A50218617ED0013635D /* MessagesFeedCell.swift */,
196 | 46D36A52218617F60013635D /* MessagesFeedCell.xib */,
197 | );
198 | path = Views;
199 | sourceTree = "";
200 | };
201 | 46D36A5421861BE90013635D /* TinderBar */ = {
202 | isa = PBXGroup;
203 | children = (
204 | 4612CD50217E5BF500C1B4F7 /* TinderBar.swift */,
205 | 4612CD52217E5C0400C1B4F7 /* TinderBarLayout.swift */,
206 | 4612CD642180EB7800C1B4F7 /* TinderBarButtonContainer.swift */,
207 | 4612CD622180E70B00C1B4F7 /* TinderBarButton.swift */,
208 | );
209 | path = TinderBar;
210 | sourceTree = "";
211 | };
212 | 46D36A5521861BF40013635D /* MessagesBar */ = {
213 | isa = PBXGroup;
214 | children = (
215 | 4612CD6F218106CF00C1B4F7 /* MessagesBar.swift */,
216 | );
217 | path = MessagesBar;
218 | sourceTree = "";
219 | };
220 | /* End PBXGroup section */
221 |
222 | /* Begin PBXNativeTarget section */
223 | 464264EA217E3FCD0001C4AF /* Tinderbar */ = {
224 | isa = PBXNativeTarget;
225 | buildConfigurationList = 464264FD217E3FCF0001C4AF /* Build configuration list for PBXNativeTarget "Tinderbar" */;
226 | buildPhases = (
227 | 464264E7217E3FCD0001C4AF /* Sources */,
228 | 464264E8217E3FCD0001C4AF /* Frameworks */,
229 | 464264E9217E3FCD0001C4AF /* Resources */,
230 | );
231 | buildRules = (
232 | );
233 | dependencies = (
234 | );
235 | name = Tinderbar;
236 | packageProductDependencies = (
237 | 46F12DF723292C3B000EC76A /* Tabman */,
238 | );
239 | productName = Tinderbar;
240 | productReference = 464264EB217E3FCD0001C4AF /* Tinderbar.app */;
241 | productType = "com.apple.product-type.application";
242 | };
243 | /* End PBXNativeTarget section */
244 |
245 | /* Begin PBXProject section */
246 | 464264E3217E3FCD0001C4AF /* Project object */ = {
247 | isa = PBXProject;
248 | attributes = {
249 | BuildIndependentTargetsInParallel = YES;
250 | LastSwiftUpdateCheck = 1000;
251 | LastUpgradeCheck = 1430;
252 | ORGANIZATIONNAME = "UI At Six";
253 | TargetAttributes = {
254 | 464264EA217E3FCD0001C4AF = {
255 | CreatedOnToolsVersion = 10.0;
256 | };
257 | };
258 | };
259 | buildConfigurationList = 464264E6217E3FCD0001C4AF /* Build configuration list for PBXProject "Tinderbar" */;
260 | compatibilityVersion = "Xcode 9.3";
261 | developmentRegion = en;
262 | hasScannedForEncodings = 0;
263 | knownRegions = (
264 | en,
265 | Base,
266 | );
267 | mainGroup = 464264E2217E3FCD0001C4AF;
268 | packageReferences = (
269 | 46F12DF623292C3B000EC76A /* XCRemoteSwiftPackageReference "Tabman" */,
270 | );
271 | productRefGroup = 464264EC217E3FCD0001C4AF /* Products */;
272 | projectDirPath = "";
273 | projectRoot = "";
274 | targets = (
275 | 464264EA217E3FCD0001C4AF /* Tinderbar */,
276 | );
277 | };
278 | /* End PBXProject section */
279 |
280 | /* Begin PBXResourcesBuildPhase section */
281 | 464264E9217E3FCD0001C4AF /* Resources */ = {
282 | isa = PBXResourcesBuildPhase;
283 | buildActionMask = 2147483647;
284 | files = (
285 | 464264F9217E3FCF0001C4AF /* LaunchScreen.storyboard in Resources */,
286 | 46D36A53218617F60013635D /* MessagesFeedCell.xib in Resources */,
287 | 464264F6217E3FCF0001C4AF /* Assets.xcassets in Resources */,
288 | 46426517217E43040001C4AF /* Matches.storyboard in Resources */,
289 | 46426510217E42A60001C4AF /* Profile.storyboard in Resources */,
290 | 46426512217E42BA0001C4AF /* Messages.storyboard in Resources */,
291 | 464264F4217E3FCD0001C4AF /* Root.storyboard in Resources */,
292 | 46D36A4F218614D40013635D /* MessagesMessageCell.xib in Resources */,
293 | );
294 | runOnlyForDeploymentPostprocessing = 0;
295 | };
296 | /* End PBXResourcesBuildPhase section */
297 |
298 | /* Begin PBXSourcesBuildPhase section */
299 | 464264E7217E3FCD0001C4AF /* Sources */ = {
300 | isa = PBXSourcesBuildPhase;
301 | buildActionMask = 2147483647;
302 | files = (
303 | 4612CD6C2181058900C1B4F7 /* MessagesTabViewController.swift in Sources */,
304 | 4642650E217E42270001C4AF /* ProfileViewController.swift in Sources */,
305 | 46D36A4D218614CC0013635D /* MessagesMessageCell.swift in Sources */,
306 | 46426509217E41E10001C4AF /* MessagesViewController.swift in Sources */,
307 | 4612CD53217E5C0400C1B4F7 /* TinderBarLayout.swift in Sources */,
308 | 4612CD6E218105AC00C1B4F7 /* MessagesFeedViewController.swift in Sources */,
309 | 4612CD672180FFE900C1B4F7 /* TinderColors.swift in Sources */,
310 | 46426515217E42F20001C4AF /* MatchesViewController.swift in Sources */,
311 | 4612CD70218106CF00C1B4F7 /* MessagesBar.swift in Sources */,
312 | 4612CD51217E5BF500C1B4F7 /* TinderBar.swift in Sources */,
313 | 464264EF217E3FCD0001C4AF /* AppDelegate.swift in Sources */,
314 | 4612CD4D217E439400C1B4F7 /* RootTabViewController.swift in Sources */,
315 | 4612CD652180EB7800C1B4F7 /* TinderBarButtonContainer.swift in Sources */,
316 | 46D36A51218617ED0013635D /* MessagesFeedCell.swift in Sources */,
317 | 4612CD6A218101EC00C1B4F7 /* UIColor+Interpolation.swift in Sources */,
318 | 4612CD632180E70B00C1B4F7 /* TinderBarButton.swift in Sources */,
319 | );
320 | runOnlyForDeploymentPostprocessing = 0;
321 | };
322 | /* End PBXSourcesBuildPhase section */
323 |
324 | /* Begin PBXVariantGroup section */
325 | 464264F2217E3FCD0001C4AF /* Root.storyboard */ = {
326 | isa = PBXVariantGroup;
327 | children = (
328 | 464264F3217E3FCD0001C4AF /* Base */,
329 | );
330 | name = Root.storyboard;
331 | sourceTree = "";
332 | };
333 | 464264F7217E3FCF0001C4AF /* LaunchScreen.storyboard */ = {
334 | isa = PBXVariantGroup;
335 | children = (
336 | 464264F8217E3FCF0001C4AF /* Base */,
337 | );
338 | name = LaunchScreen.storyboard;
339 | sourceTree = "";
340 | };
341 | /* End PBXVariantGroup section */
342 |
343 | /* Begin XCBuildConfiguration section */
344 | 464264FB217E3FCF0001C4AF /* Debug */ = {
345 | isa = XCBuildConfiguration;
346 | buildSettings = {
347 | ALWAYS_SEARCH_USER_PATHS = NO;
348 | CLANG_ANALYZER_NONNULL = YES;
349 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
350 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
351 | CLANG_CXX_LIBRARY = "libc++";
352 | CLANG_ENABLE_MODULES = YES;
353 | CLANG_ENABLE_OBJC_ARC = YES;
354 | CLANG_ENABLE_OBJC_WEAK = YES;
355 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
356 | CLANG_WARN_BOOL_CONVERSION = YES;
357 | CLANG_WARN_COMMA = YES;
358 | CLANG_WARN_CONSTANT_CONVERSION = YES;
359 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
360 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
361 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
362 | CLANG_WARN_EMPTY_BODY = YES;
363 | CLANG_WARN_ENUM_CONVERSION = YES;
364 | CLANG_WARN_INFINITE_RECURSION = YES;
365 | CLANG_WARN_INT_CONVERSION = YES;
366 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
367 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
368 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
369 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
370 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
371 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
372 | CLANG_WARN_STRICT_PROTOTYPES = YES;
373 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
374 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
375 | CLANG_WARN_UNREACHABLE_CODE = YES;
376 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
377 | CODE_SIGN_IDENTITY = "iPhone Developer";
378 | COPY_PHASE_STRIP = NO;
379 | DEBUG_INFORMATION_FORMAT = dwarf;
380 | ENABLE_STRICT_OBJC_MSGSEND = YES;
381 | ENABLE_TESTABILITY = YES;
382 | GCC_C_LANGUAGE_STANDARD = gnu11;
383 | GCC_DYNAMIC_NO_PIC = NO;
384 | GCC_NO_COMMON_BLOCKS = YES;
385 | GCC_OPTIMIZATION_LEVEL = 0;
386 | GCC_PREPROCESSOR_DEFINITIONS = (
387 | "DEBUG=1",
388 | "$(inherited)",
389 | );
390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
392 | GCC_WARN_UNDECLARED_SELECTOR = YES;
393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
394 | GCC_WARN_UNUSED_FUNCTION = YES;
395 | GCC_WARN_UNUSED_VARIABLE = YES;
396 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
397 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
398 | MTL_FAST_MATH = YES;
399 | ONLY_ACTIVE_ARCH = YES;
400 | SDKROOT = iphoneos;
401 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
402 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
403 | };
404 | name = Debug;
405 | };
406 | 464264FC217E3FCF0001C4AF /* Release */ = {
407 | isa = XCBuildConfiguration;
408 | buildSettings = {
409 | ALWAYS_SEARCH_USER_PATHS = NO;
410 | CLANG_ANALYZER_NONNULL = YES;
411 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
413 | CLANG_CXX_LIBRARY = "libc++";
414 | CLANG_ENABLE_MODULES = YES;
415 | CLANG_ENABLE_OBJC_ARC = YES;
416 | CLANG_ENABLE_OBJC_WEAK = YES;
417 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
418 | CLANG_WARN_BOOL_CONVERSION = YES;
419 | CLANG_WARN_COMMA = YES;
420 | CLANG_WARN_CONSTANT_CONVERSION = YES;
421 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
422 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
423 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
424 | CLANG_WARN_EMPTY_BODY = YES;
425 | CLANG_WARN_ENUM_CONVERSION = YES;
426 | CLANG_WARN_INFINITE_RECURSION = YES;
427 | CLANG_WARN_INT_CONVERSION = YES;
428 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
429 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
430 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
431 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
432 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
433 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
434 | CLANG_WARN_STRICT_PROTOTYPES = YES;
435 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
436 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
437 | CLANG_WARN_UNREACHABLE_CODE = YES;
438 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
439 | CODE_SIGN_IDENTITY = "iPhone Developer";
440 | COPY_PHASE_STRIP = NO;
441 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
442 | ENABLE_NS_ASSERTIONS = NO;
443 | ENABLE_STRICT_OBJC_MSGSEND = YES;
444 | GCC_C_LANGUAGE_STANDARD = gnu11;
445 | GCC_NO_COMMON_BLOCKS = YES;
446 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
447 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
448 | GCC_WARN_UNDECLARED_SELECTOR = YES;
449 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
450 | GCC_WARN_UNUSED_FUNCTION = YES;
451 | GCC_WARN_UNUSED_VARIABLE = YES;
452 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
453 | MTL_ENABLE_DEBUG_INFO = NO;
454 | MTL_FAST_MATH = YES;
455 | SDKROOT = iphoneos;
456 | SWIFT_COMPILATION_MODE = wholemodule;
457 | SWIFT_OPTIMIZATION_LEVEL = "-O";
458 | VALIDATE_PRODUCT = YES;
459 | };
460 | name = Release;
461 | };
462 | 464264FE217E3FCF0001C4AF /* Debug */ = {
463 | isa = XCBuildConfiguration;
464 | buildSettings = {
465 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
466 | CODE_SIGN_STYLE = Automatic;
467 | INFOPLIST_FILE = Tinderbar/Info.plist;
468 | LD_RUNPATH_SEARCH_PATHS = (
469 | "$(inherited)",
470 | "@executable_path/Frameworks",
471 | );
472 | PRODUCT_BUNDLE_IDENTIFIER = com.uias.Tinderbar;
473 | PRODUCT_NAME = "$(TARGET_NAME)";
474 | SWIFT_VERSION = 5.0;
475 | TARGETED_DEVICE_FAMILY = 1;
476 | };
477 | name = Debug;
478 | };
479 | 464264FF217E3FCF0001C4AF /* Release */ = {
480 | isa = XCBuildConfiguration;
481 | buildSettings = {
482 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
483 | CODE_SIGN_STYLE = Automatic;
484 | INFOPLIST_FILE = Tinderbar/Info.plist;
485 | LD_RUNPATH_SEARCH_PATHS = (
486 | "$(inherited)",
487 | "@executable_path/Frameworks",
488 | );
489 | PRODUCT_BUNDLE_IDENTIFIER = com.uias.Tinderbar;
490 | PRODUCT_NAME = "$(TARGET_NAME)";
491 | SWIFT_VERSION = 5.0;
492 | TARGETED_DEVICE_FAMILY = 1;
493 | };
494 | name = Release;
495 | };
496 | /* End XCBuildConfiguration section */
497 |
498 | /* Begin XCConfigurationList section */
499 | 464264E6217E3FCD0001C4AF /* Build configuration list for PBXProject "Tinderbar" */ = {
500 | isa = XCConfigurationList;
501 | buildConfigurations = (
502 | 464264FB217E3FCF0001C4AF /* Debug */,
503 | 464264FC217E3FCF0001C4AF /* Release */,
504 | );
505 | defaultConfigurationIsVisible = 0;
506 | defaultConfigurationName = Release;
507 | };
508 | 464264FD217E3FCF0001C4AF /* Build configuration list for PBXNativeTarget "Tinderbar" */ = {
509 | isa = XCConfigurationList;
510 | buildConfigurations = (
511 | 464264FE217E3FCF0001C4AF /* Debug */,
512 | 464264FF217E3FCF0001C4AF /* Release */,
513 | );
514 | defaultConfigurationIsVisible = 0;
515 | defaultConfigurationName = Release;
516 | };
517 | /* End XCConfigurationList section */
518 |
519 | /* Begin XCRemoteSwiftPackageReference section */
520 | 46F12DF623292C3B000EC76A /* XCRemoteSwiftPackageReference "Tabman" */ = {
521 | isa = XCRemoteSwiftPackageReference;
522 | repositoryURL = "https://github.com/uias/Tabman";
523 | requirement = {
524 | kind = upToNextMajorVersion;
525 | minimumVersion = 3.0.2;
526 | };
527 | };
528 | /* End XCRemoteSwiftPackageReference section */
529 |
530 | /* Begin XCSwiftPackageProductDependency section */
531 | 46F12DF723292C3B000EC76A /* Tabman */ = {
532 | isa = XCSwiftPackageProductDependency;
533 | package = 46F12DF623292C3B000EC76A /* XCRemoteSwiftPackageReference "Tabman" */;
534 | productName = Tabman;
535 | };
536 | /* End XCSwiftPackageProductDependency section */
537 | };
538 | rootObject = 464264E3217E3FCD0001C4AF /* Project object */;
539 | }
540 |
--------------------------------------------------------------------------------
/Sources/Tinderbar.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Sources/Tinderbar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "app_icon-2.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "60x60",
41 | "idiom" : "iphone",
42 | "filename" : "app_icon-1.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "1024x1024",
47 | "idiom" : "ios-marketing",
48 | "filename" : "app_icon.png",
49 | "scale" : "1x"
50 | }
51 | ],
52 | "info" : {
53 | "version" : 1,
54 | "author" : "xcode"
55 | }
56 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon-1.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon-2.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/AppIcon.appiconset/app_icon.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_launch_logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "ic_launch_logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "ic_launch_logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo@2x.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_launch_logo.imageset/ic_launch_logo@3x.png
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_matches.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_tinder.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | },
12 | "properties" : {
13 | "template-rendering-intent" : "template",
14 | "preserves-vector-representation" : true
15 | }
16 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_matches.imageset/ic_tinder.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_matches.imageset/ic_tinder.pdf
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_messages.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_messages.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | },
12 | "properties" : {
13 | "template-rendering-intent" : "template",
14 | "preserves-vector-representation" : true
15 | }
16 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_messages.imageset/ic_messages.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_messages.imageset/ic_messages.pdf
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "ic_profile.pdf"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | },
12 | "properties" : {
13 | "template-rendering-intent" : "template",
14 | "preserves-vector-representation" : true
15 | }
16 | }
--------------------------------------------------------------------------------
/Sources/Tinderbar/Assets.xcassets/ic_profile.imageset/ic_profile.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Sources/Tinderbar/Assets.xcassets/ic_profile.imageset/ic_profile.pdf
--------------------------------------------------------------------------------
/Sources/Tinderbar/Bars/MessagesBar/MessagesBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesBar.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 |
12 | class MessagesBar {
13 |
14 | typealias BarType = TMBarView
15 |
16 | static func make() -> BarType {
17 | let bar = BarType()
18 |
19 | bar.layout.contentMode = .fit
20 | bar.buttons.customize { (button) in
21 | button.selectedTintColor = TinderColors.primaryTint
22 | button.tintColor = TinderColors.unselectedGray
23 | button.font = UIFont.systemFont(ofSize: 19, weight: .semibold)
24 | }
25 |
26 | bar.backgroundView.style = .flat(color: .white)
27 |
28 | return bar
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Bars/TinderBar/TinderBar.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinderBar.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import Tabman
10 |
11 | class TinderBar {
12 |
13 | typealias BarType = TMBarView
14 |
15 | static func make() -> TMBar {
16 | let bar = BarType()
17 |
18 | bar.scrollMode = .swipe
19 |
20 | bar.buttons.customize { (button) in
21 | button.tintColor = TinderColors.primaryTint
22 | button.unselectedTintColor = TinderColors.unselectedGray
23 | }
24 |
25 | // Wrap in a 'navigation bar'.
26 | let navigationBar = bar.systemBar()
27 | navigationBar.backgroundStyle = .flat(color: .white)
28 | return navigationBar
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Bars/TinderBar/TinderBarButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinderBarButton.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 |
12 | class TinderBarButton: TMBarButton {
13 |
14 | // MARK: Defaults
15 |
16 | private struct Defaults {
17 | static let imageSize = CGSize(width: 36, height: 36)
18 | static let unselectedScale: CGFloat = 0.8
19 | }
20 |
21 | // MARK: Properties
22 |
23 | private let imageView = UIImageView()
24 |
25 | override var tintColor: UIColor! {
26 | didSet {
27 | update(for: self.selectionState)
28 | }
29 | }
30 | var unselectedTintColor: UIColor = .lightGray {
31 | didSet {
32 | update(for: self.selectionState)
33 | }
34 | }
35 |
36 | // MARK: Lifecycle
37 |
38 | override func layout(in view: UIView) {
39 | super.layout(in: view)
40 |
41 | adjustsAlphaOnSelection = false
42 |
43 | view.addSubview(imageView)
44 | imageView.translatesAutoresizingMaskIntoConstraints = false
45 | NSLayoutConstraint.activate([
46 | imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
47 | imageView.topAnchor.constraint(equalTo: view.topAnchor),
48 | imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
49 | imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
50 | imageView.widthAnchor.constraint(equalToConstant: Defaults.imageSize.width),
51 | imageView.heightAnchor.constraint(equalToConstant: Defaults.imageSize.height)
52 | ])
53 | }
54 |
55 | override func populate(for item: TMBarItemable) {
56 | super.populate(for: item)
57 |
58 | imageView.image = item.image
59 | }
60 |
61 | override func update(for selectionState: TMBarButton.SelectionState) {
62 | super.update(for: selectionState)
63 |
64 | imageView.tintColor = unselectedTintColor.interpolate(with: tintColor,
65 | percent: selectionState.rawValue)
66 |
67 | let scale = 1.0 - ((1.0 - selectionState.rawValue) * (1.0 - Defaults.unselectedScale))
68 | imageView.transform = CGAffineTransform(scaleX: scale, y: scale)
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Bars/TinderBar/TinderBarButtonContainer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinderBarButtonContainer.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 |
12 | class TinderBarButtonContainer: UIView {
13 |
14 | // MARK: Properties
15 |
16 | internal let button: TMBarButton
17 |
18 | private var xAnchor: NSLayoutConstraint!
19 |
20 | var offsetDelta: CGFloat = 0.0 {
21 | didSet {
22 | xAnchor.constant = offsetDelta * (button.frame.size.width)
23 | }
24 | }
25 |
26 | // MARK: Init
27 |
28 | init(for button: TMBarButton) {
29 | self.button = button
30 | super.init(frame: .zero)
31 | initialize(with: button)
32 | }
33 |
34 | required init?(coder aDecoder: NSCoder) {
35 | fatalError("Not Supported")
36 | }
37 |
38 | private func initialize(with button: TMBarButton) {
39 |
40 | xAnchor = button.centerXAnchor.constraint(equalTo: centerXAnchor)
41 |
42 | addSubview(button)
43 | button.translatesAutoresizingMaskIntoConstraints = false
44 | NSLayoutConstraint.activate([
45 | xAnchor,
46 | button.centerYAnchor.constraint(equalTo: centerYAnchor),
47 | button.topAnchor.constraint(equalTo: topAnchor),
48 | button.bottomAnchor.constraint(equalTo: bottomAnchor),
49 | button.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
50 | trailingAnchor.constraint(greaterThanOrEqualTo: button.trailingAnchor)
51 | ])
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Bars/TinderBar/TinderBarLayout.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinderBarLayout.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 |
12 | class TinderBarLayout: TMBarLayout {
13 |
14 | // MARK: Defaults
15 |
16 | private struct Defaults {
17 | static let contentInset = UIEdgeInsets(top: 4, left: 0, bottom: 10, right: 0)
18 | }
19 |
20 | // MARK: Properties
21 |
22 | private let stackView = UIStackView()
23 | private var containers = [TinderBarButtonContainer]()
24 |
25 | // MARK: Lifecycle
26 |
27 | override func layout(in view: UIView) {
28 |
29 | let paddedStackView = UIStackView()
30 | view.addSubview(paddedStackView)
31 | paddedStackView.translatesAutoresizingMaskIntoConstraints = false
32 | NSLayoutConstraint.activate([
33 | paddedStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
34 | paddedStackView.topAnchor.constraint(equalTo: view.topAnchor),
35 | paddedStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
36 | paddedStackView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
37 | ])
38 |
39 | // Add two padding views to the leading/trailing edge of the main content stack view.
40 | // These views are 0.25 times the width of the content layout guide (1/4 of the view width).
41 | addPaddingView(multiplier: 0.25, to: paddedStackView)
42 | paddedStackView.addArrangedSubview(stackView)
43 | addPaddingView(multiplier: 0.25, to: paddedStackView)
44 |
45 | // Apply a default content inset.
46 | contentInset = Defaults.contentInset
47 | }
48 |
49 | override func insert(buttons: [TMBarButton], at index: Int) {
50 | buttons.forEach { (button) in
51 | let container = TinderBarButtonContainer(for: button)
52 | stackView.addArrangedSubview(container)
53 | containers.append(container)
54 |
55 | // Make button containers 1/2 the width of the layout guide (view width).
56 | container.widthAnchor.constraint(equalTo: layoutGuide.widthAnchor, multiplier: 0.5).isActive = true
57 | }
58 | }
59 |
60 | override func remove(buttons: [TMBarButton]) {
61 | let containers = stackView.arrangedSubviews.compactMap({ $0 as? TinderBarButtonContainer })
62 | let containersToRemove = containers.filter({ buttons.contains($0.button) })
63 | containersToRemove.forEach { (container) in
64 | stackView.removeArrangedSubview(container)
65 | container.removeFromSuperview()
66 | }
67 | }
68 |
69 | override func focusArea(for position: CGFloat, capacity: Int) -> CGRect {
70 | let range = buttonIndexRange(from: position, minimum: 0, maximum: capacity - 1)
71 | guard stackView.arrangedSubviews.count > range.upperBound else {
72 | return .zero
73 | }
74 |
75 | let lowerView = stackView.arrangedSubviews[range.lowerBound]
76 | let upperView = stackView.arrangedSubviews[range.upperBound]
77 |
78 | let lowerViewFrame = view.convert(lowerView.frame, from: stackView)
79 | let upperViewFrame = view.convert(upperView.frame, from: stackView)
80 |
81 | // Create an interpolated rect between the view that is detected as 'lower' (leading)
82 | // and the view that is 'upper' (trailing) for the current position.
83 | let interpolation = interpolatedRect(between: lowerViewFrame,
84 | and: upperViewFrame,
85 | position: position)
86 |
87 | // Update the offsets in the container.
88 | // This adjusts the 'center x' constraint of the button in the container, so that it is offsetted
89 | // correctly. Results in -1.0 when offsetted to the left, 0.0 when focussed and 1.0 when offsetted to the right.
90 | // This is then interpreted for the button width and increments/decrements the constraint constant appropriately.
91 | updateContainerOffsets(for: max(0.0, min(CGFloat(capacity) - 1.0, position)))
92 |
93 | return CGRect(x: lowerViewFrame.origin.x + interpolation.origin.x,
94 | y: 0.0,
95 | width: lowerViewFrame.size.width + interpolation.size.width,
96 | height: view.bounds.size.height)
97 | }
98 |
99 | private func updateContainerOffsets(for position: CGFloat) {
100 | for (index, container) in containers.enumerated() {
101 | let index = CGFloat(index)
102 | let positionDelta = max(-1.0, min(1.0, position - index))
103 | container.offsetDelta = positionDelta
104 | }
105 | }
106 |
107 | // MARK: Utility
108 |
109 | @discardableResult
110 | private func addPaddingView(multiplier: CGFloat, to stack: UIStackView) -> UIView {
111 | let view = UIView()
112 | view.isUserInteractionEnabled = false
113 | stack.addArrangedSubview(view)
114 | view.translatesAutoresizingMaskIntoConstraints = false
115 | view.widthAnchor.constraint(equalTo: layoutGuide.widthAnchor, multiplier: multiplier).isActive = true
116 | return view
117 | }
118 |
119 | // MARK: Maths
120 |
121 | private func buttonIndexRange(from position: CGFloat, minimum: Int, maximum: Int) -> Range {
122 | guard maximum > minimum else {
123 | return 0 ..< 0
124 | }
125 | let lower = floor(position)
126 | let upper = ceil(position)
127 | let minimum = CGFloat(minimum)
128 | let maximum = CGFloat(maximum)
129 |
130 | return Int(max(minimum, min(maximum, lower))) ..< Int(min(maximum, max(minimum, upper)))
131 | }
132 |
133 | private func interpolatedRect(between frame: CGRect, and other: CGRect, position: CGFloat) -> CGRect {
134 | var integral: Float = 0.0
135 | let progress = CGFloat(modff(Float(position), &integral))
136 |
137 | return CGRect(x: (other.origin.x - frame.origin.x) * progress,
138 | y: (other.origin.y - frame.origin.y) * progress,
139 | width: (other.size.width - frame.size.width) * progress,
140 | height: (other.size.height - frame.size.height) * progress)
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Base.lproj/Root.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/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 | UIMainStoryboardFile
26 | Root
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIUserInterfaceStyle
43 | Light
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/RootTabViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // RootTabViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 | import Pageboy
12 |
13 | class RootTabViewController: TabmanViewController, PageboyViewControllerDataSource, TMBarDataSource {
14 |
15 | enum Tab: String, CaseIterable {
16 | case profile
17 | case matches
18 | case messages
19 | }
20 |
21 | private let tabItems = Tab.allCases.map({ BarItem(for: $0) })
22 | private lazy var viewControllers = tabItems.compactMap({ $0.makeViewController() })
23 |
24 | // MARK: Lifecycle
25 |
26 | override func viewDidLoad() {
27 | super.viewDidLoad()
28 |
29 | dataSource = self
30 | isScrollEnabled = false
31 |
32 | addBar(TinderBar.make(), dataSource: self, at: .top)
33 | }
34 |
35 | // MARK: PageboyViewControllerDataSource
36 |
37 | func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
38 | return viewControllers.count
39 | }
40 |
41 | func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? {
42 | return viewControllers[index]
43 | }
44 |
45 | func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
46 | return .at(index: 1)
47 | }
48 |
49 | // MARK: TMBarDataSource
50 |
51 | func barItem(for bar: TMBar, at index: Int) -> TMBarItemable {
52 | return tabItems[index]
53 | }
54 | }
55 |
56 | private class BarItem: TMBarItemable {
57 |
58 | let tab: RootTabViewController.Tab
59 |
60 | init(for tab: RootTabViewController.Tab) {
61 | self.tab = tab
62 | }
63 |
64 | private var _title: String? {
65 | return tab.rawValue.capitalized
66 | }
67 | var title: String? {
68 | get {
69 | return _title
70 | } set {}
71 | }
72 |
73 | private var _image: UIImage? {
74 | return UIImage(named: "ic_\(tab.rawValue)")
75 | }
76 | var image: UIImage? {
77 | get {
78 | return _image
79 | } set {}
80 | }
81 | var selectedImage: UIImage?
82 | var badgeValue: String?
83 |
84 | func makeViewController() -> UIViewController? {
85 | let storyboardName: String
86 | switch tab {
87 | case .profile:
88 | storyboardName = "Profile"
89 | case .matches:
90 | storyboardName = "Matches"
91 | case .messages:
92 | storyboardName = "Messages"
93 | }
94 |
95 | return UIStoryboard(name: storyboardName, bundle: nil).instantiateInitialViewController()
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/TinderColors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TinderColors.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | struct TinderColors {
12 |
13 | static var primaryTint: UIColor {
14 | return UIColor(red:0.99, green:0.31, blue:0.41, alpha:1.0)
15 | }
16 |
17 | static var unselectedGray: UIColor {
18 | return UIColor(red:0.85, green:0.87, blue:0.90, alpha:1.0)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/Utilities/UIColor+Interpolation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Interpolation.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIColor {
12 |
13 | func interpolate(with other: UIColor, percent: CGFloat) -> UIColor? {
14 | return UIColor.interpolate(betweenColor: self, and: other, percent: percent)
15 | }
16 |
17 | static func interpolate(betweenColor colorA: UIColor,
18 | and colorB: UIColor,
19 | percent: CGFloat) -> UIColor? {
20 | var redA: CGFloat = 0.0
21 | var greenA: CGFloat = 0.0
22 | var blueA: CGFloat = 0.0
23 | var alphaA: CGFloat = 0.0
24 | guard colorA.getRed(&redA, green: &greenA, blue: &blueA, alpha: &alphaA) else {
25 | return nil
26 | }
27 |
28 | var redB: CGFloat = 0.0
29 | var greenB: CGFloat = 0.0
30 | var blueB: CGFloat = 0.0
31 | var alphaB: CGFloat = 0.0
32 | guard colorB.getRed(&redB, green: &greenB, blue: &blueB, alpha: &alphaB) else {
33 | return nil
34 | }
35 |
36 | let iRed = CGFloat(redA + percent * (redB - redA))
37 | let iBlue = CGFloat(blueA + percent * (blueB - blueA))
38 | let iGreen = CGFloat(greenA + percent * (greenB - greenA))
39 | let iAlpha = CGFloat(alphaA + percent * (alphaB - alphaA))
40 |
41 | return UIColor(red: iRed, green: iGreen, blue: iBlue, alpha: iAlpha)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Matches/Matches.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Matches/MatchesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MatchesViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MatchesViewController: UIViewController {
12 |
13 | @IBOutlet private weak var cardView: UIView!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 |
18 | cardView.backgroundColor = TinderColors.unselectedGray
19 | cardView.layer.cornerRadius = 16.0
20 | }
21 | }
22 |
23 | @IBDesignable class MatchesActionButton: UIButton {
24 |
25 | override func awakeFromNib() {
26 | super.awakeFromNib()
27 |
28 | backgroundColor = TinderColors.unselectedGray
29 | }
30 |
31 | override func layoutSubviews() {
32 | super.layoutSubviews()
33 |
34 | layer.cornerRadius = bounds.size.width / 2.0
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/Messages.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/MessagesFeedViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesFeedViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessagesFeedViewController: UITableViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | tableView.contentInset = UIEdgeInsets(top: 16.0, left: 0.0, bottom: 0.0, right: 0.0)
17 |
18 | tableView.register(UINib(nibName: "MessagesFeedCell", bundle: nil),
19 | forCellReuseIdentifier: MessagesFeedCell.reuseIdentifier)
20 | }
21 |
22 | override func numberOfSections(in tableView: UITableView) -> Int {
23 | return 1
24 | }
25 |
26 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
27 | return 10
28 | }
29 |
30 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
31 | let cell = tableView.dequeueReusableCell(withIdentifier: MessagesFeedCell.reuseIdentifier, for: indexPath)
32 | cell.selectionStyle = .none
33 | return cell
34 | }
35 |
36 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
37 | return tableView.bounds.size.width * 1.2
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/MessagesTabViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesTabViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 24/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import Tabman
11 | import Pageboy
12 |
13 | class MessagesTabViewController: TabmanViewController, PageboyViewControllerDataSource, TMBarDataSource {
14 |
15 | enum Tab: String, CaseIterable {
16 | case messages
17 | case feed
18 | }
19 |
20 | private let tabItems = Tab.allCases.map({ BarItem(for: $0) })
21 | private lazy var viewControllers = tabItems.compactMap({ $0.makeViewController() })
22 |
23 | let bar = MessagesBar.make()
24 |
25 | // MARK: Lifecycle
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 |
30 | self.dataSource = self
31 |
32 | addBar(bar, dataSource: self, at: .top)
33 | }
34 |
35 | override func viewDidLayoutSubviews() {
36 | super.viewDidLayoutSubviews()
37 |
38 | bar.layer.masksToBounds = false
39 | bar.layer.shadowColor = UIColor.black.cgColor
40 | bar.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
41 | bar.layer.shadowOpacity = 0.1
42 | bar.layer.shadowPath = UIBezierPath(rect: bar.bounds).cgPath
43 | }
44 |
45 | // MARK: PageboyViewControllerDataSource
46 |
47 | func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
48 | return viewControllers.count
49 | }
50 |
51 | func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? {
52 | return viewControllers[index]
53 | }
54 |
55 | func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
56 | return nil
57 | }
58 |
59 | // MARK: TMBarDataSource
60 |
61 | func barItem(for bar: TMBar, at index: Int) -> TMBarItemable {
62 | return tabItems[index]
63 | }
64 | }
65 |
66 | private class BarItem: TMBarItemable {
67 |
68 | let tab: MessagesTabViewController.Tab
69 |
70 | init(for tab: MessagesTabViewController.Tab) {
71 | self.tab = tab
72 | }
73 |
74 | private var _title: String {
75 | return tab.rawValue.capitalized
76 | }
77 | var title: String? {
78 | get {
79 | return _title
80 | } set {}
81 | }
82 | var image: UIImage?
83 | var selectedImage: UIImage?
84 | var badgeValue: String?
85 |
86 | func makeViewController() -> UIViewController? {
87 | let storyboard = UIStoryboard(name: "Messages", bundle: nil)
88 | let viewControllerId: String
89 | switch tab {
90 | case .messages:
91 | viewControllerId = "MessagesViewController"
92 | case .feed:
93 | viewControllerId = "MessagesFeedViewController"
94 | }
95 |
96 | return storyboard.instantiateViewController(withIdentifier: viewControllerId)
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/MessagesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessagesViewController: UITableViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | tableView.register(UINib(nibName: "MessagesMessageCell", bundle: nil),
17 | forCellReuseIdentifier: MessagesMessageCell.reuseIdentifier)
18 | }
19 |
20 | override func numberOfSections(in tableView: UITableView) -> Int {
21 | return 1
22 | }
23 |
24 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
25 | return 10
26 | }
27 |
28 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
29 | let cell = tableView.dequeueReusableCell(withIdentifier: MessagesMessageCell.reuseIdentifier, for: indexPath)
30 | cell.selectionStyle = .none
31 | return cell
32 | }
33 |
34 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
35 | return 96.0
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/Views/MessagesFeedCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesFeedCell.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 28/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessagesFeedCell: UITableViewCell {
12 |
13 | static let reuseIdentifier = "MessagesFeedCell"
14 |
15 | @IBOutlet private weak var avatarView: UIView!
16 | @IBOutlet private weak var contentImageView: UIView!
17 | @IBOutlet private weak var nameLabel: UILabel!
18 | @IBOutlet private weak var actionLabel: UILabel!
19 | @IBOutlet private weak var dateLabel: UILabel!
20 |
21 | override func awakeFromNib() {
22 | super.awakeFromNib()
23 |
24 | contentImageView.backgroundColor = TinderColors.unselectedGray
25 | avatarView.backgroundColor = TinderColors.unselectedGray
26 | actionLabel.textColor = .lightGray
27 | dateLabel.textColor = .lightGray
28 | }
29 |
30 | override func layoutSubviews() {
31 | super.layoutSubviews()
32 |
33 | avatarView.layer.cornerRadius = avatarView.bounds.size.width / 2
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/Views/MessagesFeedCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
40 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/Views/MessagesMessageCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MessagesMessageCell.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 28/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class MessagesMessageCell: UITableViewCell {
12 |
13 | static let reuseIdentifier = "MessagesMessageCell"
14 |
15 | @IBOutlet private weak var avatarView: UIView!
16 | @IBOutlet private weak var titleLabel: UILabel!
17 | @IBOutlet private weak var messageLabel: UILabel!
18 |
19 | override func awakeFromNib() {
20 | super.awakeFromNib()
21 |
22 | avatarView.backgroundColor = TinderColors.unselectedGray
23 | messageLabel.textColor = .lightGray
24 | }
25 |
26 | override func layoutSubviews() {
27 | super.layoutSubviews()
28 |
29 | avatarView.layer.cornerRadius = avatarView.bounds.size.width / 2
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Messages/Views/MessagesMessageCell.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Profile/Profile.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
42 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
--------------------------------------------------------------------------------
/Sources/Tinderbar/ViewControllers/Profile/ProfileViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ProfileViewController.swift
3 | // Tinderbar
4 | //
5 | // Created by Merrick Sapsford on 22/10/2018.
6 | // Copyright © 2018 UI At Six. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ProfileViewController: UIViewController {
12 |
13 | @IBOutlet private weak var contentView: UIView!
14 | private let contentViewMaskLayer = CAShapeLayer()
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 |
19 | contentView.layer.mask = contentViewMaskLayer
20 | }
21 |
22 | override func viewDidLayoutSubviews() {
23 | super.viewDidLayoutSubviews()
24 |
25 | contentViewMaskLayer.frame = contentView.bounds
26 | contentViewMaskLayer.path = contentViewMaskPath(in: contentView.bounds).cgPath
27 | }
28 | }
29 |
30 | private extension ProfileViewController {
31 |
32 | private func contentViewMaskPath(in frame: CGRect) -> UIBezierPath {
33 |
34 | let curveOffset = frame.size.height / 6
35 |
36 | let path = UIBezierPath()
37 | path.move(to: .zero)
38 | path.addLine(to: CGPoint(x: frame.maxX, y: frame.minY))
39 | path.addLine(to: CGPoint(x: frame.maxX, y: frame.maxY - curveOffset))
40 | path.addQuadCurve(to: CGPoint(x: frame.minX, y: frame.maxY - curveOffset),
41 | controlPoint: CGPoint(x: frame.maxX / 2, y: frame.maxY))
42 | path.close()
43 | return path
44 | }
45 | }
46 |
47 | @IBDesignable class ProfileActionButton: UIButton {
48 |
49 | override func awakeFromNib() {
50 | super.awakeFromNib()
51 |
52 | backgroundColor = TinderColors.unselectedGray
53 | }
54 |
55 | override func layoutSubviews() {
56 | super.layoutSubviews()
57 |
58 | layer.cornerRadius = bounds.size.width / 2.0
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Tinderbar.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uias/Tinderbar/a10dc9e8a7f456846bd882978ccefb232ffd6959/Tinderbar.sketch
--------------------------------------------------------------------------------
/Tinderbar.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Tinderbar.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Tinderbar.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "pageboy",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/uias/Pageboy",
7 | "state" : {
8 | "revision" : "5522aa6ae88633f6c23cf504e9cd684e963822f1",
9 | "version" : "4.0.2"
10 | }
11 | },
12 | {
13 | "identity" : "tabman",
14 | "kind" : "remoteSourceControl",
15 | "location" : "https://github.com/uias/Tabman",
16 | "state" : {
17 | "revision" : "e32c0d821b03566ed966753f941113883f268da0",
18 | "version" : "3.0.2"
19 | }
20 | }
21 | ],
22 | "version" : 2
23 | }
24 |
--------------------------------------------------------------------------------