├── README.md ├── Sport Kit Interface.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── Roman.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist └── Sport Kit Interface ├── Application ├── AppDelegate.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist └── SceneDelegate.swift ├── Base.lproj └── Main.storyboard ├── Base └── Views │ ├── BarsViews │ ├── BaseBarView.swift │ └── BaseBarsView.swift │ ├── BaseButton.swift │ ├── BaseController.swift │ ├── BaseInfoView.swift │ ├── BaseView.swift │ └── ChartsViews │ ├── BaseChartsView.swift │ └── Views │ ├── ChartView.swift │ ├── XAxisView.swift │ └── YAxisView.swift ├── Controllers ├── Overview │ ├── OverviewController.swift │ └── Views │ │ ├── CollectionView │ │ └── Views │ │ │ └── SectionHeaderView.swift │ │ ├── OverviewNavBar.swift │ │ ├── TrainingCellView.swift │ │ └── WeekView │ │ ├── WeekDayView.swift │ │ └── WeekView.swift ├── Progress │ ├── ProgressController.swift │ └── Views │ │ ├── MonthlyPerformanceView │ │ └── MonthlyPerformanceView.swift │ │ └── Performance │ │ └── DailyPerformanceView.swift ├── Session │ ├── SessionController.swift │ └── Views │ │ ├── Stats │ │ ├── StatsView.swift │ │ └── Views │ │ │ └── StatsItemView.swift │ │ ├── Steps │ │ └── StepsView.swift │ │ └── Timer │ │ ├── PercentView.swift │ │ ├── ProgressView.swift │ │ └── TimerView.swift └── Settings │ └── SettingsController.swift ├── Extentions ├── Date.swift ├── UIColor.swift └── UIView.swift ├── Navigation ├── NavBarController.swift └── TabBarController.swift └── Resources ├── Assets.xcassets ├── AccentColor.colorset │ └── Contents.json ├── AppIcon.appiconset │ └── Contents.json ├── Common │ ├── Contents.json │ ├── add_icon.imageset │ │ ├── Add-2.pdf │ │ └── Contents.json │ └── all_workouts.imageset │ │ ├── Contents.json │ │ └── Path.pdf ├── Contents.json ├── Overview │ ├── Contents.json │ ├── checkmark_done.imageset │ │ ├── Checked.pdf │ │ └── Contents.json │ ├── checkmark_not_done.imageset │ │ ├── Contents.json │ │ └── Oval.pdf │ └── right_arrow.imageset │ │ ├── Contents.json │ │ └── Right Arrow.pdf ├── Stats │ ├── Contents.json │ ├── stats_averagePace.imageset │ │ ├── Contents.json │ │ └── Speed Icon.pdf │ ├── stats_heartRate.imageset │ │ ├── Contents.json │ │ └── Heart Beat Icon.pdf │ ├── stats_totalDistance.imageset │ │ ├── Contents.json │ │ └── Maps Icon.pdf │ └── stats_totalSteps.imageset │ │ ├── Contents.json │ │ └── Steps Icon.pdf └── TabBar │ ├── Contents.json │ ├── overview_tab.imageset │ ├── Contents.json │ └── House Icon.pdf │ ├── progress_tab.imageset │ ├── Analytics Bars.pdf │ └── Contents.json │ ├── session_tab.imageset │ ├── Clock Icon.pdf │ └── Contents.json │ └── settings_tab.imageset │ ├── Contents.json │ └── Gear Icon.pdf └── Resources.swift /README.md: -------------------------------------------------------------------------------- 1 | # UIKit-Interface-App! 2 | 3 | ![workout-tracking-app-johnny-jakubowicz](https://user-images.githubusercontent.com/82379236/180014441-af406889-3b2c-47fd-93cd-f02386f8f8e6.png) 4 | -------------------------------------------------------------------------------- /Sport Kit Interface.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 3002958C29B0DB0C00DCD984 /* SectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3002958B29B0DB0C00DCD984 /* SectionHeaderView.swift */; }; 11 | 3002958E29C7653900DCD984 /* TrainingCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3002958D29C7653800DCD984 /* TrainingCellView.swift */; }; 12 | 30031EF92949EAB70061796E /* MonthlyPerformanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30031EF82949EAB70061796E /* MonthlyPerformanceView.swift */; }; 13 | 30031EFC294CF3320061796E /* BaseChartsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30031EFB294CF3320061796E /* BaseChartsView.swift */; }; 14 | 30031EFE294D07A90061796E /* XAxisView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30031EFD294D07A90061796E /* XAxisView.swift */; }; 15 | 30031F00294D13570061796E /* YAxisView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30031EFF294D13570061796E /* YAxisView.swift */; }; 16 | 30031F03295616D70061796E /* ChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30031F02295616D70061796E /* ChartView.swift */; }; 17 | 301274FD2885A72C00AF2521 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 301274FC2885A72C00AF2521 /* Assets.xcassets */; }; 18 | 301274FF2888106900AF2521 /* WeekView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301274FE2888106900AF2521 /* WeekView.swift */; }; 19 | 3021B64C292B9B5F00B54DC5 /* BaseBarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3021B64B292B9B5F00B54DC5 /* BaseBarsView.swift */; }; 20 | 3021B64F292BA1E000B54DC5 /* BaseBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3021B64E292BA1E000B54DC5 /* BaseBarView.swift */; }; 21 | 304B926E2883F2C4003A542D /* BaseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304B926D2883F2C4003A542D /* BaseButton.swift */; }; 22 | 304B92702885762D003A542D /* OverviewNavBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304B926F2885762D003A542D /* OverviewNavBar.swift */; }; 23 | 304B927228857673003A542D /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304B927128857673003A542D /* BaseView.swift */; }; 24 | 304D43F2294603D6002C91DE /* DailyPerformanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304D43F1294603D6002C91DE /* DailyPerformanceView.swift */; }; 25 | 305B4C37287B4A1B00B6A6F1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C36287B4A1B00B6A6F1 /* AppDelegate.swift */; }; 26 | 305B4C39287B4A1B00B6A6F1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C38287B4A1B00B6A6F1 /* SceneDelegate.swift */; }; 27 | 305B4C3B287B4A1B00B6A6F1 /* OverviewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C3A287B4A1B00B6A6F1 /* OverviewController.swift */; }; 28 | 305B4C43287B4A1E00B6A6F1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 305B4C41287B4A1E00B6A6F1 /* LaunchScreen.storyboard */; }; 29 | 305B4C51287C2BB700B6A6F1 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C50287C2BB700B6A6F1 /* TabBarController.swift */; }; 30 | 305B4C54287C2E6900B6A6F1 /* UIColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C53287C2E6900B6A6F1 /* UIColor.swift */; }; 31 | 305B4C56287C2FC200B6A6F1 /* Resources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 305B4C55287C2FC200B6A6F1 /* Resources.swift */; }; 32 | 307C93572882A3430066DAF1 /* BaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C93562882A3430066DAF1 /* BaseController.swift */; }; 33 | 307C93592882AFD50066DAF1 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C93582882AFD50066DAF1 /* UIView.swift */; }; 34 | 307C93602882BCE00066DAF1 /* SessionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C935F2882BCE00066DAF1 /* SessionController.swift */; }; 35 | 307C93622882BD030066DAF1 /* ProgressController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C93612882BD030066DAF1 /* ProgressController.swift */; }; 36 | 307C93642882BD110066DAF1 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307C93632882BD110066DAF1 /* SettingsController.swift */; }; 37 | 308928FF2891510600EBDCE8 /* TimerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308928FE2891510600EBDCE8 /* TimerView.swift */; }; 38 | 308929012891B8D100EBDCE8 /* ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308929002891B8D100EBDCE8 /* ProgressView.swift */; }; 39 | 30A53BEE290F10B000714A1A /* StatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A53BED290F10B000714A1A /* StatsView.swift */; }; 40 | 30A53BF0290F10BF00714A1A /* StepsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A53BEF290F10BF00714A1A /* StepsView.swift */; }; 41 | 30A53BF3290F134300714A1A /* StatsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A53BF2290F134300714A1A /* StatsItemView.swift */; }; 42 | 30B956F228881948002A4088 /* WeekDayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B956F128881948002A4088 /* WeekDayView.swift */; }; 43 | 30BF946E28829739006F2C47 /* NavBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30BF946D28829739006F2C47 /* NavBarController.swift */; }; 44 | 30D8A990288858ED0061D22C /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D8A98F288858ED0061D22C /* Date.swift */; }; 45 | 30D8A9942889C5BD0061D22C /* BaseInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D8A9932889C5BD0061D22C /* BaseInfoView.swift */; }; 46 | 30E8008F28D85A8E00E7343E /* PercentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E8008E28D85A8E00E7343E /* PercentView.swift */; }; 47 | /* End PBXBuildFile section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 3002958B29B0DB0C00DCD984 /* SectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeaderView.swift; sourceTree = ""; }; 51 | 3002958D29C7653800DCD984 /* TrainingCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrainingCellView.swift; sourceTree = ""; }; 52 | 30031EF82949EAB70061796E /* MonthlyPerformanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonthlyPerformanceView.swift; sourceTree = ""; }; 53 | 30031EFB294CF3320061796E /* BaseChartsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseChartsView.swift; sourceTree = ""; }; 54 | 30031EFD294D07A90061796E /* XAxisView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XAxisView.swift; sourceTree = ""; }; 55 | 30031EFF294D13570061796E /* YAxisView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YAxisView.swift; sourceTree = ""; }; 56 | 30031F02295616D70061796E /* ChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChartView.swift; sourceTree = ""; }; 57 | 301274FC2885A72C00AF2521 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 58 | 301274FE2888106900AF2521 /* WeekView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekView.swift; sourceTree = ""; }; 59 | 3021B64B292B9B5F00B54DC5 /* BaseBarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseBarsView.swift; sourceTree = ""; }; 60 | 3021B64E292BA1E000B54DC5 /* BaseBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseBarView.swift; sourceTree = ""; }; 61 | 304B926D2883F2C4003A542D /* BaseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseButton.swift; sourceTree = ""; }; 62 | 304B926F2885762D003A542D /* OverviewNavBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverviewNavBar.swift; sourceTree = ""; }; 63 | 304B927128857673003A542D /* BaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseView.swift; sourceTree = ""; }; 64 | 304D43F1294603D6002C91DE /* DailyPerformanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyPerformanceView.swift; sourceTree = ""; }; 65 | 305B4C33287B4A1B00B6A6F1 /* Sport Kit Interface.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Sport Kit Interface.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | 305B4C36287B4A1B00B6A6F1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 67 | 305B4C38287B4A1B00B6A6F1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 68 | 305B4C3A287B4A1B00B6A6F1 /* OverviewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverviewController.swift; sourceTree = ""; }; 69 | 305B4C42287B4A1E00B6A6F1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 70 | 305B4C44287B4A1E00B6A6F1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | 305B4C50287C2BB700B6A6F1 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; 72 | 305B4C53287C2E6900B6A6F1 /* UIColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColor.swift; sourceTree = ""; }; 73 | 305B4C55287C2FC200B6A6F1 /* Resources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Resources.swift; sourceTree = ""; }; 74 | 307C93562882A3430066DAF1 /* BaseController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseController.swift; sourceTree = ""; }; 75 | 307C93582882AFD50066DAF1 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = ""; }; 76 | 307C935F2882BCE00066DAF1 /* SessionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionController.swift; sourceTree = ""; }; 77 | 307C93612882BD030066DAF1 /* ProgressController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressController.swift; sourceTree = ""; }; 78 | 307C93632882BD110066DAF1 /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = ""; }; 79 | 308928FE2891510600EBDCE8 /* TimerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerView.swift; sourceTree = ""; }; 80 | 308929002891B8D100EBDCE8 /* ProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressView.swift; sourceTree = ""; }; 81 | 30A53BED290F10B000714A1A /* StatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsView.swift; sourceTree = ""; }; 82 | 30A53BEF290F10BF00714A1A /* StepsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StepsView.swift; sourceTree = ""; }; 83 | 30A53BF2290F134300714A1A /* StatsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsItemView.swift; sourceTree = ""; }; 84 | 30B956F128881948002A4088 /* WeekDayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeekDayView.swift; sourceTree = ""; }; 85 | 30BF946D28829739006F2C47 /* NavBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavBarController.swift; sourceTree = ""; }; 86 | 30D8A98F288858ED0061D22C /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; 87 | 30D8A9932889C5BD0061D22C /* BaseInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseInfoView.swift; sourceTree = ""; }; 88 | 30E8008E28D85A8E00E7343E /* PercentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PercentView.swift; sourceTree = ""; }; 89 | /* End PBXFileReference section */ 90 | 91 | /* Begin PBXFrameworksBuildPhase section */ 92 | 305B4C30287B4A1B00B6A6F1 /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | 3002958929B0DAD200DCD984 /* CollectionView */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 3002958A29B0DAEE00DCD984 /* Views */, 106 | ); 107 | path = CollectionView; 108 | sourceTree = ""; 109 | }; 110 | 3002958A29B0DAEE00DCD984 /* Views */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 3002958B29B0DB0C00DCD984 /* SectionHeaderView.swift */, 114 | ); 115 | path = Views; 116 | sourceTree = ""; 117 | }; 118 | 30031EF72949EA8D0061796E /* MonthlyPerformanceView */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 30031EF82949EAB70061796E /* MonthlyPerformanceView.swift */, 122 | ); 123 | path = MonthlyPerformanceView; 124 | sourceTree = ""; 125 | }; 126 | 30031EFA294CF3030061796E /* ChartsViews */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 30031EFB294CF3320061796E /* BaseChartsView.swift */, 130 | 30031F01294D147F0061796E /* Views */, 131 | ); 132 | path = ChartsViews; 133 | sourceTree = ""; 134 | }; 135 | 30031F01294D147F0061796E /* Views */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | 30031EFD294D07A90061796E /* XAxisView.swift */, 139 | 30031EFF294D13570061796E /* YAxisView.swift */, 140 | 30031F02295616D70061796E /* ChartView.swift */, 141 | ); 142 | path = Views; 143 | sourceTree = ""; 144 | }; 145 | 301275002888107200AF2521 /* WeekView */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | 301274FE2888106900AF2521 /* WeekView.swift */, 149 | 30B956F128881948002A4088 /* WeekDayView.swift */, 150 | ); 151 | path = WeekView; 152 | sourceTree = ""; 153 | }; 154 | 3021B64D292B9B6900B54DC5 /* BarsViews */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | 3021B64B292B9B5F00B54DC5 /* BaseBarsView.swift */, 158 | 3021B64E292BA1E000B54DC5 /* BaseBarView.swift */, 159 | ); 160 | path = BarsViews; 161 | sourceTree = ""; 162 | }; 163 | 304B926C2883F299003A542D /* Views */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 3002958929B0DAD200DCD984 /* CollectionView */, 167 | 301275002888107200AF2521 /* WeekView */, 168 | 304B926F2885762D003A542D /* OverviewNavBar.swift */, 169 | 3002958D29C7653800DCD984 /* TrainingCellView.swift */, 170 | ); 171 | path = Views; 172 | sourceTree = ""; 173 | }; 174 | 304D43ED29451F64002C91DE /* Views */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 30031EF72949EA8D0061796E /* MonthlyPerformanceView */, 178 | 304D43EE29451F93002C91DE /* Performance */, 179 | ); 180 | path = Views; 181 | sourceTree = ""; 182 | }; 183 | 304D43EE29451F93002C91DE /* Performance */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 304D43F1294603D6002C91DE /* DailyPerformanceView.swift */, 187 | ); 188 | path = Performance; 189 | sourceTree = ""; 190 | }; 191 | 305B4C2A287B4A1B00B6A6F1 = { 192 | isa = PBXGroup; 193 | children = ( 194 | 305B4C35287B4A1B00B6A6F1 /* Sport Kit Interface */, 195 | 305B4C34287B4A1B00B6A6F1 /* Products */, 196 | ); 197 | sourceTree = ""; 198 | }; 199 | 305B4C34287B4A1B00B6A6F1 /* Products */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 305B4C33287B4A1B00B6A6F1 /* Sport Kit Interface.app */, 203 | ); 204 | name = Products; 205 | sourceTree = ""; 206 | }; 207 | 305B4C35287B4A1B00B6A6F1 /* Sport Kit Interface */ = { 208 | isa = PBXGroup; 209 | children = ( 210 | 30A53BF52917BEFD00714A1A /* Resources */, 211 | 305B4C52287C2E3C00B6A6F1 /* Extentions */, 212 | 307C93552882A3210066DAF1 /* Controllers */, 213 | 30D8A9912889C52D0061D22C /* Navigation */, 214 | 307C935A2882BC7A0066DAF1 /* Base */, 215 | 305B4C4D287B555A00B6A6F1 /* Application */, 216 | ); 217 | path = "Sport Kit Interface"; 218 | sourceTree = ""; 219 | }; 220 | 305B4C4D287B555A00B6A6F1 /* Application */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 305B4C36287B4A1B00B6A6F1 /* AppDelegate.swift */, 224 | 305B4C38287B4A1B00B6A6F1 /* SceneDelegate.swift */, 225 | 305B4C41287B4A1E00B6A6F1 /* LaunchScreen.storyboard */, 226 | 305B4C44287B4A1E00B6A6F1 /* Info.plist */, 227 | ); 228 | path = Application; 229 | sourceTree = ""; 230 | }; 231 | 305B4C52287C2E3C00B6A6F1 /* Extentions */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 305B4C53287C2E6900B6A6F1 /* UIColor.swift */, 235 | 307C93582882AFD50066DAF1 /* UIView.swift */, 236 | 30D8A98F288858ED0061D22C /* Date.swift */, 237 | ); 238 | path = Extentions; 239 | sourceTree = ""; 240 | }; 241 | 307C93552882A3210066DAF1 /* Controllers */ = { 242 | isa = PBXGroup; 243 | children = ( 244 | 307C935E2882BCBC0066DAF1 /* Settings */, 245 | 307C935D2882BCB60066DAF1 /* Progress */, 246 | 307C935C2882BCAA0066DAF1 /* Session */, 247 | 307C935B2882BC9D0066DAF1 /* Overview */, 248 | ); 249 | path = Controllers; 250 | sourceTree = ""; 251 | }; 252 | 307C935A2882BC7A0066DAF1 /* Base */ = { 253 | isa = PBXGroup; 254 | children = ( 255 | 30D8A9922889C58E0061D22C /* Views */, 256 | ); 257 | path = Base; 258 | sourceTree = ""; 259 | }; 260 | 307C935B2882BC9D0066DAF1 /* Overview */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | 305B4C3A287B4A1B00B6A6F1 /* OverviewController.swift */, 264 | 304B926C2883F299003A542D /* Views */, 265 | ); 266 | path = Overview; 267 | sourceTree = ""; 268 | }; 269 | 307C935C2882BCAA0066DAF1 /* Session */ = { 270 | isa = PBXGroup; 271 | children = ( 272 | 307C935F2882BCE00066DAF1 /* SessionController.swift */, 273 | 308928FD289150ED00EBDCE8 /* Views */, 274 | ); 275 | path = Session; 276 | sourceTree = ""; 277 | }; 278 | 307C935D2882BCB60066DAF1 /* Progress */ = { 279 | isa = PBXGroup; 280 | children = ( 281 | 304D43ED29451F64002C91DE /* Views */, 282 | 307C93612882BD030066DAF1 /* ProgressController.swift */, 283 | ); 284 | path = Progress; 285 | sourceTree = ""; 286 | }; 287 | 307C935E2882BCBC0066DAF1 /* Settings */ = { 288 | isa = PBXGroup; 289 | children = ( 290 | 307C93632882BD110066DAF1 /* SettingsController.swift */, 291 | ); 292 | path = Settings; 293 | sourceTree = ""; 294 | }; 295 | 308928FD289150ED00EBDCE8 /* Views */ = { 296 | isa = PBXGroup; 297 | children = ( 298 | 30A53BEC290AB87900714A1A /* Timer */, 299 | 30A53BEA290AB83A00714A1A /* Stats */, 300 | 30A53BEB290AB85400714A1A /* Steps */, 301 | ); 302 | path = Views; 303 | sourceTree = ""; 304 | }; 305 | 30A53BEA290AB83A00714A1A /* Stats */ = { 306 | isa = PBXGroup; 307 | children = ( 308 | 30A53BED290F10B000714A1A /* StatsView.swift */, 309 | 30A53BF1290F131C00714A1A /* Views */, 310 | ); 311 | path = Stats; 312 | sourceTree = ""; 313 | }; 314 | 30A53BEB290AB85400714A1A /* Steps */ = { 315 | isa = PBXGroup; 316 | children = ( 317 | 30A53BEF290F10BF00714A1A /* StepsView.swift */, 318 | ); 319 | path = Steps; 320 | sourceTree = ""; 321 | }; 322 | 30A53BEC290AB87900714A1A /* Timer */ = { 323 | isa = PBXGroup; 324 | children = ( 325 | 308928FE2891510600EBDCE8 /* TimerView.swift */, 326 | 308929002891B8D100EBDCE8 /* ProgressView.swift */, 327 | 30E8008E28D85A8E00E7343E /* PercentView.swift */, 328 | ); 329 | path = Timer; 330 | sourceTree = ""; 331 | }; 332 | 30A53BF1290F131C00714A1A /* Views */ = { 333 | isa = PBXGroup; 334 | children = ( 335 | 30A53BF2290F134300714A1A /* StatsItemView.swift */, 336 | ); 337 | path = Views; 338 | sourceTree = ""; 339 | }; 340 | 30A53BF52917BEFD00714A1A /* Resources */ = { 341 | isa = PBXGroup; 342 | children = ( 343 | 305B4C55287C2FC200B6A6F1 /* Resources.swift */, 344 | 301274FC2885A72C00AF2521 /* Assets.xcassets */, 345 | ); 346 | path = Resources; 347 | sourceTree = ""; 348 | }; 349 | 30D8A9912889C52D0061D22C /* Navigation */ = { 350 | isa = PBXGroup; 351 | children = ( 352 | 305B4C50287C2BB700B6A6F1 /* TabBarController.swift */, 353 | 30BF946D28829739006F2C47 /* NavBarController.swift */, 354 | ); 355 | path = Navigation; 356 | sourceTree = ""; 357 | }; 358 | 30D8A9922889C58E0061D22C /* Views */ = { 359 | isa = PBXGroup; 360 | children = ( 361 | 30031EFA294CF3030061796E /* ChartsViews */, 362 | 3021B64D292B9B6900B54DC5 /* BarsViews */, 363 | 307C93562882A3430066DAF1 /* BaseController.swift */, 364 | 304B926D2883F2C4003A542D /* BaseButton.swift */, 365 | 304B927128857673003A542D /* BaseView.swift */, 366 | 30D8A9932889C5BD0061D22C /* BaseInfoView.swift */, 367 | ); 368 | path = Views; 369 | sourceTree = ""; 370 | }; 371 | /* End PBXGroup section */ 372 | 373 | /* Begin PBXNativeTarget section */ 374 | 305B4C32287B4A1B00B6A6F1 /* Sport Kit Interface */ = { 375 | isa = PBXNativeTarget; 376 | buildConfigurationList = 305B4C47287B4A1E00B6A6F1 /* Build configuration list for PBXNativeTarget "Sport Kit Interface" */; 377 | buildPhases = ( 378 | 305B4C2F287B4A1B00B6A6F1 /* Sources */, 379 | 305B4C30287B4A1B00B6A6F1 /* Frameworks */, 380 | 305B4C31287B4A1B00B6A6F1 /* Resources */, 381 | ); 382 | buildRules = ( 383 | ); 384 | dependencies = ( 385 | ); 386 | name = "Sport Kit Interface"; 387 | productName = "Sport Kit Interface"; 388 | productReference = 305B4C33287B4A1B00B6A6F1 /* Sport Kit Interface.app */; 389 | productType = "com.apple.product-type.application"; 390 | }; 391 | /* End PBXNativeTarget section */ 392 | 393 | /* Begin PBXProject section */ 394 | 305B4C2B287B4A1B00B6A6F1 /* Project object */ = { 395 | isa = PBXProject; 396 | attributes = { 397 | BuildIndependentTargetsInParallel = 1; 398 | LastSwiftUpdateCheck = 1340; 399 | LastUpgradeCheck = 1340; 400 | TargetAttributes = { 401 | 305B4C32287B4A1B00B6A6F1 = { 402 | CreatedOnToolsVersion = 13.4.1; 403 | }; 404 | }; 405 | }; 406 | buildConfigurationList = 305B4C2E287B4A1B00B6A6F1 /* Build configuration list for PBXProject "Sport Kit Interface" */; 407 | compatibilityVersion = "Xcode 13.0"; 408 | developmentRegion = en; 409 | hasScannedForEncodings = 0; 410 | knownRegions = ( 411 | en, 412 | Base, 413 | ); 414 | mainGroup = 305B4C2A287B4A1B00B6A6F1; 415 | productRefGroup = 305B4C34287B4A1B00B6A6F1 /* Products */; 416 | projectDirPath = ""; 417 | projectRoot = ""; 418 | targets = ( 419 | 305B4C32287B4A1B00B6A6F1 /* Sport Kit Interface */, 420 | ); 421 | }; 422 | /* End PBXProject section */ 423 | 424 | /* Begin PBXResourcesBuildPhase section */ 425 | 305B4C31287B4A1B00B6A6F1 /* Resources */ = { 426 | isa = PBXResourcesBuildPhase; 427 | buildActionMask = 2147483647; 428 | files = ( 429 | 301274FD2885A72C00AF2521 /* Assets.xcassets in Resources */, 430 | 305B4C43287B4A1E00B6A6F1 /* LaunchScreen.storyboard in Resources */, 431 | ); 432 | runOnlyForDeploymentPostprocessing = 0; 433 | }; 434 | /* End PBXResourcesBuildPhase section */ 435 | 436 | /* Begin PBXSourcesBuildPhase section */ 437 | 305B4C2F287B4A1B00B6A6F1 /* Sources */ = { 438 | isa = PBXSourcesBuildPhase; 439 | buildActionMask = 2147483647; 440 | files = ( 441 | 301274FF2888106900AF2521 /* WeekView.swift in Sources */, 442 | 307C93642882BD110066DAF1 /* SettingsController.swift in Sources */, 443 | 305B4C3B287B4A1B00B6A6F1 /* OverviewController.swift in Sources */, 444 | 304B92702885762D003A542D /* OverviewNavBar.swift in Sources */, 445 | 305B4C56287C2FC200B6A6F1 /* Resources.swift in Sources */, 446 | 30031EF92949EAB70061796E /* MonthlyPerformanceView.swift in Sources */, 447 | 3021B64C292B9B5F00B54DC5 /* BaseBarsView.swift in Sources */, 448 | 305B4C51287C2BB700B6A6F1 /* TabBarController.swift in Sources */, 449 | 30BF946E28829739006F2C47 /* NavBarController.swift in Sources */, 450 | 30D8A990288858ED0061D22C /* Date.swift in Sources */, 451 | 304D43F2294603D6002C91DE /* DailyPerformanceView.swift in Sources */, 452 | 307C93602882BCE00066DAF1 /* SessionController.swift in Sources */, 453 | 304B926E2883F2C4003A542D /* BaseButton.swift in Sources */, 454 | 308928FF2891510600EBDCE8 /* TimerView.swift in Sources */, 455 | 30031EFC294CF3320061796E /* BaseChartsView.swift in Sources */, 456 | 308929012891B8D100EBDCE8 /* ProgressView.swift in Sources */, 457 | 307C93622882BD030066DAF1 /* ProgressController.swift in Sources */, 458 | 305B4C37287B4A1B00B6A6F1 /* AppDelegate.swift in Sources */, 459 | 30031F00294D13570061796E /* YAxisView.swift in Sources */, 460 | 30031EFE294D07A90061796E /* XAxisView.swift in Sources */, 461 | 305B4C39287B4A1B00B6A6F1 /* SceneDelegate.swift in Sources */, 462 | 307C93572882A3430066DAF1 /* BaseController.swift in Sources */, 463 | 30A53BF3290F134300714A1A /* StatsItemView.swift in Sources */, 464 | 30E8008F28D85A8E00E7343E /* PercentView.swift in Sources */, 465 | 304B927228857673003A542D /* BaseView.swift in Sources */, 466 | 30B956F228881948002A4088 /* WeekDayView.swift in Sources */, 467 | 3021B64F292BA1E000B54DC5 /* BaseBarView.swift in Sources */, 468 | 3002958C29B0DB0C00DCD984 /* SectionHeaderView.swift in Sources */, 469 | 307C93592882AFD50066DAF1 /* UIView.swift in Sources */, 470 | 3002958E29C7653900DCD984 /* TrainingCellView.swift in Sources */, 471 | 30A53BF0290F10BF00714A1A /* StepsView.swift in Sources */, 472 | 30031F03295616D70061796E /* ChartView.swift in Sources */, 473 | 30A53BEE290F10B000714A1A /* StatsView.swift in Sources */, 474 | 30D8A9942889C5BD0061D22C /* BaseInfoView.swift in Sources */, 475 | 305B4C54287C2E6900B6A6F1 /* UIColor.swift in Sources */, 476 | ); 477 | runOnlyForDeploymentPostprocessing = 0; 478 | }; 479 | /* End PBXSourcesBuildPhase section */ 480 | 481 | /* Begin PBXVariantGroup section */ 482 | 305B4C41287B4A1E00B6A6F1 /* LaunchScreen.storyboard */ = { 483 | isa = PBXVariantGroup; 484 | children = ( 485 | 305B4C42287B4A1E00B6A6F1 /* Base */, 486 | ); 487 | name = LaunchScreen.storyboard; 488 | sourceTree = ""; 489 | }; 490 | /* End PBXVariantGroup section */ 491 | 492 | /* Begin XCBuildConfiguration section */ 493 | 305B4C45287B4A1E00B6A6F1 /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | buildSettings = { 496 | ALWAYS_SEARCH_USER_PATHS = NO; 497 | CLANG_ANALYZER_NONNULL = YES; 498 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 499 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 500 | CLANG_ENABLE_MODULES = YES; 501 | CLANG_ENABLE_OBJC_ARC = YES; 502 | CLANG_ENABLE_OBJC_WEAK = YES; 503 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 504 | CLANG_WARN_BOOL_CONVERSION = YES; 505 | CLANG_WARN_COMMA = YES; 506 | CLANG_WARN_CONSTANT_CONVERSION = YES; 507 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 508 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 509 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 510 | CLANG_WARN_EMPTY_BODY = YES; 511 | CLANG_WARN_ENUM_CONVERSION = YES; 512 | CLANG_WARN_INFINITE_RECURSION = YES; 513 | CLANG_WARN_INT_CONVERSION = YES; 514 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 515 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 516 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 517 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 518 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 519 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 520 | CLANG_WARN_STRICT_PROTOTYPES = YES; 521 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 522 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 523 | CLANG_WARN_UNREACHABLE_CODE = YES; 524 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 525 | COPY_PHASE_STRIP = NO; 526 | DEBUG_INFORMATION_FORMAT = dwarf; 527 | ENABLE_STRICT_OBJC_MSGSEND = YES; 528 | ENABLE_TESTABILITY = YES; 529 | GCC_C_LANGUAGE_STANDARD = gnu11; 530 | GCC_DYNAMIC_NO_PIC = NO; 531 | GCC_NO_COMMON_BLOCKS = YES; 532 | GCC_OPTIMIZATION_LEVEL = 0; 533 | GCC_PREPROCESSOR_DEFINITIONS = ( 534 | "DEBUG=1", 535 | "$(inherited)", 536 | ); 537 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 538 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 539 | GCC_WARN_UNDECLARED_SELECTOR = YES; 540 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 541 | GCC_WARN_UNUSED_FUNCTION = YES; 542 | GCC_WARN_UNUSED_VARIABLE = YES; 543 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 544 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 545 | MTL_FAST_MATH = YES; 546 | ONLY_ACTIVE_ARCH = YES; 547 | SDKROOT = iphoneos; 548 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 549 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 550 | }; 551 | name = Debug; 552 | }; 553 | 305B4C46287B4A1E00B6A6F1 /* Release */ = { 554 | isa = XCBuildConfiguration; 555 | buildSettings = { 556 | ALWAYS_SEARCH_USER_PATHS = NO; 557 | CLANG_ANALYZER_NONNULL = YES; 558 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 559 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 560 | CLANG_ENABLE_MODULES = YES; 561 | CLANG_ENABLE_OBJC_ARC = YES; 562 | CLANG_ENABLE_OBJC_WEAK = YES; 563 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 564 | CLANG_WARN_BOOL_CONVERSION = YES; 565 | CLANG_WARN_COMMA = YES; 566 | CLANG_WARN_CONSTANT_CONVERSION = YES; 567 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 568 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 569 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 570 | CLANG_WARN_EMPTY_BODY = YES; 571 | CLANG_WARN_ENUM_CONVERSION = YES; 572 | CLANG_WARN_INFINITE_RECURSION = YES; 573 | CLANG_WARN_INT_CONVERSION = YES; 574 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 575 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 576 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 577 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 578 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 579 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 580 | CLANG_WARN_STRICT_PROTOTYPES = YES; 581 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 582 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 583 | CLANG_WARN_UNREACHABLE_CODE = YES; 584 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 585 | COPY_PHASE_STRIP = NO; 586 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 587 | ENABLE_NS_ASSERTIONS = NO; 588 | ENABLE_STRICT_OBJC_MSGSEND = YES; 589 | GCC_C_LANGUAGE_STANDARD = gnu11; 590 | GCC_NO_COMMON_BLOCKS = YES; 591 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 592 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 593 | GCC_WARN_UNDECLARED_SELECTOR = YES; 594 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 595 | GCC_WARN_UNUSED_FUNCTION = YES; 596 | GCC_WARN_UNUSED_VARIABLE = YES; 597 | IPHONEOS_DEPLOYMENT_TARGET = 15.5; 598 | MTL_ENABLE_DEBUG_INFO = NO; 599 | MTL_FAST_MATH = YES; 600 | SDKROOT = iphoneos; 601 | SWIFT_COMPILATION_MODE = wholemodule; 602 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 603 | VALIDATE_PRODUCT = YES; 604 | }; 605 | name = Release; 606 | }; 607 | 305B4C48287B4A1E00B6A6F1 /* Debug */ = { 608 | isa = XCBuildConfiguration; 609 | buildSettings = { 610 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 611 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 612 | CODE_SIGN_STYLE = Automatic; 613 | CURRENT_PROJECT_VERSION = 1; 614 | GENERATE_INFOPLIST_FILE = YES; 615 | INFOPLIST_FILE = "Sport Kit Interface/Application/Info.plist"; 616 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 617 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 618 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; 619 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 620 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 621 | LD_RUNPATH_SEARCH_PATHS = ( 622 | "$(inherited)", 623 | "@executable_path/Frameworks", 624 | ); 625 | MARKETING_VERSION = 1.0; 626 | PRODUCT_BUNDLE_IDENTIFIER = "Ungros.Sport-Kit-Interface"; 627 | PRODUCT_NAME = "$(TARGET_NAME)"; 628 | SWIFT_EMIT_LOC_STRINGS = YES; 629 | SWIFT_VERSION = 5.0; 630 | TARGETED_DEVICE_FAMILY = 1; 631 | }; 632 | name = Debug; 633 | }; 634 | 305B4C49287B4A1E00B6A6F1 /* Release */ = { 635 | isa = XCBuildConfiguration; 636 | buildSettings = { 637 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 638 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 639 | CODE_SIGN_STYLE = Automatic; 640 | CURRENT_PROJECT_VERSION = 1; 641 | GENERATE_INFOPLIST_FILE = YES; 642 | INFOPLIST_FILE = "Sport Kit Interface/Application/Info.plist"; 643 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 644 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 645 | INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; 646 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 647 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 648 | LD_RUNPATH_SEARCH_PATHS = ( 649 | "$(inherited)", 650 | "@executable_path/Frameworks", 651 | ); 652 | MARKETING_VERSION = 1.0; 653 | PRODUCT_BUNDLE_IDENTIFIER = "Ungros.Sport-Kit-Interface"; 654 | PRODUCT_NAME = "$(TARGET_NAME)"; 655 | SWIFT_EMIT_LOC_STRINGS = YES; 656 | SWIFT_VERSION = 5.0; 657 | TARGETED_DEVICE_FAMILY = 1; 658 | }; 659 | name = Release; 660 | }; 661 | /* End XCBuildConfiguration section */ 662 | 663 | /* Begin XCConfigurationList section */ 664 | 305B4C2E287B4A1B00B6A6F1 /* Build configuration list for PBXProject "Sport Kit Interface" */ = { 665 | isa = XCConfigurationList; 666 | buildConfigurations = ( 667 | 305B4C45287B4A1E00B6A6F1 /* Debug */, 668 | 305B4C46287B4A1E00B6A6F1 /* Release */, 669 | ); 670 | defaultConfigurationIsVisible = 0; 671 | defaultConfigurationName = Release; 672 | }; 673 | 305B4C47287B4A1E00B6A6F1 /* Build configuration list for PBXNativeTarget "Sport Kit Interface" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | 305B4C48287B4A1E00B6A6F1 /* Debug */, 677 | 305B4C49287B4A1E00B6A6F1 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | defaultConfigurationName = Release; 681 | }; 682 | /* End XCConfigurationList section */ 683 | }; 684 | rootObject = 305B4C2B287B4A1B00B6A6F1 /* Project object */; 685 | } 686 | -------------------------------------------------------------------------------- /Sport Kit Interface.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sport Kit Interface.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Sport Kit Interface.xcodeproj/xcuserdata/Roman.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /Sport Kit Interface.xcodeproj/xcuserdata/Roman.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Sport Kit Interface.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Sport Kit Interface/Application/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 10.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | func application(_ application: UIApplication, 14 | didFinishLaunchingWithOptions 15 | launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | return true 17 | } 18 | } 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sport Kit Interface/Application/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 | -------------------------------------------------------------------------------- /Sport Kit Interface/Application/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sport Kit Interface/Application/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 10.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 11 | 12 | var window: UIWindow? 13 | 14 | 15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 16 | 17 | guard let tabBarScene = (scene as? UIWindowScene) else { return } 18 | 19 | let tabBarController = TabBarController() 20 | 21 | window = UIWindow(frame: tabBarScene.coordinateSpace.bounds) 22 | window?.windowScene = tabBarScene 23 | window?.rootViewController = tabBarController 24 | window?.makeKeyAndVisible() 25 | 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BarsViews/BaseBarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseBarView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 21.11.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension BaseBarView { 11 | struct Data { 12 | let value: String 13 | let heigntMultiplier: Double 14 | let title: String 15 | } 16 | } 17 | 18 | final class BaseBarView: BaseView { 19 | 20 | private let heigntMultiplier: Double 21 | 22 | private let valueLabel: UILabel = { 23 | let label = UILabel() 24 | label.font = R.Fonts.helvelticaRegular(with: 13) 25 | label.textColor = R.Colors.active 26 | return label 27 | }() 28 | 29 | private let barView: UIView = { 30 | let view = UIView() 31 | view.backgroundColor = R.Colors.active 32 | view.layer.cornerRadius = 2.5 33 | return view 34 | }() 35 | 36 | private let titleLabel: UILabel = { 37 | let label = UILabel() 38 | label.font = R.Fonts.helvelticaRegular(with: 9) 39 | label.textColor = R.Colors.inactive 40 | return label 41 | }() 42 | 43 | init(data: Data) { 44 | self.heigntMultiplier = data.heigntMultiplier 45 | super.init(frame: .zero) 46 | 47 | valueLabel.text = data.value 48 | titleLabel.text = data.title.uppercased() 49 | 50 | 51 | } 52 | 53 | required init?(coder: NSCoder) { 54 | self.heigntMultiplier = 0 55 | super.init(frame: .zero) 56 | } 57 | 58 | 59 | } 60 | 61 | 62 | extension BaseBarView { 63 | 64 | override func setupViews() { 65 | super.setupViews() 66 | 67 | setupView(valueLabel) 68 | setupView(barView) 69 | setupView(titleLabel) 70 | 71 | } 72 | 73 | override func constaintViews() { 74 | super.constaintViews() 75 | 76 | NSLayoutConstraint.activate([ 77 | 78 | valueLabel.centerXAnchor.constraint(equalTo: centerXAnchor), 79 | valueLabel.heightAnchor.constraint(equalToConstant: 10), 80 | 81 | barView.topAnchor.constraint(equalTo: valueLabel.bottomAnchor, constant: 7), 82 | barView.centerXAnchor.constraint(equalTo: centerXAnchor), 83 | barView.widthAnchor.constraint(equalToConstant: 17), 84 | barView.heightAnchor.constraint(equalTo: heightAnchor, multiplier: heigntMultiplier * 0.8), 85 | 86 | 87 | titleLabel.topAnchor.constraint(equalTo: barView.bottomAnchor, constant: 10), 88 | titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor), 89 | titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor), 90 | titleLabel.heightAnchor.constraint(equalToConstant: 10) 91 | 92 | ]) 93 | } 94 | 95 | override func configureAppearance() { 96 | super.configureAppearance() 97 | 98 | backgroundColor = .clear 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BarsViews/BaseBarsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseBarsView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 21.11.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class BaseBarsView: BaseView { 11 | 12 | private let stackView: UIStackView = { 13 | let view = UIStackView() 14 | view.distribution = .fillEqually 15 | 16 | return view 17 | }() 18 | 19 | //zzz 20 | func configureX(with data: [BaseBarView.Data]) { 21 | data.forEach { 22 | let barView = BaseBarView(data: $0) 23 | stackView.addArrangedSubview(barView) 24 | } 25 | } 26 | } 27 | 28 | 29 | 30 | 31 | extension BaseBarsView { 32 | override func setupViews() { 33 | super.setupViews() 34 | 35 | setupView(stackView) 36 | 37 | } 38 | 39 | override func constaintViews() { 40 | super.constaintViews() 41 | 42 | NSLayoutConstraint.activate([ 43 | 44 | stackView.leadingAnchor.constraint(equalTo: leadingAnchor), 45 | stackView.topAnchor.constraint(equalTo: topAnchor), 46 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor), 47 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor), 48 | 49 | ]) 50 | } 51 | 52 | override func configureAppearance() { 53 | super.configureAppearance() 54 | 55 | backgroundColor = .clear 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BaseButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseButton.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 17.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | public enum WAButtonType { 11 | case primary 12 | case secondary 13 | } 14 | 15 | final class BaseButton: UIButton { 16 | 17 | private var type: WAButtonType = .primary 18 | 19 | private let lable: UILabel = { 20 | let lable = UILabel() 21 | lable.textAlignment = .center 22 | return lable 23 | }() 24 | 25 | private let iconView: UIImageView = { 26 | let view = UIImageView() 27 | view.image = R.Images.Common.downArrow?.withRenderingMode(.alwaysTemplate) 28 | return view 29 | }() 30 | 31 | init(with type: WAButtonType) { 32 | super.init(frame: .zero) 33 | self.type = type 34 | 35 | setupViews() 36 | constaintViews() 37 | configureAppearance() 38 | } 39 | 40 | required init?(coder: NSCoder) { 41 | super.init(frame: .zero) 42 | 43 | setupViews() 44 | constaintViews() 45 | configureAppearance() 46 | } 47 | 48 | func setTitle(_ title: String?) { 49 | lable.text = title 50 | } 51 | } 52 | 53 | private extension BaseButton { 54 | 55 | func setupViews() { 56 | setupView(lable) 57 | setupView(iconView) 58 | } 59 | 60 | func constaintViews() { 61 | var horisontalOffset: CGFloat { 62 | switch type { 63 | case .primary: return 0 64 | case .secondary: return 10 65 | } 66 | } 67 | 68 | NSLayoutConstraint.activate([ 69 | iconView.centerYAnchor.constraint(equalTo: centerYAnchor), 70 | iconView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -horisontalOffset), 71 | iconView.heightAnchor.constraint(equalToConstant: 5), 72 | iconView.widthAnchor.constraint(equalToConstant: 10), 73 | 74 | lable.centerYAnchor.constraint(equalTo: centerYAnchor), 75 | lable.trailingAnchor.constraint(equalTo: iconView.leadingAnchor, constant: -10), 76 | lable.leadingAnchor.constraint(equalTo: leadingAnchor, constant: horisontalOffset * 2) 77 | ]) 78 | } 79 | 80 | func configureAppearance() { 81 | switch type { 82 | case .primary: 83 | lable.textColor = R.Colors.inactive 84 | lable.font = R.Fonts.helvelticaRegular(with: 13) 85 | iconView.tintColor = R.Colors.inactive 86 | 87 | case .secondary: 88 | backgroundColor = R.Colors.secondary 89 | layer.cornerRadius = 14 90 | lable.textColor = R.Colors.active 91 | lable.font = R.Fonts.helvelticaRegular(with: 14) 92 | iconView.tintColor = R.Colors.active 93 | } 94 | 95 | makeSystem(self) 96 | } 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BaseController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum NavBarPosition { 11 | case Left 12 | case Right 13 | } 14 | 15 | class BaseController: UIViewController { 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | 21 | setupViews() 22 | constaintViews() 23 | configureAppearance() 24 | 25 | 26 | } 27 | } 28 | 29 | @objc extension BaseController { 30 | 31 | 32 | func setupViews(){} 33 | func constaintViews(){} 34 | func configureAppearance(){ 35 | view.backgroundColor = R.Colors.background 36 | 37 | } 38 | 39 | 40 | 41 | func navBarLeftButtonHandler(){ print("NavBar Lefight button tapped") } 42 | 43 | func navBarRightButtonHanler(){ print("NavBar Right button tapped") } 44 | } 45 | 46 | 47 | 48 | extension BaseController { 49 | 50 | func addNavBarButton(at position: NavBarPosition, with title: String) { 51 | let button = UIButton(type: .system) 52 | button.setTitle(title, for: .normal) 53 | button.setTitleColor(R.Colors.active, for: .normal) 54 | button.setTitleColor(R.Colors.inactive, for: .disabled) 55 | button.titleLabel?.font = R.Fonts.helvelticaRegular(with: 17) 56 | 57 | switch position { 58 | case .Left: 59 | button.addTarget(self, action: #selector(navBarLeftButtonHandler), for: .touchUpInside) 60 | navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button) 61 | case .Right: 62 | button.addTarget(self, action: #selector(navBarRightButtonHanler), for: .touchUpInside) 63 | navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BaseInfoView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseInfoView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 21.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class BaseInfoView: BaseView { 11 | 12 | private let titleLabel: UILabel = { 13 | let label = UILabel() 14 | label.font = R.Fonts.helvelticaRegular(with: 13) 15 | label.textColor = R.Colors.inactive 16 | return label 17 | }() 18 | 19 | private let button = BaseButton(with: .primary) 20 | 21 | let contentView: UIView = { 22 | let view = UIView() 23 | view.backgroundColor = .white 24 | view.layer.borderColor = R.Colors.separator.cgColor 25 | view.layer.borderWidth = 1 26 | view.layer.cornerRadius = 5 27 | return view 28 | }() 29 | 30 | init(with title: String? = nil, buttonTitle: String? = nil) { 31 | titleLabel.text = title?.uppercased() 32 | titleLabel.textAlignment = buttonTitle == nil ? .center : .left 33 | 34 | button.setTitle(buttonTitle?.uppercased()) 35 | button.isHidden = buttonTitle == nil ? true : false 36 | 37 | super.init(frame: .zero) 38 | } 39 | 40 | required init?(coder: NSCoder) { 41 | super.init(frame: .zero) 42 | } 43 | 44 | func addButtonTarget(target: Any?, action: Selector) { 45 | button.addTarget(action, action: action, for: .touchUpInside) 46 | } 47 | } 48 | 49 | extension BaseInfoView { 50 | override func setupViews() { 51 | super.setupViews() 52 | 53 | setupView(titleLabel) 54 | setupView(button) 55 | setupView(contentView) 56 | } 57 | 58 | override func constaintViews() { 59 | super.constaintViews() 60 | 61 | let contentTopAnchor: NSLayoutAnchor = titleLabel.text == nil ? topAnchor : titleLabel.bottomAnchor 62 | let contentTopOffset: CGFloat = titleLabel.text == nil ? 0 : 10 63 | 64 | NSLayoutConstraint.activate([ 65 | titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor), 66 | titleLabel.topAnchor.constraint(equalTo: topAnchor), 67 | titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor), 68 | 69 | button.trailingAnchor.constraint(equalTo: trailingAnchor), 70 | button.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor), 71 | button.heightAnchor.constraint(equalToConstant: 28), 72 | 73 | contentView.topAnchor.constraint(equalTo: contentTopAnchor, constant: contentTopOffset), 74 | contentView.leadingAnchor.constraint(equalTo: leadingAnchor), 75 | contentView.trailingAnchor.constraint(equalTo: trailingAnchor), 76 | contentView.bottomAnchor.constraint(equalTo: bottomAnchor) 77 | ]) 78 | } 79 | 80 | override func configureAppearance() { 81 | super.configureAppearance() 82 | 83 | backgroundColor = .clear 84 | } 85 | } 86 | 87 | 88 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/BaseView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 18.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class BaseView: UIView { 11 | 12 | override init(frame: CGRect) { 13 | super.init(frame: frame) 14 | 15 | setupViews() 16 | constaintViews() 17 | configureAppearance() 18 | } 19 | 20 | required init?(coder: NSCoder) { 21 | fatalError("init(coder:) has not been implemented") 22 | } 23 | } 24 | 25 | @objc extension BaseView { 26 | 27 | func setupViews(){} 28 | func constaintViews(){} 29 | func configureAppearance(){ 30 | 31 | backgroundColor = .white 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/ChartsViews/BaseChartsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseChartsView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension BaseChartsView { 11 | struct Data { 12 | let value: Int 13 | let title: String 14 | } 15 | } 16 | 17 | final class BaseChartsView: BaseView { 18 | 19 | private let yAxisView = YAxisView() 20 | private let xAxisView = XAxisView() 21 | 22 | private let chartView = ChartView() //BaseChartsView() 23 | 24 | func configureX(with data: [BaseChartsView.Data], topChartOffset: Int = 10) { 25 | yAxisView.configure(with: data) 26 | xAxisView.configure(with: data) 27 | chartView.configure(with: data, topChartOffset: topChartOffset) 28 | } 29 | } 30 | 31 | extension BaseChartsView { 32 | override func setupViews() { 33 | super.setupViews() 34 | 35 | setupView(yAxisView) 36 | setupView(xAxisView) 37 | 38 | setupView(chartView) 39 | 40 | } 41 | 42 | override func constaintViews() { 43 | super.constaintViews() 44 | 45 | NSLayoutConstraint.activate([ 46 | 47 | yAxisView.leadingAnchor.constraint(equalTo: leadingAnchor), 48 | yAxisView.topAnchor.constraint(equalTo: topAnchor), 49 | yAxisView.bottomAnchor.constraint(equalTo: xAxisView.topAnchor, constant: -15), 50 | 51 | xAxisView.leadingAnchor.constraint(equalTo: yAxisView.trailingAnchor, constant: 8), 52 | xAxisView.bottomAnchor.constraint(equalTo: bottomAnchor), 53 | xAxisView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 4), 54 | 55 | chartView.topAnchor.constraint(equalTo: topAnchor, constant: 4), 56 | chartView.bottomAnchor.constraint(equalTo: xAxisView.topAnchor, constant: -16), 57 | chartView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -4), 58 | chartView.leadingAnchor.constraint(equalTo: yAxisView.trailingAnchor, constant: 16) 59 | ]) 60 | } 61 | 62 | override func configureAppearance() { 63 | super.configureAppearance() 64 | 65 | backgroundColor = .clear 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/ChartsViews/Views/ChartView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChartView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 23.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class ChartView: BaseView { 11 | 12 | private let yAxisSeparator: UIView = { 13 | let view = UIView() 14 | view.backgroundColor = R.Colors.separator 15 | return view 16 | }() 17 | 18 | private let xAxisSeparator: UIView = { 19 | let view = UIView() 20 | view.backgroundColor = R.Colors.separator 21 | return view 22 | }() 23 | 24 | func configure(with data: [BaseChartsView.Data], topChartOffset: Int = 10) { 25 | 26 | layoutIfNeeded() 27 | drawDashLines() 28 | drawChart(with: data, topChartOffset: topChartOffset) 29 | } 30 | } 31 | 32 | extension ChartView { 33 | 34 | override func setupViews() { 35 | super.setupViews() 36 | 37 | setupView(yAxisSeparator) 38 | setupView(xAxisSeparator) 39 | 40 | } 41 | 42 | override func constaintViews() { 43 | super.constaintViews() 44 | 45 | NSLayoutConstraint.activate([ 46 | yAxisSeparator.leadingAnchor.constraint(equalTo: leadingAnchor), 47 | yAxisSeparator.topAnchor.constraint(equalTo: topAnchor), 48 | yAxisSeparator.bottomAnchor.constraint(equalTo: bottomAnchor), 49 | yAxisSeparator.widthAnchor.constraint(equalToConstant: 1), 50 | 51 | xAxisSeparator.leadingAnchor.constraint(equalTo: leadingAnchor), 52 | xAxisSeparator.trailingAnchor.constraint(equalTo: trailingAnchor), 53 | xAxisSeparator.bottomAnchor.constraint(equalTo: bottomAnchor), 54 | xAxisSeparator.heightAnchor.constraint(equalToConstant: 1), 55 | ]) 56 | } 57 | 58 | override func configureAppearance() { 59 | super.configureAppearance() 60 | 61 | backgroundColor = .clear 62 | } 63 | } 64 | 65 | private extension ChartView { 66 | 67 | func drawDashLines(with counts: Int = 9) { 68 | 69 | (0.. $1.value}).first?.value else {return} 92 | let valuePoints = data.enumerated().map {CGPoint(x: CGFloat($0), y: CGFloat($1.value))} 93 | let chartHeight = bounds.height / CGFloat(maxValue + 10) 94 | 95 | let points = valuePoints.map { 96 | let x = bounds.width / CGFloat(valuePoints.count - 1) * $0.x 97 | let y = bounds.height - $0.y * chartHeight 98 | return CGPoint(x: x, y: y) 99 | } 100 | 101 | let chartPath = UIBezierPath() 102 | chartPath.move(to: points[0]) 103 | 104 | points.forEach { 105 | chartPath.addLine(to: $0) 106 | drawChartDot(at: $0) 107 | } 108 | 109 | let chartLayer = CAShapeLayer() 110 | chartLayer.path = chartPath.cgPath 111 | chartLayer.fillColor = UIColor.clear.cgColor 112 | chartLayer.strokeColor = R.Colors.active.cgColor 113 | chartLayer.lineWidth = 3 114 | chartLayer.strokeEnd = 1 115 | chartLayer.lineCap = .round 116 | chartLayer.lineJoin = .round 117 | 118 | layer.addSublayer(chartLayer) 119 | } 120 | 121 | func drawChartDot(at point: CGPoint) { 122 | let dotPath = UIBezierPath() 123 | dotPath.move(to: point) 124 | dotPath.addLine(to: point) 125 | 126 | let dotLayer = CAShapeLayer() 127 | dotLayer.path = dotPath.cgPath 128 | dotLayer.strokeColor = R.Colors.active.cgColor 129 | dotLayer.lineCap = .round 130 | dotLayer.lineWidth = 10 131 | 132 | layer.addSublayer(dotLayer) 133 | } 134 | } 135 | 136 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/ChartsViews/Views/XAxisView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XAxisView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class XAxisView: BaseView { 11 | 12 | private let stackView: UIStackView = { 13 | let view = UIStackView() 14 | view.distribution = .equalSpacing 15 | return view 16 | }() 17 | 18 | func configure(with data: [BaseChartsView.Data]) { 19 | stackView.arrangedSubviews.forEach { 20 | $0.removeFromSuperview() 21 | } 22 | data.reversed().forEach { 23 | let lable = UILabel() 24 | lable.font = R.Fonts.helvelticaRegular(with: 9) 25 | lable.textColor = R.Colors.inactive 26 | lable.textAlignment = .center 27 | //lable.textAlignment = .center 28 | lable.text = $0.title.uppercased() //TODO: Remake calculated interval 29 | 30 | stackView.addArrangedSubview(lable) 31 | } 32 | } 33 | 34 | } 35 | 36 | extension XAxisView { 37 | 38 | override func setupViews() { 39 | super.setupViews() 40 | 41 | setupView(stackView) 42 | 43 | } 44 | 45 | override func constaintViews() { 46 | super.constaintViews() 47 | 48 | NSLayoutConstraint.activate([ 49 | 50 | stackView.topAnchor.constraint(equalTo: topAnchor), 51 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor), 52 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor), 53 | stackView.leadingAnchor.constraint(equalTo: leadingAnchor) 54 | ]) 55 | } 56 | 57 | override func configureAppearance() { 58 | super.configureAppearance() 59 | 60 | backgroundColor = .clear 61 | } 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /Sport Kit Interface/Base/Views/ChartsViews/Views/YAxisView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XAxisView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class YAxisView: BaseView { 11 | 12 | private let stackView: UIStackView = { 13 | let view = UIStackView() 14 | view.axis = .vertical 15 | view.distribution = .equalSpacing 16 | return view 17 | }() 18 | 19 | func configure(with data: [BaseChartsView.Data]) { 20 | stackView.arrangedSubviews.forEach { 21 | $0.removeFromSuperview() 22 | } 23 | (0...9).reversed().forEach { 24 | let lable = UILabel() 25 | lable.font = R.Fonts.helvelticaRegular(with: 9) 26 | lable.textColor = R.Colors.inactive 27 | lable.textAlignment = .right 28 | lable.text = "\($0 * 10)" //TODO: Remake calculated interval 29 | 30 | stackView.addArrangedSubview(lable) 31 | } 32 | } 33 | 34 | } 35 | 36 | extension YAxisView { 37 | 38 | override func setupViews() { 39 | super.setupViews() 40 | 41 | setupView(stackView) 42 | 43 | } 44 | 45 | override func constaintViews() { 46 | super.constaintViews() 47 | 48 | NSLayoutConstraint.activate([ 49 | 50 | stackView.topAnchor.constraint(equalTo: topAnchor), 51 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor), 52 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor), 53 | stackView.leadingAnchor.constraint(equalTo: leadingAnchor) 54 | ]) 55 | } 56 | 57 | override func configureAppearance() { 58 | super.configureAppearance() 59 | 60 | backgroundColor = .clear 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/OverviewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OverviewController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 10.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | import UIKit 11 | 12 | struct TraningData { 13 | struct Data { 14 | let title: String 15 | let subtitle: String 16 | let isDone: Bool 17 | } 18 | 19 | let date: Date 20 | let items: [Data] 21 | } 22 | 23 | class OverviewController: BaseController { 24 | 25 | private let navBar = OverviewNavBar() 26 | 27 | private var dataSource: [TraningData] = [] 28 | 29 | private let collectionView: UICollectionView = { 30 | let layout = UICollectionViewFlowLayout() 31 | layout.minimumLineSpacing = 0 32 | 33 | let view = UICollectionView(frame: .zero, collectionViewLayout: layout) 34 | view.showsVerticalScrollIndicator = false 35 | view.backgroundColor = .clear 36 | 37 | return view 38 | }() 39 | } 40 | 41 | extension OverviewController { 42 | override func setupViews() { 43 | super.setupViews() 44 | 45 | view.setupView(navBar) 46 | view.setupView(collectionView) 47 | } 48 | 49 | override func constaintViews() { 50 | super.constaintViews() 51 | 52 | NSLayoutConstraint.activate([ 53 | navBar.topAnchor.constraint(equalTo: view.topAnchor), 54 | navBar.leadingAnchor.constraint(equalTo: view.leadingAnchor), 55 | navBar.trailingAnchor.constraint(equalTo: view.trailingAnchor), 56 | 57 | collectionView.topAnchor.constraint(equalTo: navBar.bottomAnchor), 58 | collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16), 59 | collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16), 60 | collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 61 | ]) 62 | } 63 | 64 | override func configureAppearance() { 65 | super.configureAppearance() 66 | 67 | navigationController?.navigationBar.isHidden = true 68 | 69 | collectionView.register(TrainingCellView.self, forCellWithReuseIdentifier: TrainingCellView.id) 70 | collectionView.register(SectionHeaderView.self, 71 | forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, 72 | withReuseIdentifier: SectionHeaderView.id) 73 | 74 | collectionView.delegate = self 75 | collectionView.dataSource = self 76 | 77 | dataSource = [ 78 | .init(date: Date(), 79 | items: [ 80 | .init(title: "Warm Up Cardio", subtitle: "Stair Climber • 10 minutes", isDone: true), 81 | .init(title: "High Intensity Cardio", subtitle: "Treadmill • 50 minutes", isDone: false), 82 | ]), 83 | .init(date: Date(), 84 | items: [ 85 | .init(title: "Warm Up Cardio", subtitle: "Stair Climber • 10 minutes", isDone: false), 86 | .init(title: "Chest Workout", subtitle: "Bench Press • 3 sets • 10 reps", isDone: false), 87 | .init(title: "Tricep Workout", subtitle: "Overhead Extension • 5 sets • 8 reps", isDone: false), 88 | ]), 89 | .init(date: Date(), 90 | items: [ 91 | .init(title: "Cardio Interval Workout", subtitle: "Treadmill • 60 minutes", isDone: false), 92 | ]) 93 | ] 94 | collectionView.reloadData() 95 | } 96 | } 97 | 98 | // MARK: - UICollectionViewDataSource 99 | extension OverviewController: UICollectionViewDataSource { 100 | func numberOfSections(in collectionView: UICollectionView) -> Int { 101 | dataSource.count 102 | } 103 | 104 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 105 | dataSource[section].items.count 106 | } 107 | 108 | func collectionView(_ collectionView: UICollectionView, 109 | cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 110 | guard let cell = collectionView.dequeueReusableCell( 111 | withReuseIdentifier: TrainingCellView.id, for: indexPath 112 | ) as? TrainingCellView else { return UICollectionViewCell() } 113 | 114 | let item = dataSource[indexPath.section].items[indexPath.row] 115 | 116 | let roundedType: CellRoundedType 117 | if indexPath.row == 0 && indexPath.row == dataSource[indexPath.section].items.count - 1 { 118 | roundedType = .all 119 | } else if indexPath.row == 0 { 120 | roundedType = .top 121 | } else if indexPath.row == dataSource[indexPath.section].items.count - 1 { 122 | roundedType = .bottom 123 | } else { 124 | roundedType = .notRounded 125 | } 126 | 127 | cell.configure(with: item.title, subtitle: item.subtitle, isDone: item.isDone, roundedType: roundedType) 128 | return cell 129 | } 130 | 131 | func collectionView(_ collectionView: UICollectionView, 132 | viewForSupplementaryElementOfKind kind: String, 133 | at indexPath: IndexPath) -> UICollectionReusableView { 134 | guard let view = collectionView.dequeueReusableSupplementaryView( 135 | ofKind: kind, withReuseIdentifier: SectionHeaderView.id, for: indexPath 136 | ) as? SectionHeaderView else { return UICollectionReusableView() } 137 | 138 | view.configure(with: dataSource[indexPath.section].date) 139 | return view 140 | } 141 | } 142 | 143 | // MARK: - UICollectionViewDelegateFlowLayout 144 | extension OverviewController: UICollectionViewDelegateFlowLayout { 145 | func collectionView(_ collectionView: UICollectionView, 146 | layout collectionViewLayout: UICollectionViewLayout, 147 | sizeForItemAt indexPath: IndexPath) -> CGSize { 148 | CGSize(width: collectionView.frame.width, height: 70) 149 | } 150 | 151 | func collectionView(_ collectionView: UICollectionView, 152 | layout collectionViewLayout: UICollectionViewLayout, 153 | referenceSizeForHeaderInSection section: Int) -> CGSize { 154 | CGSize(width: collectionView.frame.width, height: 32) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/Views/CollectionView/Views/SectionHeaderView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SectionHeaderView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 02.03.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | final class SectionHeaderView: UICollectionReusableView { 11 | static let id = "SectionHeaderView" 12 | 13 | private let title: UILabel = { 14 | let lable = UILabel() 15 | lable.font = R.Fonts.helvelticaRegular(with: 13) 16 | lable.textColor = R.Colors.inactive 17 | lable.textAlignment = .center 18 | return lable 19 | }() 20 | 21 | override init(frame: CGRect) { 22 | super.init(frame: frame) 23 | 24 | setupViews() 25 | constaintViews() 26 | configureAppearance() 27 | } 28 | 29 | required init?(coder: NSCoder) { 30 | super.init(frame: .zero) 31 | 32 | setupViews() 33 | constaintViews() 34 | configureAppearance() 35 | } 36 | 37 | func configure(with date: Date) { 38 | let dateFormatter = DateFormatter() 39 | dateFormatter.dateFormat = "EEEE, MMMM dd" 40 | 41 | self.title.text = dateFormatter.string(from: date).uppercased() 42 | } 43 | } 44 | 45 | private extension SectionHeaderView { 46 | func setupViews() { 47 | setupView(title) 48 | } 49 | 50 | func constaintViews() { 51 | NSLayoutConstraint.activate([ 52 | title.centerXAnchor.constraint(equalTo: centerXAnchor), 53 | title.centerYAnchor.constraint(equalTo: centerYAnchor) 54 | ]) 55 | } 56 | 57 | func configureAppearance() {} 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/Views/OverviewNavBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OverviewNavBar.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 18.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | final class OverviewNavBar: BaseView { 12 | 13 | private let titleLable: UILabel = { 14 | let lable = UILabel() 15 | lable.text = R.Strings.NavBar.overview 16 | lable.textColor = R.Colors.titleGray 17 | lable.font = R.Fonts.helvelticaRegular(with: 22) 18 | return lable 19 | }() 20 | 21 | private let addButton = UIButton() 22 | private let allWorkoutsButton: BaseButton = { 23 | let button = BaseButton(with: .secondary) 24 | button.setTitle(R.Strings.Overview.allWorcoutsButton) 25 | return button 26 | }() 27 | 28 | private var weekView = WeekView() 29 | 30 | 31 | override func layoutSubviews() { 32 | super.layoutSubviews() 33 | 34 | //Addig for all subviews! 35 | addBottomBorder(with: R.Colors.separator, height: 1) 36 | } 37 | 38 | func addAllWorkoutsAction(_ action: Selector, with target: Any?) { 39 | allWorkoutsButton.addTarget(target, action: action, for: .touchUpInside) 40 | } 41 | 42 | func addButtonAction(_ action: Selector, with target: Any?) { 43 | addButton.addTarget(target, action: action, for: .touchUpInside) 44 | } 45 | } 46 | 47 | extension OverviewNavBar { 48 | 49 | 50 | 51 | override func setupViews() { 52 | super.setupViews() 53 | 54 | setupView(allWorkoutsButton) 55 | setupView(titleLable) 56 | setupView(addButton) 57 | 58 | setupView(weekView) 59 | } 60 | 61 | override func constaintViews() { 62 | super.constaintViews() 63 | 64 | NSLayoutConstraint.activate([ 65 | //Верхняя грань 66 | addButton.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 8), 67 | //Оцтуп справа 68 | addButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -15), 69 | //Высота 70 | addButton.heightAnchor.constraint(equalToConstant: 28), 71 | //Ширина 72 | addButton.widthAnchor.constraint(equalToConstant: 28), 73 | 74 | allWorkoutsButton.topAnchor.constraint(equalTo: addButton.topAnchor), 75 | allWorkoutsButton.trailingAnchor.constraint(equalTo: addButton.leadingAnchor, constant: -15), 76 | allWorkoutsButton.heightAnchor.constraint(equalToConstant: 28), 77 | allWorkoutsButton.widthAnchor.constraint(equalToConstant: 130), 78 | 79 | titleLable.centerYAnchor.constraint(equalTo: addButton.centerYAnchor), 80 | titleLable.trailingAnchor.constraint(equalTo: addButton.leadingAnchor), 81 | titleLable.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15), 82 | 83 | weekView.topAnchor.constraint(equalTo: addButton.bottomAnchor, constant: 15), 84 | weekView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15), 85 | weekView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -15), 86 | weekView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -15), 87 | weekView.heightAnchor.constraint(equalToConstant: 47) 88 | ]) 89 | } 90 | 91 | override func configureAppearance() { 92 | super.configureAppearance() 93 | 94 | backgroundColor = .white 95 | 96 | // titleLable.text = R.Strings.Overview.navBarLable 97 | // titleLable.textColor = R.Colors.titleGrey 98 | // titleLable.font = R.Fonts.helveticaRegular(with: 22) 99 | 100 | allWorkoutsButton.setTitle(R.Strings.Overview.allWorcoutsButton) 101 | 102 | addButton.setImage(R.Images.Common.add, for: .normal) 103 | 104 | 105 | } 106 | } 107 | 108 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/Views/TrainingCellView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TrainingCellView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 19.03.2023. 6 | // 7 | 8 | import UIKit 9 | 10 | enum CellRoundedType { 11 | case top, bottom, all, notRounded 12 | } 13 | 14 | final class TrainingCellView: UICollectionViewCell { 15 | static let id = "TrainingCellView" 16 | 17 | private let checkmarkView = UIImageView(image: R.Images.Overview.checkmarkNotDone) 18 | 19 | private let stackView: UIStackView = { 20 | let view = UIStackView() 21 | view.axis = .vertical 22 | view.spacing = 3 23 | return view 24 | }() 25 | 26 | private let title: UILabel = { 27 | let lable = UILabel() 28 | lable.font = R.Fonts.helvelticaRegular(with: 17) 29 | lable.textColor = R.Colors.titleGray 30 | return lable 31 | }() 32 | 33 | private let subtitle: UILabel = { 34 | let lable = UILabel() 35 | lable.font = R.Fonts.helvelticaRegular(with: 13) 36 | lable.textColor = R.Colors.inactive 37 | return lable 38 | }() 39 | 40 | private let rightArrowView = UIImageView(image: R.Images.Overview.rightArrow) 41 | 42 | override init(frame: CGRect) { 43 | super.init(frame: frame) 44 | 45 | setupViews() 46 | constaintViews() 47 | configureAppearance() 48 | } 49 | 50 | required init?(coder: NSCoder) { 51 | super.init(frame: .zero) 52 | 53 | setupViews() 54 | constaintViews() 55 | configureAppearance() 56 | } 57 | 58 | func configure(with title: String, subtitle: String, isDone: Bool, roundedType: CellRoundedType) { 59 | self.title.text = title 60 | self.subtitle.text = subtitle 61 | 62 | checkmarkView.image = isDone ? R.Images.Overview.checkmarkDone : R.Images.Overview.checkmarkNotDone 63 | 64 | switch roundedType { 65 | case .all: self.roundCorners([.allCorners], radius: 5) 66 | case .bottom: self.roundCorners([.bottomLeft, .bottomRight], radius: 5) 67 | case .top: self.roundCorners([.topLeft, .topRight], radius: 5) 68 | case .notRounded: self.roundCorners([.allCorners], radius: 0) 69 | } 70 | } 71 | } 72 | 73 | private extension TrainingCellView { 74 | func setupViews() { 75 | setupView(checkmarkView) 76 | setupView(stackView) 77 | stackView.addArrangedSubview(title) 78 | stackView.addArrangedSubview(subtitle) 79 | setupView(rightArrowView) 80 | } 81 | 82 | func constaintViews() { 83 | NSLayoutConstraint.activate([ 84 | checkmarkView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15), 85 | checkmarkView.centerYAnchor.constraint(equalTo: centerYAnchor), 86 | checkmarkView.heightAnchor.constraint(equalToConstant: 28), 87 | checkmarkView.widthAnchor.constraint(equalTo: checkmarkView.heightAnchor), 88 | 89 | stackView.leadingAnchor.constraint(equalTo: checkmarkView.trailingAnchor, constant: 15), 90 | stackView.centerYAnchor.constraint(equalTo: centerYAnchor), 91 | stackView.trailingAnchor.constraint(equalTo: rightArrowView.leadingAnchor, constant: -15), 92 | 93 | rightArrowView.centerYAnchor.constraint(equalTo: centerYAnchor), 94 | rightArrowView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -15), 95 | rightArrowView.heightAnchor.constraint(equalToConstant: 12), 96 | rightArrowView.widthAnchor.constraint(equalToConstant: 7), 97 | ]) 98 | } 99 | 100 | func configureAppearance() { 101 | backgroundColor = .white 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/Views/WeekView/WeekDayView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeekDayView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 20.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension WeekView { 11 | final class WeekDaysView: BaseView { 12 | 13 | private let nameLabel = UILabel() 14 | private let dateLabel = UILabel() 15 | private let stackView = UIStackView() 16 | 17 | func configure(with index: Int, and name: String) { 18 | 19 | let startOfWeekDate = Date().startOfWeek 20 | let currentDay = startOfWeekDate.agoForward(to: index) 21 | let day = Calendar.current.component(.day, from: currentDay) 22 | 23 | let isTooday = currentDay.strioTime() == Date().strioTime() 24 | 25 | backgroundColor = isTooday ? R.Colors.active : R.Colors.background 26 | 27 | nameLabel.text = name.uppercased() 28 | nameLabel.textColor = isTooday ? .white : R.Colors.inactive 29 | 30 | 31 | dateLabel.text = "\(day)" 32 | dateLabel.textColor = isTooday ? .white : R.Colors.inactive 33 | } 34 | 35 | } 36 | } 37 | 38 | extension WeekView.WeekDaysView { 39 | 40 | override func setupViews(){ 41 | super.setupViews() 42 | 43 | setupView(stackView) 44 | 45 | stackView.addArrangedSubview(nameLabel) 46 | stackView.addArrangedSubview(dateLabel) 47 | 48 | } 49 | 50 | override func constaintViews() { 51 | super.constaintViews() 52 | NSLayoutConstraint.activate([ 53 | 54 | stackView.centerXAnchor.constraint(equalTo: centerXAnchor), 55 | stackView.centerYAnchor.constraint(equalTo: centerYAnchor) 56 | 57 | ]) 58 | } 59 | 60 | override func configureAppearance() { 61 | super.configureAppearance() 62 | 63 | layer.cornerRadius = 5 64 | layer.masksToBounds = true 65 | 66 | nameLabel.font = R.Fonts.helvelticaRegular(with: 9) 67 | nameLabel.textAlignment = .center 68 | 69 | dateLabel.font = R.Fonts.helvelticaRegular(with: 15) 70 | dateLabel.textAlignment = .center 71 | 72 | stackView.spacing = 3 73 | stackView.axis = .vertical 74 | } 75 | } 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Overview/Views/WeekView/WeekView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WeekView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 20.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class WeekView: BaseView { 11 | 12 | private let calendar = Calendar.current 13 | 14 | private let stackView = UIStackView() 15 | 16 | } 17 | 18 | 19 | extension WeekView { 20 | 21 | override func setupViews(){ 22 | super.setupViews() 23 | 24 | setupView(stackView) 25 | } 26 | 27 | override func constaintViews() { 28 | super.constaintViews() 29 | NSLayoutConstraint.activate([ 30 | stackView.topAnchor.constraint(equalTo: topAnchor), 31 | stackView.leadingAnchor.constraint(equalTo: leadingAnchor), 32 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor), 33 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor) 34 | ]) 35 | } 36 | 37 | override func configureAppearance() { 38 | super.configureAppearance() 39 | 40 | stackView.spacing = 7 41 | stackView.distribution = .fillEqually 42 | 43 | //Настройка календаря 44 | var weekdays = calendar.shortStandaloneWeekdaySymbols 45 | 46 | // Переносим Sunday с первого на последнее место 47 | if calendar.firstWeekday == 1 { 48 | let sun = weekdays.remove(at: 0) 49 | weekdays.append(sun) 50 | } 51 | 52 | // Добавляем WeekDayView 53 | 54 | weekdays.enumerated().forEach {index, name in 55 | 56 | let view = WeekDaysView() 57 | view.configure(with: index, and: name) 58 | 59 | stackView.addArrangedSubview(view) 60 | 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Progress/ProgressController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class ProgressController: BaseController { 11 | 12 | private let dailyPerformanceView = DailyPerformanceView(with: R.Strings.Progress.dailyPerformance, 13 | buttonTitle: R.Strings.Progress.last7Days) 14 | private let monthlyPerformanceView = MonthlyPerformanceView(with: R.Strings.Progress.monthlyPerformance, 15 | buttonTitle: R.Strings.Progress.last10Month) 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | 20 | title = R.Strings.NavBar.progress 21 | navigationController?.tabBarItem.title = R.Strings.TabBar.title(for: .progress) 22 | 23 | addNavBarButton(at: .Left, with: "Export") 24 | addNavBarButton(at: .Right, with: "Finish") 25 | } 26 | 27 | } 28 | 29 | extension ProgressController { 30 | 31 | override func setupViews() { 32 | super.setupViews() 33 | 34 | view.setupView(dailyPerformanceView) 35 | view.setupView(monthlyPerformanceView) 36 | } 37 | 38 | override func configureAppearance() { 39 | super.configureAppearance() 40 | } 41 | 42 | 43 | 44 | override func constaintViews() { 45 | super.constaintViews() 46 | 47 | NSLayoutConstraint.activate([ 48 | dailyPerformanceView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15), 49 | dailyPerformanceView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 15), 50 | dailyPerformanceView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15), 51 | dailyPerformanceView.heightAnchor.constraint(equalTo: dailyPerformanceView.widthAnchor, multiplier: 0.68), 52 | 53 | monthlyPerformanceView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15), 54 | monthlyPerformanceView.topAnchor.constraint(equalTo: dailyPerformanceView.bottomAnchor, constant: 15), 55 | monthlyPerformanceView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15), 56 | monthlyPerformanceView.heightAnchor.constraint(equalTo: monthlyPerformanceView.widthAnchor, multiplier: 1.06), 57 | ]) 58 | 59 | dailyPerformanceView.configure(with: [.init(value: "1", heigntMultiplier: 0.25, title: "Mon"), 60 | .init(value: "2", heigntMultiplier: 0.4, title: "Teu"), 61 | .init(value: "3", heigntMultiplier: 0.6, title: "Wen"), 62 | .init(value: "4", heigntMultiplier: 0.8, title: "Thu"), 63 | .init(value: "5", heigntMultiplier: 1, title: "Fri"), 64 | .init(value: "6", heigntMultiplier: 0.6, title: "Sat"), 65 | .init(value: "7", heigntMultiplier: 0.4, title: "Sun")]) 66 | 67 | monthlyPerformanceView.configure(with: [.init(value: 45, title: "Mar"), 68 | .init(value: 55, title: "Apr"), 69 | .init(value: 60, title: "May"), 70 | .init(value: 65, title: "Jun"), 71 | .init(value: 70, title: "Jul"), 72 | .init(value: 80, title: "Aug"), 73 | .init(value: 65, title: "Sep"), 74 | .init(value: 45, title: "Okt"), 75 | .init(value: 30, title: "Nov"), 76 | .init(value: 15, title: "Dec")] 77 | , topChartOffset: 10) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Progress/Views/MonthlyPerformanceView/MonthlyPerformanceView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MonthlyPerformanceView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 14.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class MonthlyPerformanceView: BaseInfoView { 11 | 12 | private let chartsView = BaseChartsView() 13 | 14 | func configure(with items: [BaseChartsView.Data], topChartOffset: Int) { 15 | chartsView.configureX(with: items, topChartOffset: topChartOffset) 16 | } 17 | } 18 | 19 | extension MonthlyPerformanceView { 20 | 21 | override func setupViews() { 22 | super.setupViews() 23 | 24 | setupView(chartsView) 25 | } 26 | 27 | override func constaintViews(){ 28 | super.constaintViews() 29 | 30 | NSLayoutConstraint.activate([ 31 | chartsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 15), 32 | chartsView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15), 33 | chartsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15), 34 | chartsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -15), 35 | ]) 36 | } 37 | 38 | override func configureAppearance(){ 39 | super.configureAppearance() 40 | 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Progress/Views/Performance/DailyPerformanceView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DailyPerformanceView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 11.12.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class DailyPerformanceView: BaseInfoView { 11 | 12 | private let barsView = BaseBarsView() 13 | 14 | func configure(with items: [BaseBarView.Data]) { 15 | barsView.configureX(with: items) 16 | } 17 | } 18 | 19 | extension DailyPerformanceView { 20 | 21 | override func setupViews() { 22 | super.setupViews() 23 | 24 | setupView(barsView) 25 | } 26 | 27 | override func constaintViews(){ 28 | super.constaintViews() 29 | 30 | NSLayoutConstraint.activate([ 31 | barsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 15), 32 | barsView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10), 33 | barsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10), 34 | barsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -15), 35 | ]) 36 | } 37 | 38 | override func configureAppearance(){ 39 | super.configureAppearance() 40 | } 41 | } 42 | 43 | //test commit 44 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/SessionController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SessionController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class SessionController: BaseController { 11 | private let timerView = TimerView() 12 | private let statsView = StatsView(with: R.Strings.Session.workoutStats) 13 | private let stepsView = StepsView(with: R.Strings.Session.stepsCounter) 14 | 15 | private let timerDuration = 5.0 16 | 17 | override func navBarLeftButtonHandler() { 18 | if timerView.state == .isStopped { 19 | timerView.startTimer() 20 | } else { 21 | timerView.pauseTimer() 22 | } 23 | 24 | timerView.state = timerView.state == .isRuning ? .isStopped : .isRuning 25 | addNavBarButton( 26 | at: .Left, 27 | with: timerView.state == .isRuning 28 | ? R.Strings.Session.navBarPause : R.Strings.Session.navBarStart 29 | ) 30 | } 31 | 32 | override func navBarRightButtonHanler() { 33 | timerView.stopTimer() 34 | timerView.state = .isStopped 35 | 36 | addNavBarButton(at: .Left, with: R.Strings.Session.navBarStart) 37 | } 38 | } 39 | 40 | extension SessionController { 41 | override func setupViews() { 42 | super.setupViews() 43 | 44 | view.setupView(timerView) 45 | view.setupView(statsView) 46 | view.setupView(stepsView) 47 | } 48 | 49 | override func constaintViews() { 50 | super.constaintViews() 51 | 52 | NSLayoutConstraint.activate([ 53 | timerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15), 54 | timerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 15), 55 | timerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15), 56 | 57 | statsView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 15), 58 | statsView.topAnchor.constraint(equalTo: timerView.bottomAnchor, constant: 10), 59 | statsView.trailingAnchor.constraint(equalTo: view.centerXAnchor, constant: -7.5), 60 | 61 | stepsView.leadingAnchor.constraint(equalTo: view.centerXAnchor, constant: 7.5), 62 | stepsView.topAnchor.constraint(equalTo: statsView.topAnchor), 63 | stepsView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -15), 64 | stepsView.heightAnchor.constraint(equalTo: statsView.heightAnchor), 65 | ]) 66 | } 67 | 68 | 69 | override func configureAppearance() { 70 | super.configureAppearance() 71 | 72 | title = R.Strings.NavBar.session 73 | navigationController?.tabBarItem.title = R.Strings.TabBar.title(for: .session) 74 | 75 | addNavBarButton(at: .Left, with: R.Strings.Session.navBarStart) 76 | addNavBarButton(at: .Right, with: R.Strings.Session.navBarFinish) 77 | 78 | timerView.configure(with: timerDuration, progress: 0) 79 | 80 | timerView.callBack = { 81 | DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { 82 | self.navBarRightButtonHanler() 83 | } 84 | } 85 | 86 | // timerView.callBack = { [weak self] in 87 | // self?.navBarRightButtonHandler() 88 | // } 89 | 90 | 91 | stepsView.configure(with: [.init(value: "8k", heigntMultiplier: 1, title: "2/14"), 92 | .init(value: "7k", heigntMultiplier: 0.8, title: "2/15"), 93 | .init(value: "5k", heigntMultiplier: 0.6, title: "2/16"), 94 | .init(value: "6k", heigntMultiplier: 0.7, title: "2/17"),]) 95 | 96 | statsView.configure(with: [.heartRate(value: "155"), 97 | .averagePace(value: "8'20''"), 98 | .totalSteps(value: "7,682"), 99 | .totalDistance(value: "8.25")]) 100 | 101 | 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Stats/StatsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatsView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 30.10.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | class StatsView: BaseInfoView { 11 | 12 | private let stackView: UIStackView = { 13 | let view = UIStackView() 14 | view.axis = .vertical 15 | view.spacing = 15 16 | 17 | return view 18 | }() 19 | 20 | 21 | 22 | // Configurator 23 | func configure(with itmes: [StatsItem]) { 24 | itmes.forEach { 25 | let itmeView = StatsItemView() 26 | itmeView.configure(with: $0) 27 | stackView.addArrangedSubview(itmeView) 28 | } 29 | } 30 | } 31 | 32 | 33 | extension StatsView { 34 | override func setupViews() { 35 | super.setupViews() 36 | 37 | setupView(stackView) 38 | } 39 | 40 | override func constaintViews(){ 41 | super.constaintViews() 42 | 43 | NSLayoutConstraint.activate([ 44 | stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 15), 45 | stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 15), 46 | stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -15), 47 | stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -15), 48 | ]) 49 | } 50 | 51 | override func configureAppearance(){ 52 | super.configureAppearance() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Stats/Views/StatsItemView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StatItemView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 30.10.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum StatsItem { 11 | case averagePace(value: String) 12 | case heartRate(value: String) 13 | case totalDistance(value: String) 14 | case totalSteps(value: String) 15 | 16 | var data: StatsItemView.ItemData { 17 | switch self { 18 | case .averagePace(let value): 19 | return .init(image: R.Images.Session.Stats.pace, 20 | value: value + " / km", 21 | title: R.Strings.Session.averagePace) 22 | case .heartRate(let value): 23 | return .init(image: R.Images.Session.Stats.heartRate, 24 | value: value + " bpm", 25 | title: R.Strings.Session.heartRate) 26 | case .totalDistance(let value): 27 | return .init(image: R.Images.Session.Stats.distance, 28 | value: value + " km", 29 | title: R.Strings.Session.totalDistance) 30 | case .totalSteps(let value): 31 | return .init(image: R.Images.Session.Stats.steps, 32 | value: value, 33 | title: R.Strings.Session.totalSteps) 34 | } 35 | } 36 | } 37 | class StatsItemView: BaseView { 38 | 39 | // CONFIGURE STRUC 40 | struct ItemData { 41 | let image: UIImage? 42 | let value: String 43 | let title: String 44 | } 45 | 46 | private let imageView = UIImageView() 47 | 48 | private let valueLabel: UILabel = { 49 | let label = UILabel() 50 | label.font = R.Fonts.helvelticaRegular(with: 17) 51 | label.textColor = R.Colors.titleGray 52 | return label 53 | }() 54 | 55 | private let titleLabel: UILabel = { 56 | let label = UILabel() 57 | label.font = R.Fonts.helvelticaRegular(with: 10) 58 | label.textColor = R.Colors.inactive 59 | return label 60 | }() 61 | 62 | private let stackView: UIStackView = { 63 | let viev = UIStackView() 64 | viev.axis = .vertical 65 | return viev 66 | }() 67 | 68 | 69 | // CONFIGURE FUNC 70 | func configure(with item: StatsItem) { 71 | imageView.image = item.data.image 72 | valueLabel.text = item.data.value 73 | titleLabel.text = item.data.title.uppercased() 74 | } 75 | } 76 | 77 | extension StatsItemView { 78 | override func setupViews(){ 79 | super.setupViews() 80 | 81 | setupView(imageView) 82 | setupView(stackView) 83 | stackView.addArrangedSubview(valueLabel) 84 | stackView.addArrangedSubview(titleLabel) 85 | } 86 | 87 | override func constaintViews(){ 88 | super.constaintViews() 89 | 90 | NSLayoutConstraint.activate([ 91 | imageView.centerYAnchor.constraint(equalTo: centerYAnchor), 92 | imageView.leadingAnchor.constraint(equalTo: leadingAnchor), 93 | imageView.widthAnchor.constraint(equalToConstant: 23), 94 | 95 | stackView.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 15), 96 | stackView.topAnchor.constraint(equalTo: topAnchor), 97 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor), 98 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor) 99 | ]) 100 | } 101 | 102 | override func configureAppearance(){ 103 | super.configureAppearance() 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Steps/StepsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StepsView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 30.10.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class StepsView: BaseInfoView { 11 | 12 | private let barsView = BaseBarsView() 13 | 14 | 15 | func configure(with items: [BaseBarView.Data]) { 16 | barsView.configureX(with: items) 17 | } 18 | } 19 | 20 | 21 | 22 | extension StepsView { 23 | 24 | override func setupViews() { 25 | super.setupViews() 26 | 27 | setupView(barsView) 28 | } 29 | 30 | override func constaintViews(){ 31 | super.constaintViews() 32 | 33 | NSLayoutConstraint.activate([ 34 | barsView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 15), 35 | barsView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10), 36 | barsView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10), 37 | barsView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -15), 38 | ]) 39 | } 40 | 41 | override func configureAppearance(){ 42 | super.configureAppearance() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Timer/PercentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PercentView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 19.09.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension TimerView { 11 | 12 | final class PercentView: BaseView { 13 | 14 | private let stackView: UIStackView = { 15 | let view = UIStackView() 16 | view.axis = .vertical 17 | view.distribution = .fillProportionally 18 | view.spacing = 5 19 | return view 20 | }() 21 | 22 | private let percentLabel: UILabel = { 23 | let label = UILabel() 24 | label.font = R.Fonts.helvelticaRegular(with: 23) 25 | label.textColor = R.Colors.titleGray 26 | label.textAlignment = .center 27 | return label 28 | }() 29 | 30 | private let subtitleLabel: UILabel = { 31 | let label = UILabel() 32 | label.font = R.Fonts.helvelticaRegular(with: 10) 33 | label.textColor = R.Colors.inactive 34 | label.textAlignment = .center 35 | return label 36 | }() 37 | 38 | 39 | 40 | override func setupViews() { 41 | super.setupViews() 42 | setupView(stackView) 43 | stackView.addArrangedSubview(percentLabel) 44 | stackView.addArrangedSubview(subtitleLabel) 45 | } 46 | override func constaintViews() { 47 | super.constaintViews() 48 | 49 | NSLayoutConstraint.activate([ 50 | stackView.leadingAnchor.constraint(equalTo: leadingAnchor), 51 | stackView.topAnchor.constraint(equalTo: topAnchor), 52 | stackView.trailingAnchor.constraint(equalTo: trailingAnchor), 53 | stackView.bottomAnchor.constraint(equalTo: bottomAnchor) 54 | ]) 55 | } 56 | 57 | func configure(with title: String, andValue value: Int) { 58 | subtitleLabel.text = title 59 | percentLabel.text = "\(value)%" 60 | } 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Timer/ProgressView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ProgressView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 27.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | 11 | extension TimerView { 12 | final class ProgressView: UIView { 13 | func drawProgress(with percent: CGFloat) { 14 | layer.sublayers?.removeAll() 15 | 16 | let circleFrame = UIScreen.main.bounds.width - (15 + 40) * 2 17 | let radius = circleFrame / 2 18 | let center = CGPoint(x: radius, y: radius) 19 | let startAngle = -CGFloat.pi * 7 / 6 20 | let endAngle = CGFloat.pi * 1 / 6 21 | 22 | let circlePath = UIBezierPath(arcCenter: center, 23 | radius: radius, 24 | startAngle: startAngle, 25 | endAngle: endAngle, 26 | clockwise: true) 27 | 28 | let defaultCircleLayer = CAShapeLayer() 29 | defaultCircleLayer.path = circlePath.cgPath 30 | defaultCircleLayer.strokeColor = R.Colors.separator.cgColor 31 | defaultCircleLayer.lineWidth = 20 32 | defaultCircleLayer.strokeEnd = 1 33 | defaultCircleLayer.fillColor = UIColor.clear.cgColor 34 | defaultCircleLayer.lineCap = .round 35 | 36 | let circleLayer = CAShapeLayer() 37 | circleLayer.path = circlePath.cgPath 38 | circleLayer.strokeColor = R.Colors.active.cgColor 39 | circleLayer.lineWidth = 20 40 | circleLayer.strokeEnd = percent 41 | circleLayer.fillColor = UIColor.clear.cgColor 42 | circleLayer.lineCap = .round 43 | 44 | let dotAngle = CGFloat.pi * (7 / 6 - (8 / 6 * percent)) 45 | let dotPoint = CGPoint(x: cos(-dotAngle) * radius + center.x, 46 | y: sin(-dotAngle) * radius + center.y) 47 | 48 | let dotPath = UIBezierPath() 49 | dotPath.move(to: dotPoint) 50 | dotPath.addLine(to: dotPoint) 51 | 52 | let bigDotLayer = CAShapeLayer() 53 | bigDotLayer.path = dotPath.cgPath 54 | bigDotLayer.fillColor = UIColor.clear.cgColor 55 | bigDotLayer.strokeColor = R.Colors.active.cgColor 56 | bigDotLayer.lineCap = .round 57 | bigDotLayer.lineWidth = 20 58 | 59 | let dotLayer = CAShapeLayer() 60 | dotLayer.path = dotPath.cgPath 61 | dotLayer.fillColor = UIColor.clear.cgColor 62 | dotLayer.strokeColor = UIColor.white.cgColor 63 | dotLayer.lineCap = .round 64 | dotLayer.lineWidth = 8 65 | 66 | let barsFrame = UIScreen.main.bounds.width - (15 + 40 + 25) * 2 67 | let barsRadius = barsFrame / 2 68 | 69 | let barsPath = UIBezierPath(arcCenter: center, 70 | radius: barsRadius, 71 | startAngle: startAngle, 72 | endAngle: endAngle, 73 | clockwise: true) 74 | 75 | let barsLayer = CAShapeLayer() 76 | barsLayer.path = barsPath.cgPath 77 | barsLayer.fillColor = UIColor.clear.cgColor 78 | barsLayer.strokeColor = UIColor.clear.cgColor 79 | barsLayer.lineWidth = 6 80 | 81 | let startBarRadius = barsRadius - barsLayer.lineWidth * 0.5 82 | let endBarRadius = startBarRadius + 6 83 | 84 | var angle: CGFloat = 7 / 6 85 | (1...9).forEach { _ in 86 | let barAngle = CGFloat.pi * angle 87 | let startBarPoint = CGPoint( 88 | x: cos(-barAngle) * startBarRadius + center.x, 89 | y: sin(-barAngle) * startBarRadius + center.y 90 | ) 91 | 92 | let endBarPoint = CGPoint( 93 | x: cos(-barAngle) * endBarRadius + center.x, 94 | y: sin(-barAngle) * endBarRadius + center.y 95 | ) 96 | 97 | let barPath = UIBezierPath() 98 | barPath.move(to: startBarPoint) 99 | barPath.addLine(to: endBarPoint) 100 | 101 | let barLayer = CAShapeLayer() 102 | barLayer.path = barPath.cgPath 103 | barLayer.fillColor = UIColor.clear.cgColor 104 | barLayer.strokeColor = angle >= (7 / 6 - (8 / 6 * percent)) 105 | ? R.Colors.active.cgColor : R.Colors.separator.cgColor 106 | barLayer.lineCap = .round 107 | barLayer.lineWidth = 4 108 | 109 | barsLayer.addSublayer(barLayer) 110 | 111 | angle -= 1 / 6 112 | } 113 | 114 | 115 | layer.addSublayer(defaultCircleLayer) 116 | layer.addSublayer(circleLayer) 117 | layer.addSublayer(bigDotLayer) 118 | layer.addSublayer(dotLayer) 119 | layer.addSublayer(barsLayer) 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Session/Views/Timer/TimerView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimerView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 27.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum TimerState { 11 | case isRuning 12 | case isPaused 13 | case isStopped 14 | } 15 | 16 | final class TimerView: BaseInfoView { 17 | 18 | private let elapsedTimeLable: UILabel = { 19 | let lable = UILabel() 20 | lable.text = R.Strings.Session.elapsedTime 21 | lable.font = R.Fonts.helvelticaRegular(with: 14) 22 | lable.textColor = R.Colors.inactive 23 | lable.textAlignment = .center 24 | return lable 25 | }() 26 | 27 | private let elapsedTimeValueLable: UILabel = { 28 | let lable = UILabel() 29 | //lable.text = "02:15" 30 | lable.font = R.Fonts.helvelticaRegular(with: 46) 31 | lable.textColor = R.Colors.titleGray 32 | lable.textAlignment = .center 33 | return lable 34 | }() 35 | 36 | private let remainingTimeLable: UILabel = { 37 | let lable = UILabel() 38 | lable.text = R.Strings.Session.remainingTime 39 | lable.font = R.Fonts.helvelticaRegular(with: 13) 40 | lable.textColor = R.Colors.inactive 41 | lable.textAlignment = .center 42 | return lable 43 | }() 44 | 45 | private let remainingTimeValueLable: UILabel = { 46 | let lable = UILabel() 47 | //lable.text = "12:45" 48 | lable.font = R.Fonts.helvelticaRegular(with: 13) 49 | lable.textColor = R.Colors.titleGray 50 | lable.textAlignment = .center 51 | return lable 52 | }() 53 | 54 | private let timeStackView: UIStackView = { 55 | let view = UIStackView() 56 | view.axis = .vertical 57 | view.distribution = .fillProportionally 58 | view.spacing = 10 59 | return view 60 | }() 61 | 62 | private let bottomStackView: UIStackView = { 63 | let view = UIStackView() 64 | view.distribution = .fillProportionally 65 | view.spacing = 25 66 | return view 67 | }() 68 | 69 | private let completedPercentView = PercentView() 70 | private let remainingPercentView = PercentView() 71 | 72 | private let bottomSeparatorView: UIView = { 73 | let view = UIView() 74 | view.backgroundColor = R.Colors.separator 75 | return view 76 | }() 77 | 78 | private let progressView = ProgressView() 79 | 80 | 81 | 82 | private var timer = Timer() 83 | private var timerProgress: CGFloat = 0 84 | private var timerDuration = 0.0 85 | 86 | var state: TimerState = .isStopped 87 | var callBack: (() -> Void)? 88 | 89 | func configure(with duration: Double, progress: Double) { 90 | timerDuration = duration 91 | 92 | let tempCurrentValue = progress > duration ? duration : progress 93 | 94 | let goalValueDevider = duration == 0 ? 1 : duration 95 | let percent = tempCurrentValue / goalValueDevider 96 | let roundedPercent = Int(round(percent * 100)) 97 | 98 | elapsedTimeValueLable.text = getDisplayedString(from: Int(tempCurrentValue)) 99 | remainingTimeValueLable.text = getDisplayedString(from: Int(duration - tempCurrentValue)) 100 | completedPercentView.configure(with: R.Strings.Session.completed.uppercased(), andValue: roundedPercent) 101 | remainingPercentView.configure(with: R.Strings.Session.remaining.uppercased(), andValue: 100 - roundedPercent) 102 | progressView.drawProgress(with: CGFloat(percent)) 103 | } 104 | 105 | func startTimer() { 106 | timer.invalidate() 107 | 108 | 109 | timer = Timer.scheduledTimer(withTimeInterval: 0.01, 110 | repeats: true, 111 | block: { [weak self] timer in 112 | guard let self = self else { return } 113 | self.timerProgress += 0.01 114 | 115 | if self.timerProgress > self.timerDuration { 116 | self.timerProgress = self.timerDuration 117 | timer.invalidate() 118 | self.callBack?() 119 | } 120 | 121 | self.configure(with: self.timerDuration, progress: self.timerProgress) 122 | }) 123 | } 124 | 125 | func pauseTimer() { 126 | timer.invalidate() 127 | } 128 | 129 | func stopTimer() { 130 | guard self.timerProgress > 0 else { return } 131 | timer.invalidate() 132 | 133 | timer = Timer.scheduledTimer(withTimeInterval: 0.01, 134 | repeats: true, 135 | block: { [weak self] timer in 136 | guard let self = self else { return } 137 | self.timerProgress -= 0.1 138 | self.timerProgress -= self.timerDuration * 0.02 139 | 140 | if self.timerProgress <= 0 { 141 | self.timerProgress = 0 142 | timer.invalidate() 143 | } 144 | 145 | self.configure(with: self.timerDuration, progress: self.timerProgress) 146 | }) 147 | } 148 | } 149 | 150 | extension TimerView { 151 | override func setupViews() { 152 | super.setupViews() 153 | 154 | setupView(progressView) 155 | setupView(timeStackView) 156 | setupView(bottomStackView) 157 | 158 | [ 159 | elapsedTimeLable, 160 | elapsedTimeValueLable, 161 | remainingTimeLable, 162 | remainingTimeValueLable 163 | ].forEach(timeStackView.addArrangedSubview) 164 | 165 | [ 166 | completedPercentView, 167 | bottomSeparatorView, 168 | remainingPercentView, 169 | ].forEach(bottomStackView.addArrangedSubview) 170 | 171 | 172 | } 173 | 174 | override func constaintViews() { 175 | super.constaintViews() 176 | 177 | NSLayoutConstraint.activate([ 178 | progressView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 40), 179 | progressView.topAnchor.constraint(equalTo: topAnchor, constant: 40), 180 | progressView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -40), 181 | progressView.heightAnchor.constraint(equalTo: progressView.widthAnchor), 182 | progressView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -40), 183 | 184 | timeStackView.centerYAnchor.constraint(equalTo: progressView.centerYAnchor), 185 | timeStackView.centerXAnchor.constraint(equalTo: progressView.centerXAnchor), 186 | 187 | bottomStackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -28), 188 | bottomStackView.centerXAnchor.constraint(equalTo: centerXAnchor), 189 | bottomStackView.heightAnchor.constraint(equalToConstant: 35), 190 | bottomStackView.widthAnchor.constraint(equalToConstant: 175), 191 | 192 | bottomSeparatorView.widthAnchor.constraint(equalToConstant: 1) 193 | ]) 194 | } 195 | 196 | override func configureAppearance() { 197 | super.configureAppearance() 198 | } 199 | } 200 | 201 | private extension TimerView { 202 | func getDisplayedString(from value: Int) -> String { 203 | let seconds = value % 60 204 | let minutes = (value / 60) % 60 205 | let hours = value / 3600 206 | 207 | let secondStr = seconds < 10 ? "0\(seconds)" : "\(seconds)" 208 | let minutesStr = minutes < 10 ? "0\(minutes)" : "\(minutes)" 209 | let hoursStr = hours < 10 ? "0\(hours)" : "\(hours)" 210 | 211 | return hours == 0 212 | ? [minutesStr, secondStr].joined(separator: ":") 213 | : [hoursStr, minutesStr, secondStr].joined(separator: ": ") 214 | } 215 | } 216 | 217 | -------------------------------------------------------------------------------- /Sport Kit Interface/Controllers/Settings/SettingsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | 9 | import UIKit 10 | 11 | class SettingsController: BaseController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | title = R.Strings.NavBar.settings 17 | 18 | } 19 | 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /Sport Kit Interface/Extentions/Date.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Date.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 20.07.2022. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Date { 11 | 12 | private var calendar: Calendar { 13 | return Calendar.current 14 | } 15 | 16 | var startOfWeek: Date{ 17 | 18 | let components = calendar.dateComponents([.yearForWeekOfYear, .weekOfYear], from: self) 19 | 20 | guard let firstDay = calendar.date(from: components) else {return self} 21 | 22 | return calendar.date(byAdding: .day, value: 1, to: firstDay) ?? self 23 | 24 | } 25 | 26 | func agoForward(to days: Int) -> Date { 27 | return calendar.date(byAdding: .day, value: days, to: self) ?? self 28 | } 29 | 30 | func strioTime() -> Date { 31 | let components = calendar.dateComponents([.year, .month, .day], from: self) 32 | return calendar.date(from: components) ?? self 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Sport Kit Interface/Extentions/UIColor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 11.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIColor { 11 | convenience init(hexString: String) { 12 | let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) 13 | var int = UInt64() 14 | Scanner(string: hex).scanHexInt64(&int) 15 | let a, r, g, b: UInt64 16 | switch hex.count { 17 | case 3: // RGB (12-bit) 18 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) 19 | case 6: // RGB (24-bit) 20 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) 21 | case 8: // ARGB (32-bit) 22 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) 23 | default: 24 | (a, r, g, b) = (255, 0, 0, 0) 25 | } 26 | self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sport Kit Interface/Extentions/UIView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIView.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | extension UIView { 11 | 12 | func addBottomBorder(with color: UIColor, height: CGFloat) { 13 | let separator = UIView() 14 | separator.backgroundColor = color 15 | separator.autoresizingMask = [.flexibleWidth, .flexibleHeight] 16 | separator.frame = CGRect(x: 0, 17 | y: frame.height - height, 18 | width: frame.width, 19 | height: height) 20 | addSubview(separator) 21 | } 22 | 23 | // Button (custom) configuration 24 | 25 | func makeSystem(_ button: UIButton) { 26 | button.addTarget(self, action: #selector(handlineIn), for: [ 27 | .touchDown, 28 | .touchUpInside 29 | ]) 30 | button.addTarget(self, action: #selector(handlineOut), for: [ 31 | .touchDragOutside, 32 | .touchUpInside, 33 | .touchUpOutside, 34 | .touchDragExit, 35 | .touchCancel 36 | ]) 37 | } 38 | 39 | @objc func handlineIn() { 40 | UIView.animate(withDuration: 0.15) {self.alpha = 0.55} 41 | } 42 | 43 | @objc func handlineOut() { 44 | UIView.animate(withDuration: 0.15) {self.alpha = 1} 45 | } 46 | 47 | func setupView(_ view: UIView) { 48 | addSubview(view) 49 | view.translatesAutoresizingMaskIntoConstraints = false 50 | } 51 | 52 | func roundCorners(_ corners: UIRectCorner, radius: CGFloat) { 53 | let path = UIBezierPath(roundedRect: bounds, 54 | byRoundingCorners: corners, 55 | cornerRadii: CGSize(width: radius, height: radius)) 56 | 57 | let borderLayer = CAShapeLayer() 58 | borderLayer.frame = bounds 59 | borderLayer.path = path.cgPath 60 | borderLayer.strokeColor = R.Colors.separator.cgColor 61 | borderLayer.fillColor = UIColor.clear.cgColor 62 | borderLayer.lineWidth = 1 63 | layer.addSublayer(borderLayer) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Sport Kit Interface/Navigation/NavBarController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NavBarController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 16.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | final class NavBarController: UINavigationController { 11 | 12 | override func viewDidLoad() { 13 | super.viewDidLoad() 14 | 15 | configure() 16 | 17 | } 18 | 19 | 20 | 21 | private func configure() { 22 | view.backgroundColor = .white 23 | navigationBar.isTranslucent = false 24 | navigationBar.standardAppearance.titleTextAttributes = [ 25 | .foregroundColor: R.Colors.titleGray, 26 | .font: R.Fonts.helvelticaRegular(with: 17) 27 | ] 28 | 29 | navigationBar.addBottomBorder(with: R.Colors.separator, height: 1) 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Sport Kit Interface/Navigation/TabBarController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabBarController.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 11.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum Tabs: Int, CaseIterable { 11 | case overview 12 | case session 13 | case progress 14 | case settings 15 | } 16 | 17 | class TabBarController: UITabBarController { 18 | 19 | override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 20 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 21 | 22 | configureAppearance() 23 | //switchTo(tab: .progress) 24 | } 25 | 26 | 27 | required init?(coder: NSCoder) { 28 | super.init(coder: coder) 29 | configureAppearance() 30 | 31 | } 32 | 33 | //Selected TabBar item after loading 34 | func switchTo(tab: Tabs) { 35 | selectedIndex = tab.rawValue 36 | } 37 | 38 | 39 | private func configureAppearance() { 40 | tabBar.tintColor = R.Colors.active 41 | tabBar.barTintColor = R.Colors.inactive 42 | tabBar.backgroundColor = .white 43 | 44 | tabBar.layer.borderColor = R.Colors.separator.cgColor 45 | tabBar.layer.borderWidth = 1 46 | tabBar.layer.masksToBounds = true 47 | 48 | let controllers: [NavBarController] = Tabs.allCases.map { tab in 49 | let controller = NavBarController(rootViewController: getController(for: tab)) 50 | controller.tabBarItem = UITabBarItem(title: R.Strings.TabBar.title(for: tab), 51 | image: R.Images.TabBar.icon(for: tab), 52 | tag: tab.rawValue) 53 | return controller 54 | } 55 | 56 | setViewControllers(controllers, animated: false) 57 | } 58 | } 59 | private func getController(for tab: Tabs) -> BaseController { 60 | 61 | switch tab { 62 | case .overview: return OverviewController() 63 | case .session: return SessionController() 64 | case .progress: return ProgressController() 65 | case .settings: return SettingsController() 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Common/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Common/add_icon.imageset/Add-2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungros/UIKit-Interface-App/7935568a706cdb825160b753ffd8583a52633a2e/Sport Kit Interface/Resources/Assets.xcassets/Common/add_icon.imageset/Add-2.pdf -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Common/add_icon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Add-2.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Common/all_workouts.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Path.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Common/all_workouts.imageset/Path.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 0.000000 -0.092285 cm 14 | 0.266667 0.482353 0.996078 scn 15 | 9.477531 0.092286 m 16 | 8.953707 0.091742 8.454979 0.280827 8.108800 0.611220 c 17 | 0.342104 8.030645 l 18 | -0.168442 8.541989 -0.099887 9.302349 0.496512 9.743200 c 19 | 1.092910 10.184052 1.999001 10.144143 2.537298 9.653313 c 20 | 9.328705 3.165307 l 21 | 9.366282 3.129278 9.420523 3.108617 9.477531 3.108617 c 22 | 9.534540 3.108617 9.588780 3.129278 9.626358 3.165307 c 23 | 16.417765 9.653313 l 24 | 16.758755 9.994835 17.293102 10.154349 17.814035 10.070130 c 25 | 18.334969 9.985910 18.760761 9.671169 18.926645 9.247700 c 26 | 19.092529 8.824229 18.972485 8.358468 18.612959 8.030645 c 27 | 10.848637 0.613881 l 28 | 10.501864 0.282687 10.002462 0.092705 9.477531 0.092286 c 29 | h 30 | f 31 | n 32 | Q 33 | 34 | endstream 35 | endobj 36 | 37 | 3 0 obj 38 | 751 39 | endobj 40 | 41 | 4 0 obj 42 | << /Annots [] 43 | /Type /Page 44 | /MediaBox [ 0.000000 0.000000 19.000000 10.000000 ] 45 | /Resources 1 0 R 46 | /Contents 2 0 R 47 | /Parent 5 0 R 48 | >> 49 | endobj 50 | 51 | 5 0 obj 52 | << /Kids [ 4 0 R ] 53 | /Count 1 54 | /Type /Pages 55 | >> 56 | endobj 57 | 58 | 6 0 obj 59 | << /Pages 5 0 R 60 | /Type /Catalog 61 | >> 62 | endobj 63 | 64 | xref 65 | 0 7 66 | 0000000000 65535 f 67 | 0000000010 00000 n 68 | 0000000034 00000 n 69 | 0000000841 00000 n 70 | 0000000863 00000 n 71 | 0000001036 00000 n 72 | 0000001110 00000 n 73 | trailer 74 | << /ID [ (some) (id) ] 75 | /Root 6 0 R 76 | /Size 7 77 | >> 78 | startxref 79 | 1169 80 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/checkmark_done.imageset/Checked.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | q 14 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 15 | 0.658824 0.203922 0.819608 scn 16 | 56.000000 28.000000 m 17 | 56.000000 12.536026 43.463974 0.000000 28.000000 0.000000 c 18 | 12.536027 0.000000 0.000000 12.536026 0.000000 28.000000 c 19 | 0.000000 43.463974 12.536027 56.000000 28.000000 56.000000 c 20 | 43.463974 56.000000 56.000000 43.463974 56.000000 28.000000 c 21 | h 22 | f 23 | n 24 | Q 25 | 56.000000 28.000000 m 26 | 56.000000 12.536026 43.463974 0.000000 28.000000 0.000000 c 27 | 12.536027 0.000000 0.000000 12.536026 0.000000 28.000000 c 28 | 0.000000 43.463974 12.536027 56.000000 28.000000 56.000000 c 29 | 43.463974 56.000000 56.000000 43.463974 56.000000 28.000000 c 30 | h 31 | W* 32 | n 33 | q 34 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 35 | 0.658824 0.203922 0.819608 scn 36 | 52.000000 28.000000 m 37 | 52.000000 14.745167 41.254833 4.000000 28.000000 4.000000 c 38 | 28.000000 -4.000000 l 39 | 45.673111 -4.000000 60.000000 10.326889 60.000000 28.000000 c 40 | 52.000000 28.000000 l 41 | h 42 | 28.000000 4.000000 m 43 | 14.745166 4.000000 4.000000 14.745167 4.000000 28.000000 c 44 | -4.000000 28.000000 l 45 | -4.000000 10.326889 10.326888 -4.000000 28.000000 -4.000000 c 46 | 28.000000 4.000000 l 47 | h 48 | 4.000000 28.000000 m 49 | 4.000000 41.254833 14.745166 52.000000 28.000000 52.000000 c 50 | 28.000000 60.000000 l 51 | 10.326888 60.000000 -4.000000 45.673111 -4.000000 28.000000 c 52 | 4.000000 28.000000 l 53 | h 54 | 28.000000 52.000000 m 55 | 41.254833 52.000000 52.000000 41.254833 52.000000 28.000000 c 56 | 60.000000 28.000000 l 57 | 60.000000 45.673111 45.673111 60.000000 28.000000 60.000000 c 58 | 28.000000 52.000000 l 59 | h 60 | f 61 | n 62 | Q 63 | Q 64 | q 65 | 1.000000 0.000000 -0.000000 1.000000 17.994141 16.691772 cm 66 | 1.000000 1.000000 1.000000 scn 67 | 1.315219 11.148470 m 68 | 0.588843 11.874846 -0.588843 11.874846 -1.315219 11.148470 c 69 | -2.041594 10.422095 -2.041594 9.244409 -1.315219 8.518033 c 70 | 1.315219 11.148470 l 71 | h 72 | 5.750000 4.083252 m 73 | 4.434782 2.768033 l 74 | 5.161157 2.041658 6.338843 2.041658 7.065218 2.768033 c 75 | 5.750000 4.083252 l 76 | h 77 | 21.440218 17.143034 m 78 | 22.166594 17.869408 22.166594 19.047096 21.440218 19.773470 c 79 | 20.713844 20.499846 19.536156 20.499846 18.809782 19.773470 c 80 | 21.440218 17.143034 l 81 | h 82 | -1.315219 8.518033 m 83 | 4.434782 2.768033 l 84 | 7.065218 5.398471 l 85 | 1.315219 11.148470 l 86 | -1.315219 8.518033 l 87 | h 88 | 7.065218 2.768033 m 89 | 21.440218 17.143034 l 90 | 18.809782 19.773470 l 91 | 4.434782 5.398471 l 92 | 7.065218 2.768033 l 93 | h 94 | f 95 | n 96 | Q 97 | 98 | endstream 99 | endobj 100 | 101 | 3 0 obj 102 | 2284 103 | endobj 104 | 105 | 4 0 obj 106 | << /Annots [] 107 | /Type /Page 108 | /MediaBox [ 0.000000 0.000000 56.000000 56.000000 ] 109 | /Resources 1 0 R 110 | /Contents 2 0 R 111 | /Parent 5 0 R 112 | >> 113 | endobj 114 | 115 | 5 0 obj 116 | << /Kids [ 4 0 R ] 117 | /Count 1 118 | /Type /Pages 119 | >> 120 | endobj 121 | 122 | 6 0 obj 123 | << /Pages 5 0 R 124 | /Type /Catalog 125 | >> 126 | endobj 127 | 128 | xref 129 | 0 7 130 | 0000000000 65535 f 131 | 0000000010 00000 n 132 | 0000000034 00000 n 133 | 0000002374 00000 n 134 | 0000002397 00000 n 135 | 0000002570 00000 n 136 | 0000002644 00000 n 137 | trailer 138 | << /ID [ (some) (id) ] 139 | /Root 6 0 R 140 | /Size 7 141 | >> 142 | startxref 143 | 2703 144 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/checkmark_done.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Checked.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/checkmark_not_done.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Oval.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/checkmark_not_done.imageset/Oval.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 56.000000 28.000000 m 14 | 56.000000 12.536026 43.463974 0.000000 28.000000 0.000000 c 15 | 12.536027 0.000000 0.000000 12.536026 0.000000 28.000000 c 16 | 0.000000 43.463974 12.536027 56.000000 28.000000 56.000000 c 17 | 43.463974 56.000000 56.000000 43.463974 56.000000 28.000000 c 18 | h 19 | W* 20 | n 21 | q 22 | 1.000000 0.000000 -0.000000 1.000000 0.000000 0.000000 cm 23 | 0.909804 0.925490 0.937255 scn 24 | 52.000000 28.000000 m 25 | 52.000000 14.745167 41.254833 4.000000 28.000000 4.000000 c 26 | 28.000000 -4.000000 l 27 | 45.673111 -4.000000 60.000000 10.326889 60.000000 28.000000 c 28 | 52.000000 28.000000 l 29 | h 30 | 28.000000 4.000000 m 31 | 14.745166 4.000000 4.000000 14.745167 4.000000 28.000000 c 32 | -4.000000 28.000000 l 33 | -4.000000 10.326889 10.326888 -4.000000 28.000000 -4.000000 c 34 | 28.000000 4.000000 l 35 | h 36 | 4.000000 28.000000 m 37 | 4.000000 41.254833 14.745166 52.000000 28.000000 52.000000 c 38 | 28.000000 60.000000 l 39 | 10.326888 60.000000 -4.000000 45.673111 -4.000000 28.000000 c 40 | 4.000000 28.000000 l 41 | h 42 | 28.000000 52.000000 m 43 | 41.254833 52.000000 52.000000 41.254833 52.000000 28.000000 c 44 | 60.000000 28.000000 l 45 | 60.000000 45.673111 45.673111 60.000000 28.000000 60.000000 c 46 | 28.000000 52.000000 l 47 | h 48 | f 49 | n 50 | Q 51 | Q 52 | 53 | endstream 54 | endobj 55 | 56 | 3 0 obj 57 | 1158 58 | endobj 59 | 60 | 4 0 obj 61 | << /Annots [] 62 | /Type /Page 63 | /MediaBox [ 0.000000 0.000000 56.000000 56.000000 ] 64 | /Resources 1 0 R 65 | /Contents 2 0 R 66 | /Parent 5 0 R 67 | >> 68 | endobj 69 | 70 | 5 0 obj 71 | << /Kids [ 4 0 R ] 72 | /Count 1 73 | /Type /Pages 74 | >> 75 | endobj 76 | 77 | 6 0 obj 78 | << /Pages 5 0 R 79 | /Type /Catalog 80 | >> 81 | endobj 82 | 83 | xref 84 | 0 7 85 | 0000000000 65535 f 86 | 0000000010 00000 n 87 | 0000000034 00000 n 88 | 0000001248 00000 n 89 | 0000001271 00000 n 90 | 0000001444 00000 n 91 | 0000001518 00000 n 92 | trailer 93 | << /ID [ (some) (id) ] 94 | /Root 6 0 R 95 | /Size 7 96 | >> 97 | startxref 98 | 1577 99 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/right_arrow.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Right Arrow.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Overview/right_arrow.imageset/Right Arrow.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | -0.000000 -1.000000 -1.000000 0.000000 25.343384 25.000000 cm 14 | 0.788235 0.827451 0.850980 scn 15 | 12.470436 11.454496 m 16 | 11.781194 11.453739 11.124974 11.716358 10.669475 12.175239 c 17 | 0.450137 22.479996 l 18 | -0.221634 23.190195 -0.131430 24.246250 0.653305 24.858543 c 19 | 1.438039 25.470839 2.630265 25.415409 3.338550 24.733700 c 20 | 12.274611 15.722581 l 21 | 12.324057 15.672541 12.395425 15.643845 12.470436 15.643845 c 22 | 12.545447 15.643845 12.616816 15.672541 12.666261 15.722581 c 23 | 21.602322 24.733700 l 24 | 22.050993 25.208036 22.754082 25.429585 23.439520 25.312613 c 25 | 24.124958 25.195641 24.685211 24.758501 24.903481 24.170349 c 26 | 25.121750 23.582195 24.963793 22.935305 24.490734 22.479996 c 27 | 14.274522 12.178934 l 28 | 13.818243 11.718943 13.161134 11.455078 12.470436 11.454496 c 29 | h 30 | f 31 | n 32 | Q 33 | 34 | endstream 35 | endobj 36 | 37 | 3 0 obj 38 | 794 39 | endobj 40 | 41 | 4 0 obj 42 | << /Annots [] 43 | /Type /Page 44 | /MediaBox [ 0.000000 0.000000 13.888672 25.000000 ] 45 | /Resources 1 0 R 46 | /Contents 2 0 R 47 | /Parent 5 0 R 48 | >> 49 | endobj 50 | 51 | 5 0 obj 52 | << /Kids [ 4 0 R ] 53 | /Count 1 54 | /Type /Pages 55 | >> 56 | endobj 57 | 58 | 6 0 obj 59 | << /Pages 5 0 R 60 | /Type /Catalog 61 | >> 62 | endobj 63 | 64 | xref 65 | 0 7 66 | 0000000000 65535 f 67 | 0000000010 00000 n 68 | 0000000034 00000 n 69 | 0000000884 00000 n 70 | 0000000906 00000 n 71 | 0000001079 00000 n 72 | 0000001153 00000 n 73 | trailer 74 | << /ID [ (some) (id) ] 75 | /Root 6 0 R 76 | /Size 7 77 | >> 78 | startxref 79 | 1212 80 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_averagePace.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Speed Icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_averagePace.imageset/Speed Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungros/UIKit-Interface-App/7935568a706cdb825160b753ffd8583a52633a2e/Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_averagePace.imageset/Speed Icon.pdf -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_heartRate.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Heart Beat Icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_heartRate.imageset/Heart Beat Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungros/UIKit-Interface-App/7935568a706cdb825160b753ffd8583a52633a2e/Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_heartRate.imageset/Heart Beat Icon.pdf -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalDistance.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Maps Icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalDistance.imageset/Maps Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungros/UIKit-Interface-App/7935568a706cdb825160b753ffd8583a52633a2e/Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalDistance.imageset/Maps Icon.pdf -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalSteps.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Steps Icon.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalSteps.imageset/Steps Icon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ungros/UIKit-Interface-App/7935568a706cdb825160b753ffd8583a52633a2e/Sport Kit Interface/Resources/Assets.xcassets/Stats/stats_totalSteps.imageset/Steps Icon.pdf -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/overview_tab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "House Icon.pdf", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/overview_tab.imageset/House Icon.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 6.250000 -1.250000 cm 14 | 0.572549 0.615686 0.647059 scn 15 | 1.250000 16.250000 m 16 | 1.250000 16.940355 0.690356 17.500000 0.000000 17.500000 c 17 | -0.690356 17.500000 -1.250000 16.940355 -1.250000 16.250000 c 18 | 1.250000 16.250000 l 19 | h 20 | 0.000000 2.500000 m 21 | -1.250000 2.500000 l 22 | -1.250000 1.809644 -0.690356 1.250000 0.000000 1.250000 c 23 | 0.000000 2.500000 l 24 | h 25 | 10.000000 2.500000 m 26 | 10.000000 1.250000 l 27 | 10.690356 1.250000 11.250000 1.809644 11.250000 2.500000 c 28 | 10.000000 2.500000 l 29 | h 30 | 17.500000 2.500000 m 31 | 16.250000 2.500000 l 32 | 16.250000 1.809644 16.809645 1.250000 17.500000 1.250000 c 33 | 17.500000 2.500000 l 34 | h 35 | 27.500000 2.500000 m 36 | 27.500000 1.250000 l 37 | 28.190355 1.250000 28.750000 1.809644 28.750000 2.500000 c 38 | 27.500000 2.500000 l 39 | h 40 | 28.750000 16.250000 m 41 | 28.750000 16.940355 28.190355 17.500000 27.500000 17.500000 c 42 | 26.809645 17.500000 26.250000 16.940355 26.250000 16.250000 c 43 | 28.750000 16.250000 l 44 | h 45 | -1.250000 16.250000 m 46 | -1.250000 2.500000 l 47 | 1.250000 2.500000 l 48 | 1.250000 16.250000 l 49 | -1.250000 16.250000 l 50 | h 51 | 0.000000 1.250000 m 52 | 10.000000 1.250000 l 53 | 10.000000 3.750000 l 54 | 0.000000 3.750000 l 55 | 0.000000 1.250000 l 56 | h 57 | 11.250000 2.500000 m 58 | 11.250000 12.500000 l 59 | 8.750000 12.500000 l 60 | 8.750000 2.500000 l 61 | 11.250000 2.500000 l 62 | h 63 | 11.250000 12.500000 m 64 | 11.250000 13.190356 11.809644 13.750000 12.500000 13.750000 c 65 | 12.500000 16.250000 l 66 | 10.428932 16.250000 8.750000 14.571068 8.750000 12.500000 c 67 | 11.250000 12.500000 l 68 | h 69 | 12.500000 13.750000 m 70 | 15.000000 13.750000 l 71 | 15.000000 16.250000 l 72 | 12.500000 16.250000 l 73 | 12.500000 13.750000 l 74 | h 75 | 15.000000 13.750000 m 76 | 15.690356 13.750000 16.250000 13.190356 16.250000 12.500000 c 77 | 18.750000 12.500000 l 78 | 18.750000 14.571068 17.071068 16.250000 15.000000 16.250000 c 79 | 15.000000 13.750000 l 80 | h 81 | 16.250000 12.500000 m 82 | 16.250000 2.500000 l 83 | 18.750000 2.500000 l 84 | 18.750000 12.500000 l 85 | 16.250000 12.500000 l 86 | h 87 | 17.500000 1.250000 m 88 | 27.500000 1.250000 l 89 | 27.500000 3.750000 l 90 | 17.500000 3.750000 l 91 | 17.500000 1.250000 l 92 | h 93 | 28.750000 2.500000 m 94 | 28.750000 16.250000 l 95 | 26.250000 16.250000 l 96 | 26.250000 2.500000 l 97 | 28.750000 2.500000 l 98 | h 99 | f 100 | n 101 | Q 102 | q 103 | 1.000000 0.000000 -0.000000 1.000000 1.250000 14.877930 cm 104 | 0.572549 0.615686 0.647059 scn 105 | -0.883883 3.505844 m 106 | -1.372039 3.017689 -1.372039 2.226233 -0.883883 1.738077 c 107 | -0.395728 1.249922 0.395728 1.249920 0.883883 1.738075 c 108 | -0.883883 3.505844 l 109 | h 110 | 16.981667 19.603626 m 111 | 17.865551 18.719742 l 112 | 17.865833 18.720026 l 113 | 16.981667 19.603626 l 114 | h 115 | 20.518333 19.603626 m 116 | 19.634167 18.720026 l 117 | 19.634451 18.719742 l 118 | 20.518333 19.603626 l 119 | h 120 | 36.616116 1.738075 m 121 | 37.104271 1.249920 37.895729 1.249922 38.383884 1.738077 c 122 | 38.872040 2.226233 38.872040 3.017689 38.383884 3.505844 c 123 | 36.616116 1.738075 l 124 | h 125 | 0.883883 1.738075 m 126 | 17.865549 18.719742 l 127 | 16.097784 20.487509 l 128 | -0.883883 3.505844 l 129 | 0.883883 1.738075 l 130 | h 131 | 17.865833 18.720026 m 132 | 18.100277 18.954620 18.418341 19.086426 18.750000 19.086426 c 133 | 18.750000 21.586426 l 134 | 17.755022 21.586426 16.800831 21.191008 16.097500 20.487226 c 135 | 17.865833 18.720026 l 136 | h 137 | 18.750000 19.086426 m 138 | 19.081659 19.086426 19.399723 18.954620 19.634167 18.720026 c 139 | 21.402500 20.487226 l 140 | 20.699169 21.191008 19.744978 21.586426 18.750000 21.586426 c 141 | 18.750000 19.086426 l 142 | h 143 | 19.634451 18.719742 m 144 | 36.616116 1.738075 l 145 | 38.383884 3.505844 l 146 | 21.402216 20.487509 l 147 | 19.634451 18.719742 l 148 | h 149 | f 150 | n 151 | Q 152 | 153 | endstream 154 | endobj 155 | 156 | 3 0 obj 157 | 3294 158 | endobj 159 | 160 | 4 0 obj 161 | << /Annots [] 162 | /Type /Page 163 | /MediaBox [ 0.000000 0.000000 40.000000 35.573242 ] 164 | /Resources 1 0 R 165 | /Contents 2 0 R 166 | /Parent 5 0 R 167 | >> 168 | endobj 169 | 170 | 5 0 obj 171 | << /Kids [ 4 0 R ] 172 | /Count 1 173 | /Type /Pages 174 | >> 175 | endobj 176 | 177 | 6 0 obj 178 | << /Pages 5 0 R 179 | /Type /Catalog 180 | >> 181 | endobj 182 | 183 | xref 184 | 0 7 185 | 0000000000 65535 f 186 | 0000000010 00000 n 187 | 0000000034 00000 n 188 | 0000003384 00000 n 189 | 0000003407 00000 n 190 | 0000003580 00000 n 191 | 0000003654 00000 n 192 | trailer 193 | << /ID [ (some) (id) ] 194 | /Root 6 0 R 195 | /Size 7 196 | >> 197 | startxref 198 | 3713 199 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/progress_tab.imageset/Analytics Bars.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 1.250000 -1.250000 cm 14 | 0.572549 0.615686 0.647059 scn 15 | 0.000000 2.500000 m 16 | -1.250000 2.500000 l 17 | -1.250000 1.809645 -0.690356 1.250000 0.000000 1.250000 c 18 | 0.000000 2.500000 l 19 | h 20 | 7.500000 2.500000 m 21 | 7.500000 1.250000 l 22 | 8.190356 1.250000 8.750000 1.809645 8.750000 2.500000 c 23 | 7.500000 2.500000 l 24 | h 25 | 6.250000 21.250000 m 26 | 1.250000 21.250000 l 27 | 1.250000 18.750000 l 28 | 6.250000 18.750000 l 29 | 6.250000 21.250000 l 30 | h 31 | 1.250000 21.250000 m 32 | -0.130712 21.250000 -1.250000 20.130713 -1.250000 18.750000 c 33 | 1.250000 18.750000 l 34 | 1.250000 21.250000 l 35 | h 36 | -1.250000 18.750000 m 37 | -1.250000 2.500000 l 38 | 1.250000 2.500000 l 39 | 1.250000 18.750000 l 40 | -1.250000 18.750000 l 41 | h 42 | 0.000000 1.250000 m 43 | 7.500000 1.250000 l 44 | 7.500000 3.750000 l 45 | 0.000000 3.750000 l 46 | 0.000000 1.250000 l 47 | h 48 | 8.750000 2.500000 m 49 | 8.750000 18.750000 l 50 | 6.250000 18.750000 l 51 | 6.250000 2.500000 l 52 | 8.750000 2.500000 l 53 | h 54 | 8.750000 18.750000 m 55 | 8.750000 20.130713 7.630712 21.250000 6.250000 21.250000 c 56 | 6.250000 18.750000 l 57 | 8.750000 18.750000 l 58 | h 59 | f 60 | n 61 | Q 62 | q 63 | 1.000000 0.000000 -0.000000 1.000000 14.750000 -1.250000 cm 64 | 0.572549 0.615686 0.647059 scn 65 | 0.000000 2.500000 m 66 | -1.250000 2.500000 l 67 | -1.250000 1.809643 -0.690356 1.250000 0.000000 1.250000 c 68 | 0.000000 2.500000 l 69 | h 70 | 7.500000 2.500000 m 71 | 7.500000 1.250000 l 72 | 8.190356 1.250000 8.750000 1.809643 8.750000 2.500000 c 73 | 7.500000 2.500000 l 74 | h 75 | 6.250000 36.250000 m 76 | 1.250000 36.250000 l 77 | 1.250000 33.750000 l 78 | 6.250000 33.750000 l 79 | 6.250000 36.250000 l 80 | h 81 | 1.250000 36.250000 m 82 | -0.130712 36.250000 -1.250000 35.130711 -1.250000 33.750000 c 83 | 1.250000 33.750000 l 84 | 1.250000 36.250000 l 85 | h 86 | -1.250000 33.750000 m 87 | -1.250000 2.500000 l 88 | 1.250000 2.500000 l 89 | 1.250000 33.750000 l 90 | -1.250000 33.750000 l 91 | h 92 | 0.000000 1.250000 m 93 | 7.500000 1.250000 l 94 | 7.500000 3.750000 l 95 | 0.000000 3.750000 l 96 | 0.000000 1.250000 l 97 | h 98 | 8.750000 2.500000 m 99 | 8.750000 33.750000 l 100 | 6.250000 33.750000 l 101 | 6.250000 2.500000 l 102 | 8.750000 2.500000 l 103 | h 104 | 8.750000 33.750000 m 105 | 8.750000 35.130711 7.630712 36.250000 6.250000 36.250000 c 106 | 6.250000 33.750000 l 107 | 8.750000 33.750000 l 108 | h 109 | f 110 | n 111 | Q 112 | q 113 | 1.000000 0.000000 -0.000000 1.000000 28.250000 -1.250000 cm 114 | 0.572549 0.615686 0.647059 scn 115 | 0.000000 2.500000 m 116 | -1.250000 2.500000 l 117 | -1.250000 1.809645 -0.690356 1.250000 0.000000 1.250000 c 118 | 0.000000 2.500000 l 119 | h 120 | 7.500000 2.500000 m 121 | 7.500000 1.250000 l 122 | 8.190356 1.250000 8.750000 1.809645 8.750000 2.500000 c 123 | 7.500000 2.500000 l 124 | h 125 | 6.250000 28.750000 m 126 | 1.250000 28.750000 l 127 | 1.250000 26.250000 l 128 | 6.250000 26.250000 l 129 | 6.250000 28.750000 l 130 | h 131 | 1.250000 28.750000 m 132 | -0.130712 28.750000 -1.250000 27.630713 -1.250000 26.250000 c 133 | 1.250000 26.250000 l 134 | 1.250000 28.750000 l 135 | h 136 | -1.250000 26.250000 m 137 | -1.250000 2.500000 l 138 | 1.250000 2.500000 l 139 | 1.250000 26.250000 l 140 | -1.250000 26.250000 l 141 | h 142 | 0.000000 1.250000 m 143 | 7.500000 1.250000 l 144 | 7.500000 3.750000 l 145 | 0.000000 3.750000 l 146 | 0.000000 1.250000 l 147 | h 148 | 8.750000 2.500000 m 149 | 8.750000 26.250000 l 150 | 6.250000 26.250000 l 151 | 6.250000 2.500000 l 152 | 8.750000 2.500000 l 153 | h 154 | 8.750000 26.250000 m 155 | 8.750000 27.630713 7.630712 28.750000 6.250000 28.750000 c 156 | 6.250000 26.250000 l 157 | 8.750000 26.250000 l 158 | h 159 | f 160 | n 161 | Q 162 | 163 | endstream 164 | endobj 165 | 166 | 3 0 obj 167 | 3057 168 | endobj 169 | 170 | 4 0 obj 171 | << /Annots [] 172 | /Type /Page 173 | /MediaBox [ 0.000000 0.000000 37.000000 34.166748 ] 174 | /Resources 1 0 R 175 | /Contents 2 0 R 176 | /Parent 5 0 R 177 | >> 178 | endobj 179 | 180 | 5 0 obj 181 | << /Kids [ 4 0 R ] 182 | /Count 1 183 | /Type /Pages 184 | >> 185 | endobj 186 | 187 | 6 0 obj 188 | << /Pages 5 0 R 189 | /Type /Catalog 190 | >> 191 | endobj 192 | 193 | xref 194 | 0 7 195 | 0000000000 65535 f 196 | 0000000010 00000 n 197 | 0000000034 00000 n 198 | 0000003147 00000 n 199 | 0000003170 00000 n 200 | 0000003343 00000 n 201 | 0000003417 00000 n 202 | trailer 203 | << /ID [ (some) (id) ] 204 | /Root 6 0 R 205 | /Size 7 206 | >> 207 | startxref 208 | 3476 209 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/progress_tab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "Analytics Bars.pdf", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/session_tab.imageset/Clock Icon.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 3.750000 1.250244 cm 14 | 0.572549 0.615686 0.647059 scn 15 | 28.750000 17.500000 m 16 | 28.750000 9.906084 22.593916 3.750000 15.000000 3.750000 c 17 | 15.000000 1.250000 l 18 | 23.974627 1.250000 31.250000 8.525373 31.250000 17.500000 c 19 | 28.750000 17.500000 l 20 | h 21 | 15.000000 3.750000 m 22 | 7.406085 3.750000 1.250000 9.906084 1.250000 17.500000 c 23 | -1.250000 17.500000 l 24 | -1.250000 8.525373 6.025373 1.250000 15.000000 1.250000 c 25 | 15.000000 3.750000 l 26 | h 27 | 1.250000 17.500000 m 28 | 1.250000 25.093916 7.406085 31.250000 15.000000 31.250000 c 29 | 15.000000 33.750000 l 30 | 6.025373 33.750000 -1.250000 26.474627 -1.250000 17.500000 c 31 | 1.250000 17.500000 l 32 | h 33 | 15.000000 31.250000 m 34 | 22.593916 31.250000 28.750000 25.093916 28.750000 17.500000 c 35 | 31.250000 17.500000 l 36 | 31.250000 26.474627 23.974627 33.750000 15.000000 33.750000 c 37 | 15.000000 31.250000 l 38 | h 39 | f 40 | n 41 | Q 42 | q 43 | 1.000000 0.000000 -0.000000 1.000000 8.750000 -1.603271 cm 44 | 0.572549 0.615686 0.647059 scn 45 | -1.117953 3.412769 m 46 | -1.426779 2.795340 -1.176607 2.044463 -0.559178 1.735637 c 47 | 0.058250 1.426812 0.809128 1.676983 1.117953 2.294412 c 48 | -1.117953 3.412769 l 49 | h 50 | 3.427953 6.912745 m 51 | 3.736779 7.530174 3.486607 8.281052 2.869178 8.589877 c 52 | 2.251750 8.898703 1.500872 8.648531 1.192047 8.031102 c 53 | 3.427953 6.912745 l 54 | h 55 | 1.117953 2.294412 m 56 | 3.427953 6.912745 l 57 | 1.192047 8.031102 l 58 | -1.117953 3.412769 l 59 | 1.117953 2.294412 l 60 | h 61 | f 62 | n 63 | Q 64 | q 65 | 1.000000 0.000000 -0.000000 1.000000 13.098633 17.083496 cm 66 | 0.572549 0.615686 0.647059 scn 67 | 5.651667 0.416667 m 68 | 6.342022 0.416667 6.901667 0.976311 6.901667 1.666667 c 69 | 6.901667 2.357023 6.342022 2.916667 5.651667 2.916667 c 70 | 5.651667 0.416667 l 71 | h 72 | 0.000000 2.916667 m 73 | -0.690356 2.916667 -1.250000 2.357023 -1.250000 1.666667 c 74 | -1.250000 0.976311 -0.690356 0.416667 0.000000 0.416667 c 75 | 0.000000 2.916667 l 76 | h 77 | 5.651667 2.916667 m 78 | 0.000000 2.916667 l 79 | 0.000000 0.416667 l 80 | 5.651667 0.416667 l 81 | 5.651667 2.916667 l 82 | h 83 | f 84 | n 85 | Q 86 | q 87 | 1.000000 0.000000 -0.000000 1.000000 17.916992 16.250244 cm 88 | 0.572549 0.615686 0.647059 scn 89 | 2.083333 11.250000 m 90 | 2.083333 11.940356 1.523689 12.500000 0.833333 12.500000 c 91 | 0.142977 12.500000 -0.416667 11.940356 -0.416667 11.250000 c 92 | 2.083333 11.250000 l 93 | h 94 | -0.416667 2.500000 m 95 | -0.416667 1.809644 0.142977 1.250000 0.833333 1.250000 c 96 | 1.523689 1.250000 2.083333 1.809644 2.083333 2.500000 c 97 | -0.416667 2.500000 l 98 | h 99 | -0.416667 11.250000 m 100 | -0.416667 2.500000 l 101 | 2.083333 2.500000 l 102 | 2.083333 11.250000 l 103 | -0.416667 11.250000 l 104 | h 105 | f 106 | n 107 | Q 108 | q 109 | 1.000000 0.000000 -0.000000 1.000000 1.250000 30.935791 cm 110 | 0.572549 0.615686 0.647059 scn 111 | -0.780869 3.790539 m 112 | -1.319946 3.359277 -1.407348 2.572662 -0.976086 2.033584 c 113 | -0.544824 1.494507 0.241791 1.407105 0.780869 1.838367 c 114 | -0.780869 3.790539 l 115 | h 116 | 7.030869 6.838367 m 117 | 7.569946 7.269629 7.657348 8.056245 7.226086 8.595322 c 118 | 6.794824 9.134399 6.008209 9.221801 5.469131 8.790539 c 119 | 7.030869 6.838367 l 120 | h 121 | 0.780869 1.838367 m 122 | 7.030869 6.838367 l 123 | 5.469131 8.790539 l 124 | -0.780869 3.790539 l 125 | 0.780869 1.838367 l 126 | h 127 | f 128 | n 129 | Q 130 | q 131 | 1.000000 0.000000 -0.000000 1.000000 26.440430 -1.603271 cm 132 | 0.572549 0.615686 0.647059 scn 133 | 1.191966 2.294616 m 134 | 1.500703 1.677143 2.251544 1.426862 2.869017 1.735599 c 135 | 3.486490 2.044335 3.736770 2.795177 3.428034 3.412650 c 136 | 1.191966 2.294616 l 137 | h 138 | 1.118034 8.032650 m 139 | 0.809297 8.650123 0.058456 8.900403 -0.559017 8.591667 c 140 | -1.176490 8.282930 -1.426771 7.532089 -1.118034 6.914616 c 141 | 1.118034 8.032650 l 142 | h 143 | 3.428034 3.412650 m 144 | 1.118034 8.032650 l 145 | -1.118034 6.914616 l 146 | 1.191966 2.294616 l 147 | 3.428034 3.412650 l 148 | h 149 | f 150 | n 151 | Q 152 | q 153 | 1.000000 0.000000 -0.000000 1.000000 30.000000 30.935791 cm 154 | 0.572549 0.615686 0.647059 scn 155 | 5.469131 1.838367 m 156 | 6.008209 1.407105 6.794824 1.494507 7.226086 2.033584 c 157 | 7.657348 2.572662 7.569946 3.359277 7.030869 3.790539 c 158 | 5.469131 1.838367 l 159 | h 160 | 0.780869 8.790539 m 161 | 0.241791 9.221801 -0.544824 9.134399 -0.976086 8.595322 c 162 | -1.407348 8.056245 -1.319946 7.269629 -0.780869 6.838367 c 163 | 0.780869 8.790539 l 164 | h 165 | 7.030869 3.790539 m 166 | 0.780869 8.790539 l 167 | -0.780869 6.838367 l 168 | 5.469131 1.838367 l 169 | 7.030869 3.790539 l 170 | h 171 | f 172 | n 173 | Q 174 | 175 | endstream 176 | endobj 177 | 178 | 3 0 obj 179 | 3971 180 | endobj 181 | 182 | 4 0 obj 183 | << /Annots [] 184 | /Type /Page 185 | /MediaBox [ 0.000000 0.000000 37.500000 39.000244 ] 186 | /Resources 1 0 R 187 | /Contents 2 0 R 188 | /Parent 5 0 R 189 | >> 190 | endobj 191 | 192 | 5 0 obj 193 | << /Kids [ 4 0 R ] 194 | /Count 1 195 | /Type /Pages 196 | >> 197 | endobj 198 | 199 | 6 0 obj 200 | << /Pages 5 0 R 201 | /Type /Catalog 202 | >> 203 | endobj 204 | 205 | xref 206 | 0 7 207 | 0000000000 65535 f 208 | 0000000010 00000 n 209 | 0000000034 00000 n 210 | 0000004061 00000 n 211 | 0000004084 00000 n 212 | 0000004257 00000 n 213 | 0000004331 00000 n 214 | trailer 215 | << /ID [ (some) (id) ] 216 | /Root 6 0 R 217 | /Size 7 218 | >> 219 | startxref 220 | 4390 221 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/session_tab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "Clock Icon.pdf", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/settings_tab.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "Gear Icon.pdf", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Assets.xcassets/TabBar/settings_tab.imageset/Gear Icon.pdf: -------------------------------------------------------------------------------- 1 | %PDF-1.7 2 | 3 | 1 0 obj 4 | << >> 5 | endobj 6 | 7 | 2 0 obj 8 | << /Length 3 0 R >> 9 | stream 10 | /DeviceRGB CS 11 | /DeviceRGB cs 12 | q 13 | 1.000000 0.000000 -0.000000 1.000000 1.250000 -2.021240 cm 14 | 0.572549 0.615686 0.647059 scn 15 | 16.316900 37.942574 m 16 | 17.245621 38.779228 l 17 | 17.243439 38.781639 l 18 | 16.316900 37.942574 l 19 | h 20 | 21.163568 37.942574 m 21 | 20.239676 38.784580 l 22 | 20.234852 38.779224 l 23 | 21.163568 37.942574 l 24 | h 25 | 22.740234 39.672577 m 26 | 23.664120 38.830574 l 27 | 23.667707 38.834545 l 28 | 22.740234 39.672577 l 29 | h 30 | 28.423567 37.317574 m 31 | 27.175184 37.381153 l 32 | 27.175171 37.380886 l 33 | 28.423567 37.317574 l 34 | h 35 | 28.305235 34.984241 m 36 | 27.056839 35.047554 l 37 | 27.056812 35.047016 l 38 | 28.305235 34.984241 l 39 | h 40 | 31.723568 31.560909 m 41 | 31.784517 30.312393 l 42 | 31.786880 30.312511 l 43 | 31.723568 31.560909 l 44 | h 45 | 34.056900 31.679241 m 46 | 33.995350 32.927727 l 47 | 33.993587 32.927639 l 48 | 34.056900 31.679241 l 49 | h 50 | 36.406902 25.995909 m 51 | 37.244190 25.067764 l 52 | 37.245045 25.068539 l 53 | 36.406902 25.995909 l 54 | h 55 | 34.670235 24.429241 m 56 | 33.832947 25.357384 l 57 | 33.832363 25.356857 l 58 | 34.670235 24.429241 l 59 | h 60 | 34.670235 19.580908 m 61 | 33.832363 18.653294 l 62 | 33.832947 18.652765 l 63 | 34.670235 19.580908 l 64 | h 65 | 36.406902 18.014242 m 66 | 37.244934 18.941715 l 67 | 37.244190 18.942385 l 68 | 36.406902 18.014242 l 69 | h 70 | 34.051903 12.330908 m 71 | 34.115482 13.579290 l 72 | 34.115215 13.579304 l 73 | 34.051903 12.330908 l 74 | h 75 | 31.718567 12.449242 m 76 | 31.654352 11.200891 l 77 | 31.655254 11.200846 l 78 | 31.718567 12.449242 l 79 | h 80 | 28.291901 9.022575 m 81 | 29.540297 9.085888 l 82 | 29.540251 9.086790 l 83 | 28.291901 9.022575 l 84 | h 85 | 28.410234 6.689243 m 86 | 29.659019 6.744877 l 87 | 29.658630 6.752556 l 88 | 28.410234 6.689243 l 89 | h 90 | 22.740234 4.339241 m 91 | 21.812916 3.501003 l 92 | 21.818245 3.495182 l 93 | 22.740234 4.339241 l 94 | h 95 | 21.171902 6.074242 m 96 | 20.244133 5.236538 l 97 | 20.244602 5.236019 l 98 | 21.171902 6.074242 l 99 | h 100 | 16.325233 6.074242 m 101 | 17.250765 5.234062 l 102 | 17.253002 5.236542 l 103 | 16.325233 6.074242 l 104 | h 105 | 14.750235 4.339241 m 106 | 15.674849 3.498058 l 107 | 15.675763 3.499065 l 108 | 14.750235 4.339241 l 109 | h 110 | 9.073567 6.685909 m 111 | 7.825198 6.750111 l 112 | 7.824878 6.743145 l 113 | 9.073567 6.685909 l 114 | h 115 | 9.193567 9.019241 m 116 | 7.945218 9.083456 l 117 | 7.945217 9.083443 l 118 | 9.193567 9.019241 l 119 | h 120 | 5.766901 12.445910 m 121 | 5.830213 11.197514 l 122 | 5.831115 11.197559 l 123 | 5.766901 12.445910 l 124 | h 125 | 3.433568 12.327576 m 126 | 3.370256 13.575974 l 127 | 3.368413 13.575876 l 128 | 3.433568 12.327576 l 129 | h 130 | 1.073568 18.005909 m 131 | 0.235836 18.933653 l 132 | 0.234739 18.932659 l 133 | 1.073568 18.005909 l 134 | h 135 | 2.808568 19.572575 m 136 | 3.646299 18.644831 l 137 | 3.646441 18.644960 l 138 | 2.808568 19.572575 l 139 | h 140 | 2.808568 24.420908 m 141 | 1.968388 23.495377 l 142 | 1.970695 23.493294 l 143 | 2.808568 24.420908 l 144 | h 145 | 1.073568 25.995909 m 146 | 1.913745 26.921436 l 147 | 1.913403 26.921747 l 148 | 1.073568 25.995909 l 149 | h 150 | 3.421901 31.672575 m 151 | 3.485213 32.920975 l 152 | 3.481580 32.921150 l 153 | 3.421901 31.672575 l 154 | h 155 | 5.755234 31.554241 m 156 | 5.820863 32.802521 l 157 | 5.818545 32.802639 l 158 | 5.755234 31.554241 l 159 | h 160 | 9.185234 34.987576 m 161 | 7.936641 34.927864 l 162 | 7.937023 34.920734 l 163 | 9.185234 34.987576 l 164 | h 165 | 9.073567 37.322575 m 166 | 7.824940 37.263996 l 167 | 7.824995 37.262863 l 168 | 9.073567 37.322575 l 169 | h 170 | 14.750235 39.672577 m 171 | 15.676776 40.511639 l 172 | 15.674911 40.513691 l 173 | 14.750235 39.672577 l 174 | h 175 | 15.388183 37.105927 m 176 | 16.243738 36.156223 17.461990 35.614010 18.740234 35.614010 c 177 | 18.740234 38.114010 l 178 | 18.170290 38.114010 17.627092 38.355770 17.245617 38.779224 c 179 | 15.388183 37.105927 l 180 | h 181 | 18.740234 35.614010 m 182 | 20.018478 35.614010 21.236731 36.156223 22.092285 37.105927 c 183 | 20.234852 38.779224 l 184 | 19.853376 38.355770 19.310179 38.114010 18.740234 38.114010 c 185 | 18.740234 35.614010 l 186 | h 187 | 22.087446 37.100582 m 188 | 23.664112 38.830582 l 189 | 21.816357 40.514568 l 190 | 20.239691 38.784569 l 191 | 22.087446 37.100582 l 192 | h 193 | 23.667707 38.834545 m 194 | 24.239151 39.466980 25.146713 39.671444 25.934149 39.345158 c 195 | 26.891165 41.654728 l 196 | 25.126760 42.385841 23.093193 41.927696 21.812761 40.510605 c 197 | 23.667707 38.834545 l 198 | h 199 | 25.934149 39.345158 m 200 | 26.721584 39.018867 27.218538 38.232414 27.175184 37.381153 c 201 | 29.671949 37.253998 l 202 | 29.769091 39.161407 28.655571 40.923611 26.891165 41.654728 c 203 | 25.934149 39.345158 l 204 | h 205 | 27.175171 37.380886 m 206 | 27.056839 35.047554 l 207 | 29.553631 34.920933 l 208 | 29.671963 37.254265 l 209 | 27.175171 37.380886 l 210 | h 211 | 27.056812 35.047016 m 212 | 26.992802 33.773987 27.470064 32.533249 28.370710 31.631287 c 213 | 30.139769 33.397758 l 214 | 29.738005 33.800114 29.525103 34.353588 29.553658 34.921467 c 215 | 27.056812 35.047016 l 216 | h 217 | 28.370710 31.631287 m 218 | 29.271355 30.729324 30.511396 30.250244 31.784517 30.312395 c 219 | 31.662619 32.809422 l 220 | 31.094698 32.781696 30.541534 32.995407 30.139769 33.397758 c 221 | 28.370710 31.631287 l 222 | h 223 | 31.786880 30.312511 m 224 | 34.120213 30.430847 l 225 | 33.993587 32.927639 l 226 | 31.660255 32.809303 l 227 | 31.786880 30.312511 l 228 | h 229 | 34.118450 30.430759 m 230 | 34.969135 30.472698 35.754318 29.975245 36.079769 29.188160 c 231 | 38.390057 30.143440 l 232 | 37.660820 31.907059 35.901470 33.021698 33.995350 32.927727 c 233 | 34.118450 30.430759 l 234 | h 235 | 36.079769 29.188160 m 236 | 36.405220 28.401073 36.200645 27.494370 35.568760 26.923279 c 237 | 37.245045 25.068539 l 238 | 38.660908 26.348171 39.119297 28.379822 38.390057 30.143440 c 239 | 36.079769 29.188160 l 240 | h 241 | 35.569614 26.924051 m 242 | 33.832947 25.357384 l 243 | 35.507523 23.501099 l 244 | 37.244190 25.067766 l 245 | 35.569614 26.924051 l 246 | h 247 | 33.832363 25.356857 m 248 | 32.884274 24.500490 32.343208 23.282665 32.343208 22.005075 c 249 | 34.843208 22.005075 l 250 | 34.843208 22.575510 35.084789 23.119263 35.508106 23.501627 c 251 | 33.832363 25.356857 l 252 | h 253 | 32.343208 22.005075 m 254 | 32.343208 20.727486 32.884274 19.509659 33.832363 18.653294 c 255 | 35.508106 20.508522 l 256 | 35.084793 20.890884 34.843208 21.434639 34.843208 22.005075 c 257 | 32.343208 22.005075 l 258 | h 259 | 33.832947 18.652765 m 260 | 35.569614 17.086100 l 261 | 37.244190 18.942385 l 262 | 35.507523 20.509050 l 263 | 33.832947 18.652765 l 264 | h 265 | 35.568874 17.086769 m 266 | 36.201305 16.515326 36.405773 15.607765 36.079483 14.820328 c 267 | 38.389053 13.863312 l 268 | 39.120171 15.627716 38.662025 17.661283 37.244930 18.941715 c 269 | 35.568874 17.086769 l 270 | h 271 | 36.079483 14.820328 m 272 | 35.753193 14.032890 34.966740 13.535936 34.115482 13.579290 c 273 | 33.988323 11.082525 l 274 | 35.895737 10.985384 37.657940 12.098907 38.389053 13.863312 c 275 | 36.079483 14.820328 l 276 | h 277 | 34.115215 13.579304 m 278 | 31.781879 13.697638 l 279 | 31.655254 11.200846 l 280 | 33.988590 11.082512 l 281 | 34.115215 13.579304 l 282 | h 283 | 31.782782 13.697592 m 284 | 30.506868 13.763224 29.262917 13.285025 28.359516 12.381626 c 285 | 30.127285 10.613857 l 286 | 30.530277 11.016851 31.085188 11.230169 31.654352 11.200891 c 287 | 31.782782 13.697592 l 288 | h 289 | 28.359516 12.381626 m 290 | 27.456118 11.478226 26.977919 10.234274 27.043550 8.958361 c 291 | 29.540251 9.086790 l 292 | 29.510973 9.655954 29.724291 10.210865 30.127285 10.613857 c 293 | 28.359516 12.381626 l 294 | h 295 | 27.043505 8.959263 m 296 | 27.161839 6.625931 l 297 | 29.658630 6.752556 l 298 | 29.540297 9.085888 l 299 | 27.043505 8.959263 l 300 | h 301 | 27.161472 6.633610 m 302 | 27.199198 5.786846 26.702986 5.007004 25.919971 4.682472 c 303 | 26.877171 2.372978 l 304 | 28.631664 3.100147 29.743525 4.847542 29.658997 6.744877 c 305 | 27.161472 6.633610 l 306 | h 307 | 25.919971 4.682472 m 308 | 25.136955 4.357944 24.234564 4.558117 23.662224 5.183300 c 309 | 21.818245 3.495182 l 310 | 23.100689 2.094334 25.122677 1.645805 26.877171 2.372978 c 311 | 25.919971 4.682472 l 312 | h 313 | 23.667534 5.177464 m 314 | 22.099201 6.912464 l 315 | 20.244602 5.236019 l 316 | 21.812935 3.501019 l 317 | 23.667534 5.177464 l 318 | h 319 | 22.099670 6.911942 m 320 | 21.243601 7.860054 20.025974 8.401165 18.748568 8.401165 c 321 | 18.748568 5.901165 l 322 | 19.318663 5.901165 19.862078 5.659672 20.244133 5.236542 c 323 | 22.099670 6.911942 l 324 | h 325 | 18.748568 8.401165 m 326 | 17.471161 8.401165 16.253534 7.860054 15.397464 6.911942 c 327 | 17.253002 5.236542 l 328 | 17.635057 5.659672 18.178473 5.901165 18.748568 5.901165 c 329 | 18.748568 8.401165 l 330 | h 331 | 15.399705 6.914417 m 332 | 13.824706 5.179417 l 333 | 15.675763 3.499065 l 334 | 17.250763 5.234066 l 335 | 15.399705 6.914417 l 336 | h 337 | 13.825621 5.180424 m 338 | 13.254137 4.552261 12.350161 4.349819 11.565349 4.674252 c 339 | 10.610269 2.363880 l 340 | 12.368792 1.636929 14.394327 2.090530 15.674849 3.498058 c 341 | 13.825621 5.180424 l 342 | h 343 | 11.565349 4.674252 m 344 | 10.780538 4.998684 10.283373 5.780338 10.322256 6.628674 c 345 | 7.824878 6.743145 l 346 | 7.737751 4.842281 8.851746 3.090832 10.610269 2.363880 c 347 | 11.565349 4.674252 l 348 | h 349 | 10.321918 6.621708 m 350 | 10.441917 8.955040 l 351 | 7.945217 9.083443 l 352 | 7.825217 6.750111 l 353 | 10.321918 6.621708 l 354 | h 355 | 10.441916 8.955027 m 356 | 10.507549 10.230940 10.029351 11.474894 9.125952 12.378294 c 357 | 7.358185 10.610525 l 358 | 7.761178 10.207533 7.974495 9.652622 7.945218 9.083456 c 359 | 10.441916 8.955027 l 360 | h 361 | 9.125952 12.378294 m 362 | 8.222553 13.281693 6.978600 13.759892 5.702687 13.694260 c 363 | 5.831115 11.197559 l 364 | 6.400281 11.226837 6.955191 11.013519 7.358185 10.610525 c 365 | 9.125952 12.378294 l 366 | h 367 | 5.703589 13.694305 m 368 | 3.370256 13.575972 l 369 | 3.496880 11.079180 l 370 | 5.830213 11.197514 l 371 | 5.703589 13.694305 l 372 | h 373 | 3.368413 13.575876 m 374 | 2.517766 13.531477 1.731228 14.027205 1.404315 14.813780 c 375 | -0.904238 13.854311 l 376 | -0.171391 12.091028 1.591808 10.979744 3.498723 11.079275 c 377 | 3.368413 13.575876 l 378 | h 379 | 1.404315 14.813780 m 380 | 1.077403 15.600355 1.280868 16.507544 1.912397 17.079159 c 381 | 0.234739 18.932659 l 382 | -1.180972 17.651257 -1.637084 15.617594 -0.904238 13.854311 c 383 | 1.404315 14.813780 l 384 | h 385 | 1.911299 17.078165 m 386 | 3.646299 18.644831 l 387 | 1.970837 20.500319 l 388 | 0.235837 18.933653 l 389 | 1.911299 17.078165 l 390 | h 391 | 3.646441 18.644960 m 392 | 4.594529 19.501326 5.135593 20.719154 5.135593 21.996742 c 393 | 2.635594 21.996742 l 394 | 2.635594 21.426306 2.394011 20.882551 1.970695 20.500189 c 395 | 3.646441 18.644960 l 396 | h 397 | 5.135593 21.996742 m 398 | 5.135593 23.274332 4.594529 24.492157 3.646441 25.348522 c 399 | 1.970695 23.493294 l 400 | 2.394011 23.110929 2.635594 22.567179 2.635594 21.996742 c 401 | 5.135593 21.996742 l 402 | h 403 | 3.648745 25.346436 m 404 | 1.913745 26.921436 l 405 | 0.233391 25.070381 l 406 | 1.968391 23.495380 l 407 | 3.648745 25.346436 l 408 | h 409 | 1.913403 26.921747 m 410 | 1.283993 27.492691 1.080830 28.397343 1.405671 29.182587 c 411 | -0.904462 30.138248 l 412 | -1.632667 28.377945 -1.177230 26.349966 0.233732 25.070070 c 413 | 1.913403 26.921747 l 414 | h 415 | 1.405671 29.182587 m 416 | 1.730513 29.967834 2.513407 30.464573 3.362222 30.424000 c 417 | 3.481580 32.921150 l 418 | 1.578772 33.012100 -0.176256 31.898550 -0.904462 30.138248 c 419 | 1.405671 29.182587 l 420 | h 421 | 3.358590 30.424179 m 422 | 5.691923 30.305847 l 423 | 5.818545 32.802639 l 424 | 3.485212 32.920971 l 425 | 3.358590 30.424179 l 426 | h 427 | 5.689605 30.305965 m 428 | 6.967985 30.238754 8.214768 30.717577 9.119528 31.623215 c 429 | 7.350903 33.390125 l 430 | 6.947302 32.986130 6.391130 32.772537 5.820863 32.802517 c 431 | 5.689605 30.305965 l 432 | h 433 | 9.119528 31.623215 m 434 | 10.024287 32.528854 10.501899 33.776104 10.433446 35.054417 c 435 | 7.937023 34.920734 l 436 | 7.967558 34.350494 7.754503 33.794117 7.350903 33.390125 c 437 | 9.119528 31.623215 l 438 | h 439 | 10.433807 35.047287 m 440 | 10.322141 37.382286 l 441 | 7.824995 37.262863 l 442 | 7.936661 34.927864 l 443 | 10.433807 35.047287 l 444 | h 445 | 10.322194 37.381153 m 446 | 10.282377 38.229870 10.779210 39.012371 11.564253 39.337357 c 447 | 10.608013 41.647251 l 448 | 8.848975 40.919052 7.735723 39.165714 7.824941 37.263996 c 449 | 10.322194 37.381153 l 450 | h 451 | 11.564253 39.337357 m 452 | 12.349294 39.662346 13.253835 39.459984 13.825559 38.831459 c 453 | 15.674911 40.513691 l 454 | 14.393853 41.922016 12.367052 42.375450 10.608013 41.647251 c 455 | 11.564253 39.337357 l 456 | h 457 | 13.823695 38.833511 m 458 | 15.390361 37.103512 l 459 | 17.243439 38.781639 l 460 | 15.676774 40.511639 l 461 | 13.823695 38.833511 l 462 | h 463 | f 464 | n 465 | Q 466 | q 467 | 1.000000 0.000000 -0.000000 1.000000 12.490234 9.982910 cm 468 | 0.572549 0.615686 0.647059 scn 469 | 13.750000 10.000000 m 470 | 13.750000 6.548221 10.951779 3.750000 7.500000 3.750000 c 471 | 7.500000 1.250000 l 472 | 12.332492 1.250000 16.250000 5.167508 16.250000 10.000000 c 473 | 13.750000 10.000000 l 474 | h 475 | 7.500000 3.750000 m 476 | 4.048220 3.750000 1.250000 6.548221 1.250000 10.000000 c 477 | -1.250000 10.000000 l 478 | -1.250000 5.167508 2.667508 1.250000 7.500000 1.250000 c 479 | 7.500000 3.750000 l 480 | h 481 | 1.250000 10.000000 m 482 | 1.250000 13.451780 4.048220 16.250000 7.500000 16.250000 c 483 | 7.500000 18.750000 l 484 | 2.667508 18.750000 -1.250000 14.832492 -1.250000 10.000000 c 485 | 1.250000 10.000000 l 486 | h 487 | 7.500000 16.250000 m 488 | 10.951779 16.250000 13.750000 13.451780 13.750000 10.000000 c 489 | 16.250000 10.000000 l 490 | 16.250000 14.832492 12.332492 18.750000 7.500000 18.750000 c 491 | 7.500000 16.250000 l 492 | h 493 | f 494 | n 495 | Q 496 | 497 | endstream 498 | endobj 499 | 500 | 3 0 obj 501 | 11512 502 | endobj 503 | 504 | 4 0 obj 505 | << /Annots [] 506 | /Type /Page 507 | /MediaBox [ 0.000000 0.000000 39.983398 38.984619 ] 508 | /Resources 1 0 R 509 | /Contents 2 0 R 510 | /Parent 5 0 R 511 | >> 512 | endobj 513 | 514 | 5 0 obj 515 | << /Kids [ 4 0 R ] 516 | /Count 1 517 | /Type /Pages 518 | >> 519 | endobj 520 | 521 | 6 0 obj 522 | << /Pages 5 0 R 523 | /Type /Catalog 524 | >> 525 | endobj 526 | 527 | xref 528 | 0 7 529 | 0000000000 65535 f 530 | 0000000010 00000 n 531 | 0000000034 00000 n 532 | 0000011602 00000 n 533 | 0000011626 00000 n 534 | 0000011799 00000 n 535 | 0000011873 00000 n 536 | trailer 537 | << /ID [ (some) (id) ] 538 | /Root 6 0 R 539 | /Size 7 540 | >> 541 | startxref 542 | 11932 543 | %%EOF -------------------------------------------------------------------------------- /Sport Kit Interface/Resources/Resources.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // Sport Kit Interface 4 | // 5 | // Created by Roman on 11.07.2022. 6 | // 7 | 8 | import UIKit 9 | 10 | enum R { 11 | 12 | enum Strings { 13 | enum TabBar { 14 | static func title(for tab: Tabs) -> String { 15 | switch tab { 16 | case .overview: return "Overview" 17 | case .session: return "Session" 18 | case .progress: return "Progress" 19 | case .settings: return "Settings" 20 | } 21 | } 22 | } 23 | 24 | enum NavBar { 25 | static let overview = "Today" 26 | static let session = "High Intensity Cardio" 27 | static let progress = "Workout Progress" 28 | static let settings = "Settings" 29 | } 30 | 31 | enum Overview { 32 | static let allWorcoutsButton = "All Workouts" 33 | } 34 | 35 | enum Session { 36 | static let navBarStart = "Start" 37 | static let navBarPause = "Pause" 38 | static let navBarFinish = "Finish" 39 | 40 | static let elapsedTime = "Elapsed Time" 41 | static let remainingTime = "Remaining Time" 42 | 43 | static let completed = "Completed" 44 | static let remaining = "Remaining" 45 | 46 | static let workoutStats = "Workout stats" 47 | static let stepsCounter = "Steps counter" 48 | 49 | static let workoutStats1 = "Workout stats" 50 | static let averagePace = "Average pace" 51 | static let heartRate = "Heart rate" 52 | static let totalDistance = "Total distance" 53 | static let totalSteps = "Total steps" 54 | 55 | } 56 | 57 | enum Progress { 58 | static let navBarLeft = "Export" 59 | static let navBarRight = "Details" 60 | 61 | static let dailyPerformance = "Daily performance" 62 | static let last7Days = "Last 7 days" 63 | 64 | static let monthlyPerformance = "Monthly performance" 65 | static let last10Month = "Last 10 moth" 66 | } 67 | 68 | enum Settings {} 69 | } 70 | 71 | enum Images { 72 | enum TabBar { 73 | static func icon(for tab: Tabs) -> UIImage? { 74 | switch tab { 75 | case .overview: return UIImage(named: "overview_tab") 76 | case .session: return UIImage(named: "session_tab") 77 | case .progress: return UIImage(named: "progress_tab") 78 | case .settings: return UIImage(named: "settings_tab") 79 | } 80 | } 81 | } 82 | 83 | enum Session { 84 | static let hearthBeat = UIImage(named: "hearth_beat") 85 | static let stats = UIImage(named: "") 86 | 87 | enum Stats { 88 | static let distance = UIImage(named: "stats_totalDistance") 89 | static let heartRate = UIImage(named: "stats_heartRate") 90 | static let steps = UIImage(named: "stats_totalSteps") 91 | static let pace = UIImage(named: "stats_averagePace") 92 | } 93 | } 94 | 95 | enum Overview { 96 | static let checkmarkNotDone = UIImage(named: "checkmark_not_done") 97 | static let checkmarkDone = UIImage(named: "checkmark_done") 98 | static let rightArrow = UIImage(named: "right_arrow") 99 | } 100 | 101 | enum Common { 102 | static let downArrow = UIImage(named: "all_workouts") 103 | static let add = UIImage(named: "add_icon") 104 | } 105 | 106 | } 107 | 108 | enum Fonts { 109 | static func helvelticaRegular(with size: CGFloat) -> UIFont { 110 | UIFont(name: "Helvetica", size: size) ?? UIFont() 111 | } 112 | } 113 | 114 | enum Colors { 115 | static let active = UIColor(hexString: "#AF52DE") 116 | static let inactive = UIColor(hexString: "#929DA5") 117 | 118 | static let background = UIColor(hexString: "#F8F9F9") 119 | static let separator = UIColor(hexString: "#E8ECEF") 120 | static let secondary = UIColor(hexString: "#F0F3FF") 121 | 122 | static let titleGray = UIColor(hexString: "#545C77") 123 | static let subtitleGray = UIColor(hexString: "#D8D8D8") 124 | } 125 | } 126 | --------------------------------------------------------------------------------