├── FitTrack ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── Extensions │ ├── FloatAdditions.swift │ └── ViewAdditions.swift │ ├── Models │ ├── Activity │ │ └── Activity.swift │ ├── ActivityResource │ │ └── ActivityResource.swift │ └── LabelConfigurator │ │ └── LabelConfigurator.swift │ ├── RoundActivityButton │ └── RoundActivityButton.swift │ ├── AnimationView │ ├── AnimationView.xib │ ├── AnimationView.swift │ └── Animations.swift │ └── ActivityContainerView │ ├── ActivityContainerView.swift │ └── ActivityContainerView.xib ├── _Pods.xcodeproj ├── Example ├── Pods │ ├── Target Support Files │ │ ├── FitTrack │ │ │ ├── FitTrack-prefix.pch │ │ │ ├── FitTrack.modulemap │ │ │ ├── FitTrack-dummy.m │ │ │ ├── FitTrack-umbrella.h │ │ │ ├── FitTrack.xcconfig │ │ │ └── Info.plist │ │ ├── Pods-FitTrack_Tests │ │ │ ├── Pods-FitTrack_Tests.modulemap │ │ │ ├── Pods-FitTrack_Tests-dummy.m │ │ │ ├── Pods-FitTrack_Tests-umbrella.h │ │ │ ├── Pods-FitTrack_Tests.debug.xcconfig │ │ │ ├── Pods-FitTrack_Tests.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-FitTrack_Tests-acknowledgements.markdown │ │ │ ├── Pods-FitTrack_Tests-acknowledgements.plist │ │ │ ├── Pods-FitTrack_Tests-frameworks.sh │ │ │ └── Pods-FitTrack_Tests-resources.sh │ │ └── Pods-FitTrack_Example │ │ │ ├── Pods-FitTrack_Example.modulemap │ │ │ ├── Pods-FitTrack_Example-dummy.m │ │ │ ├── Pods-FitTrack_Example-umbrella.h │ │ │ ├── Pods-FitTrack_Example.debug.xcconfig │ │ │ ├── Pods-FitTrack_Example.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-FitTrack_Example-acknowledgements.markdown │ │ │ ├── Pods-FitTrack_Example-acknowledgements.plist │ │ │ ├── Pods-FitTrack_Example-frameworks.sh │ │ │ └── Pods-FitTrack_Example-resources.sh │ ├── Manifest.lock │ ├── Local Podspecs │ │ └── FitTrack.podspec.json │ └── Pods.xcodeproj │ │ └── xcshareddata │ │ └── xcschemes │ │ └── FitTrack.xcscheme ├── FitTrack │ ├── Resources │ │ ├── SFUIText-Bold.ttf │ │ ├── SFUIText-Light.ttf │ │ └── SFUIText-Regular.ttf │ ├── Images.xcassets │ │ ├── bg.imageset │ │ │ ├── bg.png │ │ │ ├── bg@2x.png │ │ │ ├── bg@3x.png │ │ │ └── Contents.json │ │ ├── logo.imageset │ │ │ ├── logo.png │ │ │ ├── logo@2x.png │ │ │ ├── logo@3x.png │ │ │ └── Contents.json │ │ ├── line.imageset │ │ │ ├── Line@2x.png │ │ │ ├── Line@3x.png │ │ │ └── Contents.json │ │ ├── grad_blue.imageset │ │ │ ├── grad_blue.png │ │ │ ├── grad_blue@2x.png │ │ │ ├── grad_blue@3x.png │ │ │ └── Contents.json │ │ ├── grad_pink.imageset │ │ │ ├── grad_pink.png │ │ │ ├── grad_pink@2x.png │ │ │ ├── grad_pink@3x.png │ │ │ └── Contents.json │ │ ├── iPhone 6.imageset │ │ │ ├── iPhone 6.png │ │ │ ├── iPhone 6@2x.png │ │ │ ├── iPhone 6@3x.png │ │ │ └── Contents.json │ │ ├── myDayFit.imageset │ │ │ ├── MyDay Fit.png │ │ │ ├── MyDay Fit@2x.png │ │ │ ├── MyDay Fit@3x.png │ │ │ └── Contents.json │ │ ├── cal_active.imageset │ │ │ ├── cal_active.png │ │ │ ├── cal_active@2x.png │ │ │ ├── cal_active@3x.png │ │ │ └── Contents.json │ │ ├── cal_normal.imageset │ │ │ ├── cal_normal.png │ │ │ ├── cal_normal@2x.png │ │ │ ├── cal_normal@3x.png │ │ │ └── Contents.json │ │ ├── dis_active.imageset │ │ │ ├── dis_active.png │ │ │ ├── dis_active@2x.png │ │ │ ├── dis_active@3x.png │ │ │ └── Contents.json │ │ ├── dis_normal.imageset │ │ │ ├── dis_normal.png │ │ │ ├── dis_normal@2x.png │ │ │ ├── dis_normal@3x.png │ │ │ └── Contents.json │ │ ├── grad_green.imageset │ │ │ ├── grad_green.png │ │ │ ├── grad_green@2x.png │ │ │ ├── grad_green@3x.png │ │ │ └── Contents.json │ │ ├── run_active.imageset │ │ │ ├── run_active.png │ │ │ ├── run_active@2x.png │ │ │ ├── run_active@3x.png │ │ │ └── Contents.json │ │ ├── run_normal.imageset │ │ │ ├── run_normal.png │ │ │ ├── run_normal@2x.png │ │ │ ├── run_normal@3x.png │ │ │ └── Contents.json │ │ ├── bike_active.imageset │ │ │ ├── bike_active.png │ │ │ ├── bike_active@2x.png │ │ │ ├── bike_active@3x.png │ │ │ └── Contents.json │ │ ├── bike_normal.imageset │ │ │ ├── bike_normal.png │ │ │ ├── bike_normal@2x.png │ │ │ ├── bike_normal@3x.png │ │ │ └── Contents.json │ │ ├── grad_orange.imageset │ │ │ ├── grad_orange.png │ │ │ ├── grad_orange@2x.png │ │ │ ├── grad_orange@3x.png │ │ │ └── Contents.json │ │ ├── grad_purple.imageset │ │ │ ├── grad_purple.png │ │ │ ├── grad_purple@2x.png │ │ │ ├── grad_purple@3x.png │ │ │ └── Contents.json │ │ ├── ic_calendar.imageset │ │ │ ├── ic_calendar.png │ │ │ ├── ic_calendar@2x.png │ │ │ ├── ic_calendar@3x.png │ │ │ └── Contents.json │ │ ├── ic_settings.imageset │ │ │ ├── ic_settings.png │ │ │ ├── ic_settings@2x.png │ │ │ ├── ic_settings@3x.png │ │ │ └── Contents.json │ │ ├── bg_white_top.imageset │ │ │ ├── bg_white_top.png │ │ │ ├── bg_white_top@2x.png │ │ │ ├── bg_white_top@3x.png │ │ │ └── Contents.json │ │ ├── sleep_active.imageset │ │ │ ├── sleep_active.png │ │ │ ├── sleep_active@2x.png │ │ │ ├── sleep_active@3x.png │ │ │ └── Contents.json │ │ ├── sleep_normal.imageset │ │ │ ├── sleep_normal.png │ │ │ ├── sleep_normal@2x.png │ │ │ ├── sleep_normal@3x.png │ │ │ └── Contents.json │ │ ├── bg_white_bottom.imageset │ │ │ ├── bg_white_bottom.png │ │ │ ├── bg_white_bottom@2x.png │ │ │ ├── bg_white_bottom@3x.png │ │ │ └── Contents.json │ │ ├── bg_white_middle.imageset │ │ │ ├── bg_white_middle.png │ │ │ ├── bg_white_middle@2x.png │ │ │ ├── bg_white_middle@3x.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Views │ │ ├── ActivityCell │ │ │ ├── ActivityTableViewCell.swift │ │ │ └── ActivityTableViewCell.xib │ │ └── TableHeaderSectionView │ │ │ ├── SegmentView.swift │ │ │ ├── TableHeaderSectionView.swift │ │ │ └── TableHeaderSectionView.xib │ ├── Protocols │ │ └── CellInterface.swift │ ├── AppDelegate.swift │ ├── ViewControllers │ │ ├── CustomNavigationController.swift │ │ └── MyDayFitViewController.swift │ ├── Info.plist │ ├── Extensions │ │ └── CustomColors.swift │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Helpers │ │ └── ZoomStartupAnimation │ │ │ └── ZoomStartupAnimation.swift │ └── DataProviders │ │ └── ActivityDataProvider │ │ └── ActivityDataProvider.swift ├── FitTrack.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── FitTrack-Example.xcscheme ├── Podfile.lock ├── Podfile ├── FitTrack.xcworkspace │ └── contents.xcworkspacedata └── Tests │ ├── Info.plist │ └── Tests.swift ├── .travis.yml ├── .gitignore ├── FitTrack.podspec ├── LICENSE ├── .github ├── ISSUE_TEMPLATE.md └── contributing.md └── README.md /FitTrack/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /FitTrack/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/FitTrack-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Example/FitTrack/Resources/SFUIText-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Resources/SFUIText-Bold.ttf -------------------------------------------------------------------------------- /Example/FitTrack/Resources/SFUIText-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Resources/SFUIText-Light.ttf -------------------------------------------------------------------------------- /Example/FitTrack/Resources/SFUIText-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Resources/SFUIText-Regular.ttf -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg.imageset/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg.imageset/bg.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg.imageset/bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg.imageset/bg@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg.imageset/bg@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg.imageset/bg@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/logo.imageset/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/logo.imageset/logo.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/line.imageset/Line@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/line.imageset/Line@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/line.imageset/Line@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/line.imageset/Line@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/logo.imageset/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/logo.imageset/logo@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/logo.imageset/logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/logo.imageset/logo@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/iPhone 6.imageset/iPhone 6@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/myDayFit.imageset/MyDay Fit@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_active.imageset/run_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_active.imageset/run_active.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_active.imageset/cal_active@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/cal_normal.imageset/cal_normal@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_active.imageset/dis_active@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/dis_normal.imageset/dis_normal@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_blue.imageset/grad_blue@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_green.imageset/grad_green@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_pink.imageset/grad_pink@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_active.imageset/run_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_active.imageset/run_active@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_active.imageset/run_active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_active.imageset/run_active@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/run_normal.imageset/run_normal@3x.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/FitTrack.modulemap: -------------------------------------------------------------------------------- 1 | framework module FitTrack { 2 | umbrella header "FitTrack-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_active.imageset/bike_active@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bike_normal.imageset/bike_normal@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_orange.imageset/grad_orange@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/grad_purple.imageset/grad_purple@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_calendar.imageset/ic_calendar@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/ic_settings.imageset/ic_settings@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_top.imageset/bg_white_top@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_active.imageset/sleep_active@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/sleep_normal.imageset/sleep_normal@3x.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/FitTrack-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FitTrack : NSObject 3 | @end 4 | @implementation PodsDummy_FitTrack 5 | @end 6 | -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/bg_white_bottom@3x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle@2x.png -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Yalantis/FitTrack/HEAD/Example/FitTrack/Images.xcassets/bg_white_middle.imageset/bg_white_middle@3x.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/FitTrack-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double FitTrackVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char FitTrackVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_FitTrack_Tests { 2 | umbrella header "Pods-FitTrack_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_FitTrack_Example { 2 | umbrella header "Pods-FitTrack_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_FitTrack_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_FitTrack_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/FitTrack.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_FitTrack_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_FitTrack_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_FitTrack_TestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_FitTrack_TestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_FitTrack_ExampleVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_FitTrack_ExampleVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FitTrack (0.1.0) 3 | 4 | DEPENDENCIES: 5 | - FitTrack (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | FitTrack: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | FitTrack: 10834979ad0611e103cee28ed491dd627f0f97dc 13 | 14 | COCOAPODS: 0.39.0 15 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FitTrack (0.1.0) 3 | 4 | DEPENDENCIES: 5 | - FitTrack (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | FitTrack: 9 | :path: ../ 10 | 11 | SPEC CHECKSUMS: 12 | FitTrack: 10834979ad0611e103cee28ed491dd627f0f97dc 13 | 14 | COCOAPODS: 0.39.0 15 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | use_frameworks! 3 | 4 | target 'FitTrack_Example', :exclusive => true do 5 | pod 'FitTrack', :path => '../' 6 | 7 | end 8 | 9 | target 'FitTrack_Tests', :exclusive => true do 10 | pod 'FitTrack', :path => '../' 11 | 12 | end 13 | 14 | -------------------------------------------------------------------------------- /Example/FitTrack.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/FitTrack.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FitTrack" "${PODS_ROOT}/Headers/Public" 3 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 4 | PODS_ROOT = ${SRCROOT} 5 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /FitTrack/Classes/Extensions/FloatAdditions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatAdditions.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 20.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Float { 12 | 13 | var cleanValue: String { 14 | return self % 1 == 0 ? String(format: "%.0f", self) : String(self) 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/line.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Line@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "Line@3x.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bg.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bg@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bg@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "logo.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "logo@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "logo@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/iPhone 6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "iPhone 6.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "iPhone 6@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "iPhone 6@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_blue.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "grad_blue.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "grad_blue@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "grad_blue@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_pink.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "grad_pink.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "grad_pink@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "grad_pink@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/myDayFit.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "MyDay Fit.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "MyDay Fit@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "MyDay Fit@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bike_active.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bike_active@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bike_active@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bike_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bike_normal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bike_normal@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bike_normal@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cal_active.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cal_active@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cal_active@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/cal_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "cal_normal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "cal_normal@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "cal_normal@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "dis_active.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "dis_active@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "dis_active@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/dis_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "dis_normal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "dis_normal@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "dis_normal@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_green.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "grad_green.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "grad_green@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "grad_green@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_orange.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "grad_orange.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "grad_orange@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "grad_orange@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/grad_purple.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "grad_purple.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "grad_purple@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "grad_purple@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_calendar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_calendar.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_calendar@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_calendar@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/ic_settings.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "ic_settings.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "ic_settings@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "ic_settings@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "run_active.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "run_active@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "run_active@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/run_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "run_normal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "run_normal@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "run_normal@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_top.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bg_white_top.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bg_white_top@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bg_white_top@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_active.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sleep_active.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "sleep_active@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "sleep_active@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/sleep_normal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "sleep_normal.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "sleep_normal@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "sleep_normal@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Views/ActivityCell/ActivityTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActivityTableViewCell.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 23.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ActivityTableViewCell: UITableViewCell, CellInterface { 12 | 13 | @IBOutlet 14 | private weak var backgroundImageView: UIImageView! 15 | 16 | func setBackgroundImage(image: UIImage) { 17 | backgroundImageView.image = image 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_bottom.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bg_white_bottom.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bg_white_bottom@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bg_white_bottom@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/bg_white_middle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bg_white_middle.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bg_white_middle@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bg_white_middle@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -workspace Example/FitTrack.xcworkspace -scheme FitTrack-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FitTrack.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "FitTrack" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-FitTrack_Tests 8 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FitTrack.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "FitTrack" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-FitTrack_Example 8 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FitTrack.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "FitTrack" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-FitTrack_Tests 8 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FitTrack.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "FitTrack" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-FitTrack_Example 8 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/FitTrack/Protocols/CellInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CellInterface.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 23.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol CellInterface { 12 | 13 | static var id: String { get } 14 | static var cellNib: UINib { get } 15 | 16 | } 17 | 18 | extension CellInterface { 19 | 20 | static var id: String { 21 | return String(Self) 22 | } 23 | 24 | static var cellNib: UINib { 25 | return UINib(nibName: id, bundle: nil) 26 | } 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /FitTrack/Classes/Models/Activity/Activity.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Activity.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 20.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct Activity { 12 | 13 | let title: String! 14 | let goal: Float! 15 | let currentProgress: Float! 16 | let activityResource: ActivityResource! 17 | 18 | public init (title: String, goal: Float, currentProgress: Float, activityResource: ActivityResource) { 19 | self.title = title 20 | self.goal = goal 21 | self.currentProgress = currentProgress 22 | self.activityResource = activityResource 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | # 33 | # Pods/ 34 | -------------------------------------------------------------------------------- /Example/FitTrack/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/FitTrack/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // FitTrack 4 | // 5 | // Created by roman.sherbakov on 07/11/2016. 6 | // Copyright (c) 2016 roman.sherbakov. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 17 | UIApplication.sharedApplication().statusBarStyle = .LightContent 18 | 19 | ZoomStartupAnimation.performAnimation(window!, navControllerIdentifier: "navigationController", backgroundImage: UIImage(named: "bg")!, animationImage: UIImage(named: "logo")!) 20 | 21 | return true 22 | } 23 | 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/FitTrack.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FitTrack", 3 | "version": "0.1.0", 4 | "summary": "Concept of a fitness app", 5 | "screenshots": "https://d13yacurqjgara.cloudfront.net/users/226733/screenshots/2337201/open-uri20151106-3-2y7q4w", 6 | "homepage": "https://github.com/Yalantis/FitTrack", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": "Yalantis", 12 | "social_media_url": "https://twitter.com/yalantis", 13 | "platforms": { 14 | "ios": "9.0" 15 | }, 16 | "source": { 17 | "git": "https://github.com/Yalantis/FitTrack.git", 18 | "tag": "0.1.0" 19 | }, 20 | "source_files": "FitTrack/Classes/**/*", 21 | "resource_bundles": { 22 | "FitTrack": [ 23 | "FitTrack/Classes/**/*.xib" 24 | ] 25 | }, 26 | "requires_arc": true 27 | } 28 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /FitTrack/Classes/RoundActivityButton/RoundActivityButton.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RoundActivityButton.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 15.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | internal class RoundActivityButton: UIButton { 12 | 13 | override init(frame: CGRect) { 14 | super.init(frame: frame) 15 | configureRoundActivityButton() 16 | } 17 | 18 | required init?(coder aDecoder: NSCoder) { 19 | fatalError("init(coder:) has not been implemented") 20 | } 21 | 22 | override func awakeFromNib() { 23 | super.awakeFromNib() 24 | 25 | configureRoundActivityButton() 26 | } 27 | 28 | private func configureRoundActivityButton() { 29 | layer.cornerRadius = frame.height / 2 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import XCTest 3 | 4 | class Tests: XCTestCase { 5 | 6 | override func setUp() { 7 | super.setUp() 8 | // Put setup code here. This method is called before the invocation of each test method in the class. 9 | } 10 | 11 | override func tearDown() { 12 | // Put teardown code here. This method is called after the invocation of each test method in the class. 13 | super.tearDown() 14 | } 15 | 16 | func testExample() { 17 | // This is an example of a functional test case. 18 | XCTAssert(true, "Pass") 19 | } 20 | 21 | func testPerformanceExample() { 22 | // This is an example of a performance test case. 23 | self.measureBlock() { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /FitTrack.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = 'FitTrack' 4 | s.version = '0.1.0' 5 | s.summary = 'Concept of a fitness app' 6 | s.screenshot = 'https://d13yacurqjgara.cloudfront.net/users/226733/screenshots/2337201/open-uri20151106-3-2y7q4w' 7 | 8 | s.homepage = 'https://github.com/Yalantis/FitTrack' 9 | s.license = { :type => "MIT", :file => "LICENSE" } 10 | s.author = "Yalantis" 11 | s.social_media_url = "https://twitter.com/yalantis" 12 | 13 | s.platform = :ios, '9.0' 14 | s.ios.deployment_target = '9.0' 15 | 16 | s.source = { :git => 'https://github.com/Yalantis/FitTrack.git', :tag => "0.1.0" } 17 | s.source_files = 'FitTrack/Classes/**/*' 18 | s.resource_bundles = { 'FitTrack' => [ 'FitTrack/Classes/**/*.xib'] } 19 | 20 | s.requires_arc = true 21 | 22 | end 23 | -------------------------------------------------------------------------------- /FitTrack/Classes/Models/ActivityResource/ActivityResource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActivityResource.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 20.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct ActivityResource { 12 | 13 | let normalActivityButtonImage: UIImage! 14 | let selectedActivityButtonImage: UIImage! 15 | let gradientImage: UIImage! 16 | let labelConfigurator: LabelConfigurator? 17 | 18 | public init(normalActivityButtonImage: UIImage, selectedActivityButtonImage: UIImage, gradientImage: UIImage, labelConfigurator: LabelConfigurator? = nil) { 19 | self.normalActivityButtonImage = normalActivityButtonImage 20 | self.selectedActivityButtonImage = selectedActivityButtonImage 21 | self.gradientImage = gradientImage 22 | self.labelConfigurator = labelConfigurator 23 | } 24 | } -------------------------------------------------------------------------------- /Example/FitTrack/ViewControllers/CustomNavigationController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomNavigationController.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 22.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CustomNavigationController: UINavigationController { 12 | 13 | static let navControllerIdentifier = "navigationController" 14 | 15 | // MARK - Lifecycle 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | configureNavigationBar() 20 | } 21 | 22 | // MARK - Private methods 23 | private func configureNavigationBar() { 24 | navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default) 25 | navigationBar.shadowImage = UIImage() 26 | navigationBar.translucent = true 27 | navigationBarHidden = true 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/FitTrack/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Yalantis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /FitTrack/Classes/Models/LabelConfigurator/LabelConfigurator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LabelConfigurator.swift 3 | // Pods 4 | // 5 | // Created by Roman on 12.07.16. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | public struct LabelConfigurator { 12 | 13 | let textColor: UIColor? 14 | 15 | let titleFontName: String? 16 | let titleFontSize: CGFloat? 17 | 18 | let currentProgressFontName: String? 19 | let currentProgressFontSize: CGFloat? 20 | 21 | let goalFontName: String? 22 | let goalLabelFontSize: CGFloat? 23 | 24 | public init(textColor: UIColor, titleFontName: String, titleFontSize: CGFloat, currentProgressFontName: String, currentProgressFontSize: CGFloat, goalFontName: String, goalLabelFontSize: CGFloat) { 25 | self.textColor = textColor 26 | 27 | self.titleFontName = titleFontName 28 | self.titleFontSize = titleFontSize 29 | 30 | self.currentProgressFontName = currentProgressFontName 31 | self.currentProgressFontSize = currentProgressFontSize 32 | 33 | self.goalFontName = goalFontName 34 | self.goalLabelFontSize = goalLabelFontSize 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Report 2 | 3 | > The more information you provide, the faster we can help you. 4 | 5 | ⚠️ Select what you want - **a feature request** or **report a bug**. Please remove the section you aren't interested in. 6 | 7 | ## A feature request 8 | 9 | ### What do you want to add? 10 | 11 | > Please describe what you want to add to the component. 12 | 13 | ### How should it look like? 14 | 15 | > Please add images. 16 | 17 | ## Report a bug 18 | 19 | ### What did you do? 20 | 21 | > Please replace this with what you did. 22 | 23 | ### What did you expect to happen? 24 | 25 | > Please replace this with what you expected to happen. 26 | 27 | ### What happened instead? 28 | 29 | > Please replace this with what happened instead. 30 | 31 | ### Your Environment 32 | 33 | - Version of the component: _insert here_ 34 | - Swift version: _insert here_ 35 | - iOS version: _insert here_ 36 | - Device: _insert here_ 37 | - Xcode version: _insert here_ 38 | - If you use Cocoapods: _run `pod env | pbcopy` and insert here_ 39 | - If you use Carthage: _run `carthage version | pbcopy` and insert here_ 40 | 41 | ### Project that demonstrates the bug 42 | 43 | > Please add a link to a project we can download that reproduces the bug. 44 | 45 | -------------------------------------------------------------------------------- /FitTrack/Classes/Extensions/ViewAdditions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewAdditions.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 22.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIView { 12 | 13 | func roundSpecificCorners(corners: UIRectCorner, cornerRadius: CGFloat) { 14 | let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(cornerRadius, cornerRadius)) 15 | let maskLayer: CAShapeLayer = CAShapeLayer() 16 | maskLayer.frame = bounds 17 | maskLayer.path = maskPath.CGPath 18 | layer.mask = maskLayer 19 | } 20 | 21 | func xibSetup(inout subview: UIView?, nibName: String) { 22 | subview = loadViewFromNib(nibName) 23 | subview!.frame = bounds 24 | subview!.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight] 25 | addSubview(subview!) 26 | } 27 | 28 | private func loadViewFromNib(nibName: String) -> UIView { 29 | let bundle = NSBundle(forClass: self.dynamicType) 30 | let nib = UINib(nibName: nibName, bundle: bundle) 31 | let view = nib.instantiateWithOwner(self, options: nil)[0] as! UIView 32 | 33 | return view 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FitTrack 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2016 Yalantis 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - http://cocoapods.org 29 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FitTrack 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2016 Yalantis 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - http://cocoapods.org 29 | -------------------------------------------------------------------------------- /Example/FitTrack/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIAppFonts 6 | 7 | SFUIText-Regular.ttf 8 | SFUIText-Light.ttf 9 | SFUIText-Bold.ttf 10 | 11 | CFBundleDevelopmentRegion 12 | en 13 | CFBundleExecutable 14 | $(EXECUTABLE_NAME) 15 | CFBundleIdentifier 16 | $(PRODUCT_BUNDLE_IDENTIFIER) 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | $(PRODUCT_NAME) 21 | CFBundlePackageType 22 | APPL 23 | CFBundleShortVersionString 24 | 1.0 25 | CFBundleSignature 26 | ???? 27 | CFBundleVersion 28 | 1 29 | LSRequiresIPhoneOS 30 | 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UIStatusBarStyle 40 | UIStatusBarStyleLightContent 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | 45 | UIViewControllerBasedStatusBarAppearance 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Example/FitTrack/Views/TableHeaderSectionView/SegmentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SegmentView.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 22.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private let segmentViewCornerRadius: CGFloat = 13.0 12 | private let segmentViewBoederWidth: CGFloat = 1.0 13 | 14 | class SegmentView: UIView { 15 | 16 | private let buttonOvalLayer = CAShapeLayer() 17 | 18 | // MARK - Lifecycle 19 | override func drawRect(rect: CGRect) { 20 | super.drawRect(rect) 21 | 22 | configureSegmentView() 23 | createButtonOvalLayer() 24 | } 25 | 26 | // MARK - Private methods 27 | private func configureSegmentView() { 28 | layer.cornerRadius = segmentViewCornerRadius 29 | layer.borderWidth = segmentViewBoederWidth 30 | layer.borderColor = UIColor.whiteColor().CGColor 31 | } 32 | 33 | private func createButtonOvalLayer() { 34 | let buttonOvalLayerHeight = bounds.height 35 | let buttonOvalLayerWidth = bounds.width / 2 36 | let buttonOvalPath = UIBezierPath(roundedRect: CGRectMake(0, 0, buttonOvalLayerWidth, buttonOvalLayerHeight), cornerRadius: segmentViewCornerRadius) 37 | buttonOvalLayer.path = buttonOvalPath.CGPath 38 | buttonOvalLayer.fillColor = UIColor.whiteColor().CGColor 39 | layer.addSublayer(buttonOvalLayer) 40 | } 41 | 42 | // MARK - Public methods 43 | func setIndicatorPosition(position: CGFloat) { 44 | buttonOvalLayer.position = CGPointMake(position, bounds.origin.y) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Example/FitTrack/Extensions/CustomColors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomColors.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 20.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | import UIKit 12 | 13 | extension UIColor { 14 | 15 | static func runActivityColor() -> UIColor { 16 | return generateColor(255.0, green: 80.0, blue: 163.0, alpha: 1) 17 | } 18 | 19 | static func caloriesActivityColor() -> UIColor { 20 | return generateColor(255.0, green: 117.0, blue: 31.0, alpha: 1) 21 | } 22 | 23 | static func distanceActivityColor() -> UIColor { 24 | return generateColor(80.0, green: 185.0, blue: 255.0, alpha: 1) 25 | } 26 | 27 | static func bikeActivityColor() -> UIColor { 28 | return generateColor(13.0, green: 202.0, blue: 172.0, alpha: 1) 29 | } 30 | 31 | static func sleepActivityColor() -> UIColor { 32 | return generateColor(111.0, green: 58.0, blue: 255.0, alpha: 1) 33 | } 34 | 35 | static func activeSegmentButtonFontBackgroundColor() -> UIColor { 36 | return generateColor(149.0, green: 121.0, blue: 229.0, alpha: 1) 37 | } 38 | 39 | static func headerSectionBackgroundColor() -> UIColor { 40 | return generateColor(117.0, green: 90.0, blue: 204.0, alpha: 1) 41 | } 42 | 43 | static func navigationBarBackgroundColor() -> UIColor { 44 | return generateColor(104.0, green: 75.0, blue: 195.0, alpha: 1) 45 | } 46 | 47 | static func generateColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> UIColor { 48 | return UIColor(red: red / 255.0, green: green / 255.0, blue: blue / 255.0, alpha: alpha) 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /Example/FitTrack/Views/TableHeaderSectionView/TableHeaderSectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TableHeaderSectionView.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 22.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private let startIndicatorPosition: CGFloat = 0.0 12 | 13 | class TableHeaderSectionView: UITableViewHeaderFooterView, CellInterface { 14 | 15 | @IBOutlet 16 | private weak var timelineButton: UIButton! 17 | 18 | @IBOutlet 19 | private weak var statisticsButton: UIButton! 20 | 21 | @IBOutlet 22 | private weak var segmentView: SegmentView! 23 | 24 | // MARK - Lifecycle 25 | override func drawRect(rect: CGRect) { 26 | super.drawRect(rect) 27 | 28 | configureButtons() 29 | } 30 | 31 | // MARK - Provate methods 32 | private func configureButtons() { 33 | timelineButton.setTitleColor(UIColor.activeSegmentButtonFontBackgroundColor(), forState: .Selected) 34 | timelineButton.setTitleColor(UIColor.whiteColor(), forState: .Normal) 35 | statisticsButton.setTitleColor(UIColor.activeSegmentButtonFontBackgroundColor(), forState: .Selected) 36 | statisticsButton.setTitleColor(UIColor.whiteColor(), forState: .Normal) 37 | timelineButton.selected = true 38 | statisticsButton.selected = false 39 | } 40 | 41 | // MARK - Actions 42 | @IBAction func timelineButtonTapped(sender: AnyObject) { 43 | timelineButton.selected = true 44 | statisticsButton.selected = false 45 | segmentView.setIndicatorPosition(startIndicatorPosition) 46 | } 47 | 48 | @IBAction func statisticsButtonTapped(sender: AnyObject) { 49 | statisticsButton.selected = true 50 | timelineButton.selected = false 51 | segmentView.setIndicatorPosition(statisticsButton.bounds.width) 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2016 Yalantis 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | Title 40 | FitTrack 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - http://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2016 Yalantis 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | Title 40 | FitTrack 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - http://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/FitTrack.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /.github/contributing.md: -------------------------------------------------------------------------------- 1 | ## How to contribute to FitTrack 2 | 3 | #### **Did you find a bug?** 4 | 5 | * **Ensure the bug was not already reported** by searching under [Issues](https://github.com/Yalantis/FitTrack/issues). 6 | 7 | * If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/Yalantis/FitTrack/issues/new). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **example project** demonstrating the expected behavior that is not occurring. 8 | 9 | * Fill appropriate section in issue template and remove the section you aren't interested in. 10 | 11 | #### **Did you write a patch that fixes a bug?** 12 | 13 | * Open a new GitHub pull request with the patch. 14 | 15 | * Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable. 16 | 17 | * Ensure the PR doesn't extend the number of existing issues. 18 | 19 | #### **Did you fix whitespace, format code, or make a purely cosmetic patch?** 20 | 21 | * Changes that are **cosmetic** in nature and **do not add anything substantial** to the stability or functionality of FitTrack will generally **not be accepted**. 22 | 23 | #### **Did you write patch that extends functionality?** 24 | 25 | * Ensure the functionality you trying to add needed not only for your case. 26 | 27 | #### Each issue will be labeled by it's `type`, `priority` and `status`. 28 | 29 | **Issue types:** 30 | * Bug 31 | * Enhancement 32 | 33 | **These are the available priority labels:** 34 | * Critical 35 | * High 36 | * Medium 37 | * Low 38 | 39 | **Status label will be assigned to your issue to keep the issue tracker easy to follow:** 40 | * Queued (will be reviewed soon) 41 | * Reviewed (assignee has read it) 42 | * Pending (will work on it soon) 43 | * Work in progress (is working on it now) 44 | * On hold 45 | * Invalid (if bug it's not reproducible) 46 | * Need feedback (signal to get people to read and comment or provide help) 47 | 48 | #### **Coding Style** 49 | 50 | * Most importantly, match the existing code style as much as possible. 51 | 52 | #### **Do you have a question?** 53 | 54 | For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com/). By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others. 55 | 56 | ## Thank you! 57 | 58 | #### [![Yalantis](https://raw.githubusercontent.com/Yalantis/PullToMakeSoup/master/PullToMakeSoupDemo/Resouces/badge_dark.png)](https://Yalantis.com/?utm_source=github) 59 | 60 | -------------------------------------------------------------------------------- /FitTrack/Classes/AnimationView/AnimationView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FitTrack 2 | [![Platform](http://img.shields.io/badge/platform-iOS-blue.svg?style=flat)](http://cocoapods.org/?q=YALSideMenu) [![License](http://img.shields.io/badge/license-MIT-green.svg?style=flat)]() 3 | 4 | Concept of a fitness app. 5 | 6 | [![Yalantis](https://raw.githubusercontent.com/Yalantis/PullToRefresh/develop/PullToRefreshDemo/Resources/badge_dark.png)](https://yalantis.com/?utm_source=github) 7 | 8 | 9 | 10 | Check this project on dribbble. 11 | 12 | ## Requirements 13 | - iOS 9.0+ 14 | - Xcode 7 15 | - Swift 2 16 | 17 | ## Installing with [CocoaPods](https://cocoapods.org) 18 | 19 | ```ruby 20 | use_frameworks! 21 | pod ‘FitTrack’, '~> 0.1.0’ 22 | ``` 23 | 24 | ## Usage 25 | 26 | At first, import FitTrack: 27 | ```swift 28 | import FitTrack 29 | ``` 30 | 31 | Then create animation view, for example, as outlet: 32 | ```swift 33 | @IBOutlet private weak var animationView: AnimationView! 34 | ``` 35 | 36 | Then create collection of activities and configure animation view (pass these activities to animation view): 37 | ```swift 38 | let activities = ActivityDataProvider.generateActivities() 39 | animationView.configureSubviews(activities.count, activities: activities) 40 | ``` 41 | 42 | Сreation of activity is as follows: 43 | ```swift 44 | // bike activity 45 | let bikeLabelConfigurator = LabelConfigurator(textColor: UIColor.bikeActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 46 | let bikeActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "bike_normal")!, selectedActivityButtonImage: UIImage(named: "bike_active")!, gradientImage: UIImage(named: "grad_green")!, labelConfigurator: bikeLabelConfigurator) 47 | let bikeActivity = Activity(title: "Miles", goal: 2.5, currentProgress: 2, activityResource: bikeActivityResource) 48 | activities.append(bikeActivity) 49 | ``` 50 | 51 | After configure animation view need to start animation: 52 | ```swift 53 | animationView.performAnimation() 54 | ``` 55 | 56 | For more information, please, see example. 57 | 58 | Have fun! :) 59 | 60 | #### Let us know! 61 | 62 | We’d be really happy if you sent us links to your projects where you use our component. Just send an email to github@yalantis.com And do let us know if you have any questions or suggestion regarding the animation. 63 | 64 | P.S. We’re going to publish more awesomeness wrapped in code and a tutorial on how to make UI for iOS (Android) better than better. Stay tuned! 65 | 66 | ## License 67 | 68 | The MIT License (MIT) 69 | 70 | Copyright © 2017 Yalantis 71 | 72 | Permission is hereby granted, free of charge, to any person obtaining a copy 73 | of this software and associated documentation files (the "Software"), to deal 74 | in the Software without restriction, including without limitation the rights 75 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 76 | copies of the Software, and to permit persons to whom the Software is 77 | furnished to do so, subject to the following conditions: 78 | 79 | The above copyright notice and this permission notice shall be included in 80 | all copies or substantial portions of the Software. 81 | 82 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 83 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 84 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 85 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 86 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 87 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 88 | THE SOFTWARE. 89 | 90 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "Pods-FitTrack_Tests/FitTrack.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "Pods-FitTrack_Tests/FitTrack.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "Pods-FitTrack_Example/FitTrack.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "Pods-FitTrack_Example/FitTrack.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Example/FitTrack/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Example/FitTrack/Helpers/ZoomStartupAnimation/ZoomStartupAnimation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomStartupAnimation.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 22.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private let startAnimationImageWidth: CGFloat = 172.0 12 | private let finishAnimationImageWidth: CGFloat = 2000.0 13 | 14 | private let transformAnimationDuration: NSTimeInterval = 0.3 15 | private let transformAnimationDelay: NSTimeInterval = 1 16 | private let maskBackgroundImageViewAnimationDuration: NSTimeInterval = 0.1 17 | private let maskBackgroundImageViewAnimationDelay: NSTimeInterval = 1.1 18 | 19 | class ZoomStartupAnimation { 20 | 21 | static func performAnimation(window: UIWindow, navControllerIdentifier: String, backgroundImage: UIImage, animationImage: UIImage) { 22 | let backgroundImageView = UIImageView(frame: UIScreen.mainScreen().bounds) 23 | backgroundImageView.image = backgroundImage 24 | 25 | window.addSubview(backgroundImageView) 26 | window.makeKeyAndVisible() 27 | 28 | let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) 29 | let navController = mainStoryboard.instantiateViewControllerWithIdentifier(navControllerIdentifier) as! UINavigationController 30 | window.rootViewController = navController 31 | 32 | navController.view.layer.mask = CALayer() 33 | navController.view.layer.mask!.contents = animationImage.CGImage 34 | navController.view.layer.mask!.bounds = CGRect(x: 0, y: 0, width: startAnimationImageWidth, height: startAnimationImageWidth) 35 | navController.view.layer.mask!.anchorPoint = CGPoint(x: 0.5, y: 0.5) 36 | navController.view.layer.mask!.position = CGPoint(x: navController.view.frame.width / 2, y: navController.view.frame.height / 2) 37 | 38 | let maskBackgroundImageView = UIImageView(frame: navController.view.layer.mask!.frame) 39 | maskBackgroundImageView.image = animationImage 40 | navController.view.addSubview(maskBackgroundImageView) 41 | navController.view.bringSubviewToFront(maskBackgroundImageView) 42 | 43 | createTransformAnimation(navController, maskBackgroundImageView: maskBackgroundImageView) 44 | maskBackgroundImageViewAnimation(maskBackgroundImageView, navController: navController) 45 | } 46 | 47 | private static func createTransformAnimation(navController: UINavigationController, maskBackgroundImageView: UIImageView) { 48 | let transformAnimation = CAKeyframeAnimation(keyPath: "bounds") 49 | transformAnimation.duration = transformAnimationDuration 50 | transformAnimation.beginTime = CACurrentMediaTime() + transformAnimationDelay 51 | let initalBounds = NSValue(CGRect: navController.view.layer.mask!.bounds) 52 | let finalBounds = NSValue(CGRect: CGRect(x: 0, y: 0, width: finishAnimationImageWidth, height: finishAnimationImageWidth)) 53 | transformAnimation.values = [initalBounds, finalBounds] 54 | transformAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)] 55 | transformAnimation.removedOnCompletion = false 56 | transformAnimation.fillMode = kCAFillModeForwards 57 | navController.view.layer.mask!.addAnimation(transformAnimation, forKey: "maskAnimation") 58 | maskBackgroundImageView.layer.addAnimation(transformAnimation, forKey: "maskAnimation") 59 | } 60 | 61 | private static func maskBackgroundImageViewAnimation(maskBackgroundImageView: UIImageView, navController: UINavigationController) { 62 | UIView.animateWithDuration(maskBackgroundImageViewAnimationDuration, 63 | delay: maskBackgroundImageViewAnimationDelay, 64 | options: .CurveEaseIn, 65 | animations: { 66 | maskBackgroundImageView.alpha = 0.0 67 | }, 68 | completion: { finished in 69 | if finished == true { 70 | maskBackgroundImageView.removeFromSuperview() 71 | navController.view.layer.mask = nil 72 | } 73 | }) 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /Example/FitTrack/DataProviders/ActivityDataProvider/ActivityDataProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ActivityDataProvider.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 20.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FitTrack 11 | 12 | class ActivityDataProvider { 13 | 14 | static func generateActivities() -> [Activity] { 15 | var activities = [Activity]() 16 | 17 | // run activity 18 | let runLabelConfigurator = LabelConfigurator(textColor: UIColor.runActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 19 | let runActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "run_normal")!, selectedActivityButtonImage: UIImage(named: "run_active")!, gradientImage: UIImage(named: "grad_pink")!, labelConfigurator: runLabelConfigurator) 20 | let runActivity = Activity(title: "Steps", goal: 1240, currentProgress: 200, activityResource: runActivityResource) 21 | activities.append(runActivity) 22 | 23 | // calories activity 24 | let caloriesLabelConfigurator = LabelConfigurator(textColor: UIColor.caloriesActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 25 | let caloriesActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "cal_normal")!, selectedActivityButtonImage: UIImage(named: "cal_active")!, gradientImage: UIImage(named: "grad_orange")!, labelConfigurator: caloriesLabelConfigurator) 26 | let caloriesActivity = Activity(title: "Calories", goal: 2000, currentProgress: 1000, activityResource: caloriesActivityResource) 27 | activities.append(caloriesActivity) 28 | 29 | // distance activity 30 | let distanceLabelConfigurator = LabelConfigurator(textColor: UIColor.distanceActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 31 | let distanceActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "dis_normal")!, selectedActivityButtonImage: UIImage(named: "dis_active")!, gradientImage: UIImage(named: "grad_blue")!, labelConfigurator: distanceLabelConfigurator) 32 | let distanceActivity = Activity(title: "Miles", goal: 1.35, currentProgress: 0.9, activityResource: distanceActivityResource) 33 | activities.append(distanceActivity) 34 | 35 | // bike activity 36 | let bikeLabelConfigurator = LabelConfigurator(textColor: UIColor.bikeActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 37 | let bikeActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "bike_normal")!, selectedActivityButtonImage: UIImage(named: "bike_active")!, gradientImage: UIImage(named: "grad_green")!, labelConfigurator: bikeLabelConfigurator) 38 | let bikeActivity = Activity(title: "Miles", goal: 2.5, currentProgress: 2, activityResource: bikeActivityResource) 39 | activities.append(bikeActivity) 40 | 41 | // sleep activity 42 | let sleepLabelConfigurator = LabelConfigurator(textColor: UIColor.sleepActivityColor(), titleFontName: "SFUIText-Light", titleFontSize: 24, currentProgressFontName: "SFUIText-Bold", currentProgressFontSize: 48, goalFontName: "SFUIText-Light", goalLabelFontSize: 14) 43 | let sleepActivityResource = ActivityResource(normalActivityButtonImage: UIImage(named: "sleep_normal")!, selectedActivityButtonImage: UIImage(named: "sleep_active")!, gradientImage: UIImage(named: "grad_purple")!, labelConfigurator: sleepLabelConfigurator) 44 | let sleepActivity = Activity(title: "Hours", goal: 8, currentProgress: 5.5, activityResource: sleepActivityResource) 45 | activities.append(sleepActivity) 46 | 47 | return activities 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Example/FitTrack.xcodeproj/xcshareddata/xcschemes/FitTrack-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Example/Pods-FitTrack_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 63 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 64 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 65 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 66 | fi 67 | rm -f "$RESOURCES_TO_COPY" 68 | 69 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 70 | then 71 | case "${TARGETED_DEVICE_FAMILY}" in 72 | 1,2) 73 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 74 | ;; 75 | 1) 76 | TARGET_DEVICE_ARGS="--target-device iphone" 77 | ;; 78 | 2) 79 | TARGET_DEVICE_ARGS="--target-device ipad" 80 | ;; 81 | *) 82 | TARGET_DEVICE_ARGS="--target-device mac" 83 | ;; 84 | esac 85 | 86 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 87 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 88 | while read line; do 89 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 90 | XCASSET_FILES+=("$line") 91 | fi 92 | done <<<"$OTHER_XCASSETS" 93 | 94 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 95 | fi 96 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FitTrack_Tests/Pods-FitTrack_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 63 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 64 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 65 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 66 | fi 67 | rm -f "$RESOURCES_TO_COPY" 68 | 69 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 70 | then 71 | case "${TARGETED_DEVICE_FAMILY}" in 72 | 1,2) 73 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 74 | ;; 75 | 1) 76 | TARGET_DEVICE_ARGS="--target-device iphone" 77 | ;; 78 | 2) 79 | TARGET_DEVICE_ARGS="--target-device ipad" 80 | ;; 81 | *) 82 | TARGET_DEVICE_ARGS="--target-device mac" 83 | ;; 84 | esac 85 | 86 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 87 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 88 | while read line; do 89 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 90 | XCASSET_FILES+=("$line") 91 | fi 92 | done <<<"$OTHER_XCASSETS" 93 | 94 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 95 | fi 96 | -------------------------------------------------------------------------------- /FitTrack/Classes/AnimationView/AnimationView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AnimationView.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 17.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | internal let ratioItemWidthToGap: CGFloat = 3.42 12 | internal let dropButtonsPositionCoefficient: CGFloat = 1.08 13 | internal let finalButtonsPositionCoefficient: CGFloat = 1.06 14 | private let transformScale: CGFloat = 0.3 15 | 16 | public class AnimationView: UIView { 17 | 18 | @IBOutlet 19 | internal weak var activityContainerView: ActivityContainerView! 20 | 21 | // fake button which determines the final position 22 | internal var centerActivityRoundButton: RoundActivityButton? 23 | internal var centerActivityRoundButtonIndex: Int = 0 24 | internal var activitiesCount: Int! 25 | internal var roundActivityButtons = [RoundActivityButton]() 26 | internal var gapBetweenActivityButtons: CGFloat = 0.0 27 | internal var realActivityButtonWidth: CGFloat = 0.0 28 | public var animationFirstPhaseDidFinish: (Void -> Void)? 29 | public var animationDidFinish: (Void -> Void)? 30 | 31 | private var activities: [Activity]? 32 | private var currentActiveRoundButtonTag = 0 33 | private var subview: UIView? 34 | 35 | // MARK - Lifecycle 36 | override init(frame: CGRect) { 37 | super.init(frame: frame) 38 | xibSetup(&subview, nibName: "AnimationView") 39 | } 40 | 41 | required public init?(coder: NSCoder) { 42 | super.init(coder: coder)! 43 | xibSetup(&subview, nibName: "AnimationView") 44 | } 45 | 46 | // MARK - Actions 47 | func roundButtonPressed(roundButton: RoundActivityButton!) { 48 | if roundButton.selected == false { 49 | roundButton.selected = true 50 | let currentActiveRoundButton = roundActivityButtons[currentActiveRoundButtonTag] 51 | currentActiveRoundButton.selected = false 52 | currentActiveRoundButtonTag = roundButton.tag 53 | activityContainerView.flipView(activities![currentActiveRoundButtonTag]) 54 | } 55 | } 56 | 57 | // MARK - Public methods 58 | public func configureSubviews(activitiesCount: Int, activities: [Activity]) { 59 | self.activitiesCount = activitiesCount 60 | self.activities = activities 61 | createAndSetStartPositionRoundActivityButtons() 62 | activityContainerView.flipView(activities[0]) 63 | } 64 | 65 | public func performAnimation() { 66 | aimateDrop() 67 | } 68 | 69 | // MARK: Private methods 70 | private func createAndSetStartPositionRoundActivityButtons() { 71 | let allContentWidth = bounds.width 72 | let buttonWidth = allContentWidth / CGFloat(activitiesCount) 73 | gapBetweenActivityButtons = (buttonWidth / ratioItemWidthToGap) 74 | let deltaWidth = gapBetweenActivityButtons / CGFloat(activitiesCount) 75 | realActivityButtonWidth = (buttonWidth - deltaWidth - gapBetweenActivityButtons) 76 | 77 | centerActivityRoundButton = RoundActivityButton.init(frame: CGRectMake(0, 0, realActivityButtonWidth * animateScalFirsteButtonCoefficient, realActivityButtonWidth * animateScalFirsteButtonCoefficient)) 78 | centerActivityRoundButton!.backgroundColor = UIColor.clearColor() 79 | centerActivityRoundButton!.center = CGPointMake(bounds.width / 2, (bounds.height / 2) / dropButtonsPositionCoefficient) 80 | 81 | centerActivityRoundButtonIndex = activitiesCount%2 == 0 ? -1 : activitiesCount / 2 82 | 83 | currentActiveRoundButtonTag = 0 84 | 85 | addSubview(centerActivityRoundButton!) 86 | for index in 0.. 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | SFUIText-Regular 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Example/FitTrack/ViewControllers/MyDayFitViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MyDayFitViewController.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman on 15.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FitTrack 11 | 12 | private let ratioCoefficient: CGFloat = 3.117 13 | private let tableHeaderSectionViewHeight: CGFloat = 114.0 14 | private let tableCellHeight: CGFloat = 105.0 15 | private let rowsCount = 10 16 | private let tableHeaderSectionViewHeightDelta: CGFloat = 64.0 17 | private let animationDuration: NSTimeInterval = 0.3 18 | private let maxHeaderSectionAlphaValue: CGFloat = 0.95 19 | private let cornerRadius: CGFloat = 12.0 20 | 21 | private enum HeaderSectionState { 22 | case VisibleState 23 | case UnvisibleState 24 | } 25 | 26 | class MyDayFitViewController: UIViewController { 27 | 28 | @IBOutlet 29 | private weak var animationView: AnimationView! 30 | 31 | @IBOutlet 32 | private weak var activityTableView: UITableView! 33 | 34 | @IBOutlet 35 | private weak var helperView: UIView! 36 | 37 | @IBOutlet 38 | private weak var activityTableViewLeadingConstraint: NSLayoutConstraint! 39 | 40 | @IBOutlet 41 | private weak var activityTableViewTrailingConstraint: NSLayoutConstraint! 42 | 43 | private var tableHeaderSectionView: TableHeaderSectionView! 44 | private var headerSectionState = HeaderSectionState.UnvisibleState 45 | private var backgroundHeaderSectionView: UIView! 46 | 47 | // MARK - Lifecycle 48 | override func viewDidLoad() { 49 | super.viewDidLoad() 50 | 51 | backgroundHeaderSectionView = UIView(frame: helperView.frame) 52 | animationView.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.width - activityTableViewLeadingConstraint.constant + activityTableViewTrailingConstraint.constant, view.frame.height) 53 | setTitleView() 54 | setupTableView() 55 | } 56 | 57 | override func viewDidAppear(animated: Bool) { 58 | super.viewDidAppear(animated) 59 | 60 | configureAnimationView() 61 | 62 | let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.3 * Double(NSEC_PER_SEC))) // perform animation after 0.3 s 63 | dispatch_after(delayTime, dispatch_get_main_queue()) { 64 | self.animationView.performAnimation() 65 | } 66 | } 67 | 68 | // MARK - Private methods 69 | private func setTitleView() { 70 | let logo = UIImage(named: "myDayFit") 71 | let imageView = UIImageView(image:logo) 72 | navigationItem.titleView = imageView 73 | } 74 | 75 | private func setupTableView() { 76 | activityTableView.registerNib(ActivityTableViewCell.cellNib, forCellReuseIdentifier: ActivityTableViewCell.id) 77 | activityTableView.registerNib(TableHeaderSectionView.cellNib, forHeaderFooterViewReuseIdentifier: TableHeaderSectionView.id) 78 | } 79 | 80 | private func configureAnimationView() { 81 | let activities = ActivityDataProvider.generateActivities() 82 | animationView.configureSubviews(activities.count, activities: activities) 83 | animationView.animationFirstPhaseDidFinish = { 84 | [UIView.beginAnimations(nil, context: nil)] 85 | [UIView.setAnimationDuration(animationDuration)] 86 | self.animationView.frame = CGRect(x: 0.0, y: 0.0, width: self.animationView.frame.width, height: self.animationView.frame.height - (self.animationView.frame.height / ratioCoefficient) - tableHeaderSectionViewHeightDelta) 87 | self.activityTableView.tableHeaderView = self.animationView 88 | self.navigationController!.navigationBarHidden = false 89 | [UIView.commitAnimations] 90 | } 91 | } 92 | 93 | // MARK - UITableViewDatasource 94 | func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 95 | return rowsCount 96 | } 97 | 98 | func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 99 | let cell = tableView.dequeueReusableCellWithIdentifier(ActivityTableViewCell.id, forIndexPath: indexPath) 100 | return cell 101 | } 102 | 103 | // MARK - UITableViewDelegate 104 | func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 105 | let activityTableViewCell = cell as! ActivityTableViewCell 106 | if indexPath.row == 0 { 107 | activityTableViewCell.setBackgroundImage(UIImage(named: "bg_white_top")!) 108 | } else if indexPath.row == rowsCount - 1 { 109 | activityTableViewCell.setBackgroundImage(UIImage(named: "bg_white_bottom")!) 110 | cell.clipsToBounds = true 111 | } else { 112 | activityTableViewCell.setBackgroundImage(UIImage(named: "bg_white_middle")!) 113 | } 114 | } 115 | 116 | func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 117 | let headerSction = tableView.dequeueReusableHeaderFooterViewWithIdentifier(TableHeaderSectionView.id) as! TableHeaderSectionView 118 | tableHeaderSectionView = headerSction 119 | backgroundHeaderSectionView.backgroundColor = UIColor.clearColor() 120 | tableHeaderSectionView.backgroundView = backgroundHeaderSectionView 121 | return headerSction 122 | } 123 | 124 | func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 125 | return tableHeaderSectionViewHeight 126 | } 127 | 128 | func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 129 | return tableCellHeight 130 | } 131 | 132 | // MARK - UIScrollViewDelegate 133 | func scrollViewDidScroll(scrollView: UIScrollView!) { 134 | if scrollView.contentOffset.y > 0 { 135 | animationView.alpha = 1 - scrollView.contentOffset.y / animationView.frame.height 136 | helperView.alpha = min(1 - animationView.alpha, maxHeaderSectionAlphaValue) 137 | if animationView.alpha <= 0 && headerSectionState == HeaderSectionState.UnvisibleState { 138 | backgroundHeaderSectionView.backgroundColor = helperView.backgroundColor?.colorWithAlphaComponent(maxHeaderSectionAlphaValue) 139 | tableHeaderSectionView.backgroundView = backgroundHeaderSectionView 140 | headerSectionState = HeaderSectionState.VisibleState 141 | } else if animationView.alpha > 0 && headerSectionState == HeaderSectionState.VisibleState { 142 | backgroundHeaderSectionView.backgroundColor = UIColor.clearColor() 143 | tableHeaderSectionView.backgroundView = backgroundHeaderSectionView 144 | headerSectionState = HeaderSectionState.UnvisibleState 145 | } 146 | } else { 147 | helperView.alpha = 0 148 | animationView.alpha = 1 149 | } 150 | 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /Example/FitTrack/Views/TableHeaderSectionView/TableHeaderSectionView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | SFUIText-Regular 10 | SFUIText-Regular 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 41 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /FitTrack/Classes/AnimationView/Animations.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Animations.swift 3 | // YALFitnessConcept 4 | // 5 | // Created by Roman Scherbakov on 17.03.16. 6 | // Copyright © 2016 Yalantis. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | private let animateDropDuration: NSTimeInterval = 0.3 12 | private let animateDropDumping: CGFloat = 0.7 13 | private let animateDropVelocity: CGFloat = 0.5 14 | 15 | private let animateExtendDistanceDuration: NSTimeInterval = 0.2 16 | private let animateExtendDistanceDelay: NSTimeInterval = 0.0 17 | 18 | private let animateCollectActivitiesDuration: NSTimeInterval = 0.25 19 | private let animateCollectActivitiesDelay: NSTimeInterval = 0.0 20 | 21 | private let animateScaleFirstButtonDuration: NSTimeInterval = 0.2 22 | private let animateScalFirsteButtonDelay: NSTimeInterval = 0.0 23 | internal let animateScalFirsteButtonCoefficient: CGFloat = 1.33 24 | 25 | private let animateMoveDuration: NSTimeInterval = 0.4 26 | private let animateMoveDelay: NSTimeInterval = 0.0 27 | 28 | private let animateScaleDuration: NSTimeInterval = 1.0 29 | private let animateScaleDelay: NSTimeInterval = 0.0 30 | private let animatScaleDumping: CGFloat = 0.3 31 | private let animateScaleVelocity: CGFloat = 0.7 32 | 33 | private let animateMoveFinalPositionDuration: NSTimeInterval = 0.3 34 | private let animateMoveFinalPositionDelay: NSTimeInterval = 0.1 35 | 36 | extension AnimationView { 37 | 38 | internal func aimateDrop() { 39 | struct Counter { 40 | static var index = 0 41 | } 42 | if Counter.index == roundActivityButtons.count { 43 | animateExtendDistance() 44 | 45 | return 46 | } 47 | let roundActivityButton = roundActivityButtons[Counter.index] 48 | let delay: NSTimeInterval = Counter.index == 0 ? 1 : 0 49 | UIView.animateWithDuration(animateDropDuration, 50 | delay: delay, 51 | usingSpringWithDamping: animateDropDumping, 52 | initialSpringVelocity: animateDropVelocity, 53 | options: .CurveLinear, 54 | animations: { 55 | let changedFrame = CGRectMake(roundActivityButton.frame.origin.x, (self.bounds.height / 2) / dropButtonsPositionCoefficient - roundActivityButton.frame.height / 2, roundActivityButton.frame.width, roundActivityButton.frame.height) 56 | roundActivityButton.frame = changedFrame 57 | }) { finished in 58 | if finished == true { 59 | Counter.index += 1 60 | self.aimateDrop() 61 | } 62 | } 63 | } 64 | 65 | private func animateExtendDistance() { 66 | UIView.animateWithDuration(animateExtendDistanceDuration, 67 | delay: animateExtendDistanceDelay, 68 | options: .CurveLinear, 69 | animations: { 70 | for index in 0.. 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /FitTrack/Classes/ActivityContainerView/ActivityContainerView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | SFUIText-Bold 10 | 11 | 12 | SFUIText-Light 13 | SFUIText-Light 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 64 | 71 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | --------------------------------------------------------------------------------