diff --git a/GetRestIOS.xcodeproj/project.pbxproj b/GetRestIOS.xcodeproj/project.pbxproj index e2bd0b2..8aff735 100644 --- a/GetRestIOS.xcodeproj/project.pbxproj +++ b/GetRestIOS.xcodeproj/project.pbxproj @@ -3,16 +3,45 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 101C8AB8252B5C2981990F9D /* Pods_GetRestIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EFDBF9252B0AFEB18C69E835 /* Pods_GetRestIOS.framework */; }; + 4B3F935022D08C21004919B1 /* PortfolioTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F934E22D08C21004919B1 /* PortfolioTableViewCell.swift */; }; + 4B3F935122D08C21004919B1 /* PortfolioTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B3F934F22D08C21004919B1 /* PortfolioTableViewCell.xib */; }; + 4B63B05022CFA523005F52D7 /* AddPortfolioViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B63B04F22CFA523005F52D7 /* AddPortfolioViewController.swift */; }; + 4B63B05222CFFFF7005F52D7 /* PortfolioDetailVC1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B63B05122CFFFF7005F52D7 /* PortfolioDetailVC1.swift */; }; + 4B63B05422D011A1005F52D7 /* PortfolioDetailVC2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B63B05322D011A1005F52D7 /* PortfolioDetailVC2.swift */; }; + 4B63B05B22D02E58005F52D7 /* ChipCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B63B05922D02E58005F52D7 /* ChipCollectionViewCell.swift */; }; + 4B63B05C22D02E58005F52D7 /* ChipCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B63B05A22D02E58005F52D7 /* ChipCollectionViewCell.xib */; }; + 4B67C18022D1D9C900B9F546 /* PortfolioModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C17F22D1D9C900B9F546 /* PortfolioModel.swift */; }; + 4B67C18322D3512500B9F546 /* RecruitListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C18222D3512500B9F546 /* RecruitListModel.swift */; }; + 4B67C18722D3536200B9F546 /* RecruitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C18622D3536200B9F546 /* RecruitViewController.swift */; }; + 4B67C18B22D3574400B9F546 /* RecruitListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C18A22D3574400B9F546 /* RecruitListCell.swift */; }; + 4B67C18D22D4055300B9F546 /* DatePickerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C18C22D4055300B9F546 /* DatePickerVC.swift */; }; + 4B67C18F22D41C7400B9F546 /* NotificationNameExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C18E22D41C7400B9F546 /* NotificationNameExtension.swift */; }; + 4B67C19122D42F9F00B9F546 /* RecruitFilterVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19022D42F9F00B9F546 /* RecruitFilterVC.swift */; }; + 4B67C19322D44DEF00B9F546 /* FIlterListTVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19222D44DEF00B9F546 /* FIlterListTVC.swift */; }; + 4B67C19522D44E1200B9F546 /* FIlterListCellCVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19422D44E1200B9F546 /* FIlterListCellCVC.swift */; }; + 4B67C19722D4BBCA00B9F546 /* RecruitDetailVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19622D4BBCA00B9F546 /* RecruitDetailVC.swift */; }; + 4B67C19922D4E1D800B9F546 /* SearchVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19822D4E1D800B9F546 /* SearchVC.swift */; }; + 4B67C19D22D5183700B9F546 /* SelectVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19C22D5183700B9F546 /* SelectVC.swift */; }; + 4B67C19F22D518A900B9F546 /* SelectTVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C19E22D518A900B9F546 /* SelectTVC.swift */; }; + 4B67C1A122D518C500B9F546 /* SelectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C1A022D518C500B9F546 /* SelectCell.swift */; }; + 4B67C1A522D5199000B9F546 /* QuestionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67C1A422D5199000B9F546 /* QuestionCell.swift */; }; 4BB47EEF22C614E300930582 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB47EEE22C614E300930582 /* AppDelegate.swift */; }; - 4BB47EF122C614E300930582 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB47EF022C614E300930582 /* ViewController.swift */; }; 4BB47EF422C614E300930582 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BB47EF222C614E300930582 /* Main.storyboard */; }; - 4BB47EF622C614E400930582 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4BB47EF522C614E400930582 /* Assets.xcassets */; }; 4BB47EF922C614E400930582 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BB47EF722C614E400930582 /* LaunchScreen.storyboard */; }; + 4BC0DD6A22D6672600517324 /* PortfolioSelectVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0DD6922D6672600517324 /* PortfolioSelectVC.swift */; }; + 4BC0DD6C22D6697500517324 /* PopUp.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BC0DD6B22D6697500517324 /* PopUp.storyboard */; }; + 4BC0DD7022D694E300517324 /* CategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0DD6F22D694E300517324 /* CategoryCell.swift */; }; + 4BC0DD7222D6953100517324 /* CategoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC0DD7122D6953100517324 /* CategoryVC.swift */; }; + 4BFE157922CC1D4E008369B9 /* PortfolioViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BFE157822CC1D4E008369B9 /* PortfolioViewController.swift */; }; + C51EAD5B22CF49E100C836A7 /* bubbleTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = C51EAD5A22CF49E100C836A7 /* bubbleTransition.swift */; }; + C56EE50D22CCE5540062F072 /* HashTagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C56EE50B22CCE5540062F072 /* HashTagCollectionViewCell.swift */; }; + C56EE51122CD063F0062F072 /* HashTagCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = C56EE51022CD063F0062F072 /* HashTagCollectionViewCell.xib */; }; + C56EE51322CD204B0062F072 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C56EE51222CD204B0062F072 /* Assets.xcassets */; }; C5ACDC9922C89B4300837653 /* Home.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5ACDC9722C89B4300837653 /* Home.storyboard */; }; C5ACDC9B22C89B7E00837653 /* Portfolio.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5ACDC9A22C89B7E00837653 /* Portfolio.storyboard */; }; C5ACDC9D22C8A3C300837653 /* MyResume.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C5ACDC9C22C8A3C300837653 /* MyResume.storyboard */; }; @@ -20,18 +49,53 @@ C5ACDCA422C8D73900837653 /* UIColor+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5ACDCA322C8D73900837653 /* UIColor+Extensions.swift */; }; C5ACDCA622C8DC5600837653 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5ACDCA522C8DC5600837653 /* UIView+Extensions.swift */; }; C5ACDCA822C8E04900837653 /* MainHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5ACDCA722C8E04900837653 /* MainHomeViewController.swift */; }; + C5D6DE9722CE021800A7EB0E /* PortfolioDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D6DE9622CE021800A7EB0E /* PortfolioDetailViewController.swift */; }; + C5D6DE9922CE0A9700A7EB0E /* PortfolioDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D6DE9822CE0A9700A7EB0E /* PortfolioDetailModel.swift */; }; + C5D6DE9D22CE3D5C00A7EB0E /* PortfolioDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5D6DE9C22CE3D5C00A7EB0E /* PortfolioDetailTableViewCell.swift */; }; + C5DC86CC22CB8F1B000C247F /* HomeGraphDetailTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5DC86CB22CB8F1B000C247F /* HomeGraphDetailTableViewCell.swift */; }; + C5DC86D222CBDC4B000C247F /* HomeGraphDetailModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5DC86D122CBDC4B000C247F /* HomeGraphDetailModel.swift */; }; + C5DC86D422CBF8D4000C247F /* CardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5DC86D322CBF8D4000C247F /* CardView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 00D5413CD194F992CD511BF0 /* Pods-GetRestIOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GetRestIOS.debug.xcconfig"; path = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.debug.xcconfig"; sourceTree = ""; }; 48F387B77A4E8B89EB6CF466 /* Pods-GetRestIOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-GetRestIOS.release.xcconfig"; path = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.release.xcconfig"; sourceTree = ""; }; + 4B3F934E22D08C21004919B1 /* PortfolioTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioTableViewCell.swift; sourceTree = ""; }; + 4B3F934F22D08C21004919B1 /* PortfolioTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PortfolioTableViewCell.xib; sourceTree = ""; }; + 4B63B04F22CFA523005F52D7 /* AddPortfolioViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddPortfolioViewController.swift; sourceTree = ""; }; + 4B63B05122CFFFF7005F52D7 /* PortfolioDetailVC1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioDetailVC1.swift; sourceTree = ""; }; + 4B63B05322D011A1005F52D7 /* PortfolioDetailVC2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioDetailVC2.swift; sourceTree = ""; }; + 4B63B05922D02E58005F52D7 /* ChipCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipCollectionViewCell.swift; sourceTree = ""; }; + 4B63B05A22D02E58005F52D7 /* ChipCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ChipCollectionViewCell.xib; sourceTree = ""; }; + 4B67C17F22D1D9C900B9F546 /* PortfolioModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioModel.swift; sourceTree = ""; }; + 4B67C18222D3512500B9F546 /* RecruitListModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecruitListModel.swift; sourceTree = ""; }; + 4B67C18622D3536200B9F546 /* RecruitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecruitViewController.swift; sourceTree = ""; }; + 4B67C18A22D3574400B9F546 /* RecruitListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecruitListCell.swift; sourceTree = ""; }; + 4B67C18C22D4055300B9F546 /* DatePickerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DatePickerVC.swift; path = GetRestIOS/Controllers/Recruit/DatePickerVC.swift; sourceTree = SOURCE_ROOT; }; + 4B67C18E22D41C7400B9F546 /* NotificationNameExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNameExtension.swift; sourceTree = ""; }; + 4B67C19022D42F9F00B9F546 /* RecruitFilterVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecruitFilterVC.swift; sourceTree = ""; }; + 4B67C19222D44DEF00B9F546 /* FIlterListTVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FIlterListTVC.swift; sourceTree = ""; }; + 4B67C19422D44E1200B9F546 /* FIlterListCellCVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FIlterListCellCVC.swift; sourceTree = ""; }; + 4B67C19622D4BBCA00B9F546 /* RecruitDetailVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecruitDetailVC.swift; sourceTree = ""; }; + 4B67C19822D4E1D800B9F546 /* SearchVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchVC.swift; sourceTree = ""; }; + 4B67C19C22D5183700B9F546 /* SelectVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectVC.swift; sourceTree = ""; }; + 4B67C19E22D518A900B9F546 /* SelectTVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTVC.swift; sourceTree = ""; }; + 4B67C1A022D518C500B9F546 /* SelectCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectCell.swift; sourceTree = ""; }; + 4B67C1A422D5199000B9F546 /* QuestionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionCell.swift; sourceTree = ""; }; 4BB47EEB22C614E300930582 /* GetRestIOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GetRestIOS.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4BB47EEE22C614E300930582 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 4BB47EF022C614E300930582 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 4BB47EF322C614E300930582 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 4BB47EF522C614E400930582 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4BB47EF822C614E400930582 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4BB47EFA22C614E400930582 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4BC0DD6922D6672600517324 /* PortfolioSelectVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioSelectVC.swift; sourceTree = ""; }; + 4BC0DD6B22D6697500517324 /* PopUp.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = PopUp.storyboard; sourceTree = ""; }; + 4BC0DD6F22D694E300517324 /* CategoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryCell.swift; sourceTree = ""; }; + 4BC0DD7122D6953100517324 /* CategoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryVC.swift; sourceTree = ""; }; + 4BFE157822CC1D4E008369B9 /* PortfolioViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioViewController.swift; sourceTree = ""; }; + C51EAD5A22CF49E100C836A7 /* bubbleTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = bubbleTransition.swift; sourceTree = ""; }; + C56EE50B22CCE5540062F072 /* HashTagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashTagCollectionViewCell.swift; sourceTree = ""; }; + C56EE51022CD063F0062F072 /* HashTagCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HashTagCollectionViewCell.xib; sourceTree = ""; }; + C56EE51222CD204B0062F072 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; C5ACDC9822C89B4300837653 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Home.storyboard; sourceTree = ""; }; C5ACDC9A22C89B7E00837653 /* Portfolio.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Portfolio.storyboard; sourceTree = ""; }; C5ACDC9C22C8A3C300837653 /* MyResume.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = MyResume.storyboard; sourceTree = ""; }; @@ -39,6 +103,12 @@ C5ACDCA322C8D73900837653 /* UIColor+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "UIColor+Extensions.swift"; path = "GetRestIOS/Storyboards/UIColor+Extensions.swift"; sourceTree = SOURCE_ROOT; }; C5ACDCA522C8DC5600837653 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = ""; }; C5ACDCA722C8E04900837653 /* MainHomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainHomeViewController.swift; sourceTree = ""; }; + C5D6DE9622CE021800A7EB0E /* PortfolioDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioDetailViewController.swift; sourceTree = ""; }; + C5D6DE9822CE0A9700A7EB0E /* PortfolioDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PortfolioDetailModel.swift; path = GetRestIOS/Storyboards/PortfolioDetailModel.swift; sourceTree = SOURCE_ROOT; }; + C5D6DE9C22CE3D5C00A7EB0E /* PortfolioDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PortfolioDetailTableViewCell.swift; sourceTree = ""; }; + C5DC86CB22CB8F1B000C247F /* HomeGraphDetailTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeGraphDetailTableViewCell.swift; sourceTree = ""; }; + C5DC86D122CBDC4B000C247F /* HomeGraphDetailModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HomeGraphDetailModel.swift; path = GetRestIOS/Storyboards/HomeGraphDetailModel.swift; sourceTree = SOURCE_ROOT; }; + C5DC86D322CBF8D4000C247F /* CardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardView.swift; sourceTree = ""; }; EFDBF9252B0AFEB18C69E835 /* Pods_GetRestIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_GetRestIOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -62,6 +132,64 @@ name = Frameworks; sourceTree = ""; }; + 4B67C18122D2E04700B9F546 /* PortfolioView */ = { + isa = PBXGroup; + children = ( + 4B3F934E22D08C21004919B1 /* PortfolioTableViewCell.swift */, + 4B3F934F22D08C21004919B1 /* PortfolioTableViewCell.xib */, + ); + path = PortfolioView; + sourceTree = ""; + }; + 4B67C18422D3531C00B9F546 /* Portfolio */ = { + isa = PBXGroup; + children = ( + 4B63B04F22CFA523005F52D7 /* AddPortfolioViewController.swift */, + 4BFE157822CC1D4E008369B9 /* PortfolioViewController.swift */, + 4B63B05122CFFFF7005F52D7 /* PortfolioDetailVC1.swift */, + 4B63B05322D011A1005F52D7 /* PortfolioDetailVC2.swift */, + 4BC0DD6F22D694E300517324 /* CategoryCell.swift */, + 4BC0DD7122D6953100517324 /* CategoryVC.swift */, + ); + path = Portfolio; + sourceTree = ""; + }; + 4B67C18522D3532800B9F546 /* Recruit */ = { + isa = PBXGroup; + children = ( + 4B67C19B22D5180D00B9F546 /* Select */, + 4B67C19A22D517EB00B9F546 /* Filter */, + 4B67C18622D3536200B9F546 /* RecruitViewController.swift */, + 4B67C18A22D3574400B9F546 /* RecruitListCell.swift */, + 4B67C18C22D4055300B9F546 /* DatePickerVC.swift */, + 4B67C19622D4BBCA00B9F546 /* RecruitDetailVC.swift */, + 4B67C19822D4E1D800B9F546 /* SearchVC.swift */, + ); + path = Recruit; + sourceTree = ""; + }; + 4B67C19A22D517EB00B9F546 /* Filter */ = { + isa = PBXGroup; + children = ( + 4B67C19022D42F9F00B9F546 /* RecruitFilterVC.swift */, + 4B67C19222D44DEF00B9F546 /* FIlterListTVC.swift */, + 4B67C19422D44E1200B9F546 /* FIlterListCellCVC.swift */, + ); + path = Filter; + sourceTree = ""; + }; + 4B67C19B22D5180D00B9F546 /* Select */ = { + isa = PBXGroup; + children = ( + 4B67C19C22D5183700B9F546 /* SelectVC.swift */, + 4B67C19E22D518A900B9F546 /* SelectTVC.swift */, + 4B67C1A422D5199000B9F546 /* QuestionCell.swift */, + 4B67C1A022D518C500B9F546 /* SelectCell.swift */, + 4BC0DD6922D6672600517324 /* PortfolioSelectVC.swift */, + ); + path = Select; + sourceTree = ""; + }; 4BB47EE222C614E300930582 = { isa = PBXGroup; children = ( @@ -99,7 +227,7 @@ 4BB47F0622C6191300930582 /* Resources */ = { isa = PBXGroup; children = ( - 4BB47EF522C614E400930582 /* Assets.xcassets */, + C56EE51222CD204B0062F072 /* Assets.xcassets */, ); path = Resources; sourceTree = ""; @@ -113,6 +241,7 @@ 4BB47EF722C614E400930582 /* LaunchScreen.storyboard */, C5ACDC9722C89B4300837653 /* Home.storyboard */, C5ACDC9A22C89B7E00837653 /* Portfolio.storyboard */, + 4BC0DD6B22D6697500517324 /* PopUp.storyboard */, ); path = Storyboards; sourceTree = ""; @@ -122,6 +251,8 @@ children = ( C5ACDCA522C8DC5600837653 /* UIView+Extensions.swift */, C5ACDCA322C8D73900837653 /* UIColor+Extensions.swift */, + C51EAD5A22CF49E100C836A7 /* bubbleTransition.swift */, + 4B67C18E22D41C7400B9F546 /* NotificationNameExtension.swift */, ); path = Extensions; sourceTree = ""; @@ -136,6 +267,10 @@ 4BB47F0A22C6193A00930582 /* Models */ = { isa = PBXGroup; children = ( + C5DC86D122CBDC4B000C247F /* HomeGraphDetailModel.swift */, + C5D6DE9822CE0A9700A7EB0E /* PortfolioDetailModel.swift */, + 4B67C17F22D1D9C900B9F546 /* PortfolioModel.swift */, + 4B67C18222D3512500B9F546 /* RecruitListModel.swift */, ); path = Models; sourceTree = ""; @@ -143,6 +278,13 @@ 4BB47F0B22C6194400930582 /* Views */ = { isa = PBXGroup; children = ( + 4B67C18122D2E04700B9F546 /* PortfolioView */, + C5DC86CB22CB8F1B000C247F /* HomeGraphDetailTableViewCell.swift */, + C5DC86D322CBF8D4000C247F /* CardView.swift */, + C5D6DE9C22CE3D5C00A7EB0E /* PortfolioDetailTableViewCell.swift */, + C56EE50F22CCE5F50062F072 /* HashTagView */, + 4B63B05922D02E58005F52D7 /* ChipCollectionViewCell.swift */, + 4B63B05A22D02E58005F52D7 /* ChipCollectionViewCell.xib */, ); path = Views; sourceTree = ""; @@ -150,8 +292,10 @@ 4BB47F0C22C6194A00930582 /* Controllers */ = { isa = PBXGroup; children = ( - 4BB47EF022C614E300930582 /* ViewController.swift */, + 4B67C18522D3532800B9F546 /* Recruit */, + 4B67C18422D3531C00B9F546 /* Portfolio */, C5ACDCA722C8E04900837653 /* MainHomeViewController.swift */, + C5D6DE9622CE021800A7EB0E /* PortfolioDetailViewController.swift */, ); path = Controllers; sourceTree = ""; @@ -165,6 +309,15 @@ path = Pods; sourceTree = ""; }; + C56EE50F22CCE5F50062F072 /* HashTagView */ = { + isa = PBXGroup; + children = ( + C56EE50B22CCE5540062F072 /* HashTagCollectionViewCell.swift */, + C56EE51022CD063F0062F072 /* HashTagCollectionViewCell.xib */, + ); + path = HashTagView; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -228,10 +381,14 @@ C5ACDCA222C8A4F200837653 /* Recruit.storyboard in Resources */, 4BB47EF922C614E400930582 /* LaunchScreen.storyboard in Resources */, C5ACDC9D22C8A3C300837653 /* MyResume.storyboard in Resources */, - 4BB47EF622C614E400930582 /* Assets.xcassets in Resources */, + 4B3F935122D08C21004919B1 /* PortfolioTableViewCell.xib in Resources */, 4BB47EF422C614E300930582 /* Main.storyboard in Resources */, + C56EE51122CD063F0062F072 /* HashTagCollectionViewCell.xib in Resources */, C5ACDC9922C89B4300837653 /* Home.storyboard in Resources */, + C56EE51322CD204B0062F072 /* Assets.xcassets in Resources */, + 4BC0DD6C22D6697500517324 /* PopUp.storyboard in Resources */, C5ACDC9B22C89B7E00837653 /* Portfolio.storyboard in Resources */, + 4B63B05C22D02E58005F52D7 /* ChipCollectionViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -266,6 +423,7 @@ files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh", @@ -273,15 +431,20 @@ "${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework", "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework", "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework", + "${BUILT_PRODUCTS_DIR}/ScrollableGraphView/ScrollableGraphView.framework", + "${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireObjectMapper.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ScrollableGraphView.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XLPagerTabStrip.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -295,11 +458,42 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BB47EF122C614E300930582 /* ViewController.swift in Sources */, + 4B67C18B22D3574400B9F546 /* RecruitListCell.swift in Sources */, + 4B67C18322D3512500B9F546 /* RecruitListModel.swift in Sources */, + C5D6DE9922CE0A9700A7EB0E /* PortfolioDetailModel.swift in Sources */, + C5D6DE9D22CE3D5C00A7EB0E /* PortfolioDetailTableViewCell.swift in Sources */, + C51EAD5B22CF49E100C836A7 /* bubbleTransition.swift in Sources */, + 4B63B05222CFFFF7005F52D7 /* PortfolioDetailVC1.swift in Sources */, + 4B67C19122D42F9F00B9F546 /* RecruitFilterVC.swift in Sources */, + 4B67C1A522D5199000B9F546 /* QuestionCell.swift in Sources */, + 4B63B05B22D02E58005F52D7 /* ChipCollectionViewCell.swift in Sources */, + 4B63B05422D011A1005F52D7 /* PortfolioDetailVC2.swift in Sources */, C5ACDCA822C8E04900837653 /* MainHomeViewController.swift in Sources */, + 4B67C19922D4E1D800B9F546 /* SearchVC.swift in Sources */, + 4B67C1A122D518C500B9F546 /* SelectCell.swift in Sources */, + 4B67C19522D44E1200B9F546 /* FIlterListCellCVC.swift in Sources */, + 4B63B05022CFA523005F52D7 /* AddPortfolioViewController.swift in Sources */, C5ACDCA422C8D73900837653 /* UIColor+Extensions.swift in Sources */, + C56EE50D22CCE5540062F072 /* HashTagCollectionViewCell.swift in Sources */, + 4B67C19722D4BBCA00B9F546 /* RecruitDetailVC.swift in Sources */, + C5D6DE9722CE021800A7EB0E /* PortfolioDetailViewController.swift in Sources */, + 4B67C18722D3536200B9F546 /* RecruitViewController.swift in Sources */, + C5DC86CC22CB8F1B000C247F /* HomeGraphDetailTableViewCell.swift in Sources */, + 4B67C18F22D41C7400B9F546 /* NotificationNameExtension.swift in Sources */, + C5DC86D222CBDC4B000C247F /* HomeGraphDetailModel.swift in Sources */, + 4B67C18D22D4055300B9F546 /* DatePickerVC.swift in Sources */, + 4BC0DD7022D694E300517324 /* CategoryCell.swift in Sources */, + 4B67C19F22D518A900B9F546 /* SelectTVC.swift in Sources */, + 4BFE157922CC1D4E008369B9 /* PortfolioViewController.swift in Sources */, + 4BC0DD6A22D6672600517324 /* PortfolioSelectVC.swift in Sources */, C5ACDCA622C8DC5600837653 /* UIView+Extensions.swift in Sources */, + C5DC86D422CBF8D4000C247F /* CardView.swift in Sources */, + 4BC0DD7222D6953100517324 /* CategoryVC.swift in Sources */, 4BB47EEF22C614E300930582 /* AppDelegate.swift in Sources */, + 4B3F935022D08C21004919B1 /* PortfolioTableViewCell.swift in Sources */, + 4B67C18022D1D9C900B9F546 /* PortfolioModel.swift in Sources */, + 4B67C19D22D5183700B9F546 /* SelectVC.swift in Sources */, + 4B67C19322D44DEF00B9F546 /* FIlterListTVC.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/GetRestIOS.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist b/GetRestIOS.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist index f8625a9..16699e9 100644 --- a/GetRestIOS.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/GetRestIOS.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ GetRestIOS.xcscheme_^#shared#^_ orderHint - 1 + 6 diff --git a/GetRestIOS.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist b/GetRestIOS.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist index eae66dd..c955db6 100644 --- a/GetRestIOS.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/GetRestIOS.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ GetRestIOS.xcscheme_^#shared#^_ orderHint - 5 + 8 diff --git a/GetRestIOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/GetRestIOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..949b678 --- /dev/null +++ b/GetRestIOS.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/GetRestIOS.xcworkspace/xcuserdata/gyeongseon.xcuserdatad/UserInterfaceState.xcuserstate b/GetRestIOS.xcworkspace/xcuserdata/gyeongseon.xcuserdatad/UserInterfaceState.xcuserstate index 8c0ec08..944e02c 100644 Binary files a/GetRestIOS.xcworkspace/xcuserdata/gyeongseon.xcuserdatad/UserInterfaceState.xcuserstate and b/GetRestIOS.xcworkspace/xcuserdata/gyeongseon.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/GetRestIOS/Controllers/MainHomeViewController.swift b/GetRestIOS/Controllers/MainHomeViewController.swift index 63ee9f4..4e0dfe8 100644 --- a/GetRestIOS/Controllers/MainHomeViewController.swift +++ b/GetRestIOS/Controllers/MainHomeViewController.swift @@ -6,31 +6,183 @@ // Copyright © 2019 최리안. All rights reserved. // -import UIKit +import UIKit +import ScrollableGraphView -class MainHomeViewController: UIViewController { - @IBOutlet weak var topSideView: UIView! +class MainHomeViewController: UIViewController { + var barPlotData: [Double] = [ 7, 4, 7, 6, 3, 7, 3, 4, 3, 2, 7, 4] + var xAxisLabels: [String] = ["1" ,"2","3", "4", "1" ,"2","3", "4", "1" ,"2","3", "4",] + var graphDetailList : [HomeGraphDetailModel] = [ +// HomeGraphDetailModel("솝트", "2019.03 ~ 2019.07"), +// HomeGraphDetailModel("매디", "2018.01 ~ 2019.12"), +// HomeGraphDetailModel("매디", "2018.01 ~ 2019.12"), +// HomeGraphDetailModel("매디", "2018.01 ~ 2019.12"), +// HomeGraphDetailModel("매디", "2018.01 ~ 2019.12") + ] + + @IBOutlet weak var scrollView: UIScrollView! + @IBOutlet weak var topSideView: UIImageView! + @IBOutlet weak var topSideLabel: UILabel! + @IBOutlet weak var graphView: UIView! + @IBOutlet weak var graphDetailTableView: UITableView! + @IBOutlet weak var firstSectionView: UIView! + @IBOutlet weak var secondSectionView: UIView! + + + var scrollViewContentHeight = 1200 as CGFloat + let navigationBarHeight = 64 as CGFloat + var tableCellHeight = 64 as CGFloat + var tableHeight = 1000 as CGFloat + + var username: String = "박경선" + override func viewDidLoad() { super.viewDidLoad() + view.backgroundColor = UIColor.mainBackgroudGray + setTableView() + setTopSideView() + setGraph(containerView: graphView) + graphDetailTableView.reloadData() + let attributedString = NSMutableAttributedString() + .bold(username, fontSize: 23) + .normal("님의 \n기록을 살펴 볼까요?", fontSize: 23) + topSideLabel.attributedText = attributedString + firstSectionView.dropShadow(color: UIColor.shadow, offSet: CGSize.zero, opacity: 1.0, radius: 5) + secondSectionView.dropShadow(color: UIColor.shadow, offSet: CGSize.zero, opacity: 1.0, radius: 5) + } + + func setTableView() { + self.graphDetailTableView.delegate = self + self.graphDetailTableView.dataSource = self +// self.graphDetailTableView.estimatedRowHeight = tableCellHeight +// self.graphDetailTableView.rowHeight = UITableView.automaticDimension + self.graphDetailTableView.backgroundColor = UIColor.white + self.graphDetailTableView.separatorColor = UIColor.mainBackgroudGray + self.graphDetailTableView.alwaysBounceVertical = false +// self.graphDetailTableView.isScrollEnabled = false + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewDidAppear(animated) + setNavigationBar() + } + func setNavigationBar(){ navigationController?.navigationBar.barTintColor = UIColor.mainGreen + // 불투명하게 만들기 navigationController?.navigationBar.isTranslucent = false + navigationController?.navigationBar.setBackgroundImage(UIImage(named: "navigationBarWithLogo"), for: .default) + navigationController?.navigationBar.shadowImage = UIImage() - topSideView.backgroundColor = UIColor.mainGreen + } + + func setTopSideView(){ + topSideView.backgroundColor = UIColor(patternImage: UIImage(named: "homeTopSideViewImg")!) topSideView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 28) - - // Do any additional setup after loading the view. + + topSideLabel.text = "\(username)님의\n기록을 살펴볼까요?" + topSideLabel.numberOfLines = 0 } + func attributedText(withString string: String, boldString: String, font: UIFont) -> String { + let attributedString = NSMutableAttributedString(string: string, attributes: [NSAttributedString.Key.font: font]) + let boldFontAttribute: [NSAttributedString.Key: Any] = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: font.pointSize)] + let range = (string as NSString).range(of: boldString) + attributedString.addAttributes(boldFontAttribute, range: range) + return attributedString.string + } +} - /* - // MARK: - Navigation +extension MainHomeViewController : ScrollableGraphViewDataSource { + func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double { + return barPlotData[pointIndex] + } + + func label(atIndex pointIndex: Int) -> String { + return xAxisLabels[pointIndex] + } + + func numberOfPoints() -> Int { + return xAxisLabels.count + } + + func setGraph(containerView: UIView) { + drawReferenceLine(containerView) + let frame : CGRect = CGRect(x: 0, + y: 0, + width: self.graphView.frame.width, + height: self.graphView.frame.height) + let barGraphView = ScrollableGraphView(frame: frame, dataSource: self) + let barPlot = BarPlot(identifier: "bar") + + barPlot.barWidth = 12 + barPlot.barLineWidth = 0 + barPlot.barColor = UIColor.graphBarGray + +// barPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic +// barPlot.animationDuration = 1.5 + barGraphView.topMargin = 0 + barGraphView.bottomMargin = 16 + barGraphView.dataPointSpacing = 27 + + barGraphView.leftmostPointPadding = 20 + let referenceLines = ReferenceLines() + +// referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 7) + referenceLines.dataPointLabelFont = UIFont.systemFont(ofSize: 14) + referenceLines.referenceLineColor = UIColor.graphLineGray + referenceLines.referenceLineLabelColor = UIColor.mainColorBlue + referenceLines.dataPointLabelColor = UIColor.mainColorBlue +// referenceLines.shouldShowReferenceLines = false + referenceLines.shouldAddLabelsToIntermediateReferenceLines = false + referenceLines.shouldAddUnitsToIntermediateReferenceLineLabels = false + + barGraphView.backgroundFillColor = UIColor.graphBackgroundWhite + barGraphView.shouldAnimateOnStartup = false + + barGraphView.rangeMax = barPlotData.max()! + barGraphView.rangeMin = 0 + + barGraphView.addReferenceLines(referenceLines: referenceLines) + barGraphView.addPlot(plot: barPlot) + + containerView.addSubview(barGraphView) + } + + func drawReferenceLine(_ containerView: UIView){ + } +} - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. +extension MainHomeViewController : UITableViewDataSource, UITableViewDelegate { + func numberOfSections(in tableView: UITableView) -> Int { + return 1 + } + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return graphDetailList.count } - */ + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "graphDetailTableViewCell") as! HomeGraphDetailTableViewCell + cell.contentView.backgroundColor = UIColor.white + cell.portfolioTitle?.text = graphDetailList[indexPath.row].portfolioTitle! + cell.portfolioDuration?.text = graphDetailList[indexPath.row].portfolioDuration! + return cell + } +} +extension NSMutableAttributedString { + + func bold(_ text: String, fontSize: CGFloat) -> NSMutableAttributedString { + let attrs: [NSAttributedString.Key: Any] = [.font: UIFont.boldSystemFont(ofSize: fontSize)] + self.append(NSMutableAttributedString(string: text, attributes: attrs)) + return self + } + + func normal(_ text: String, fontSize: CGFloat) -> NSMutableAttributedString { + let attrs: [NSAttributedString.Key: Any] = [.font: UIFont.systemFont(ofSize: fontSize)] + self.append(NSMutableAttributedString(string: text, attributes: attrs)) + return self + } } + + diff --git a/GetRestIOS/Controllers/Portfolio/AddPortfolioViewController.swift b/GetRestIOS/Controllers/Portfolio/AddPortfolioViewController.swift new file mode 100644 index 0000000..805df51 --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/AddPortfolioViewController.swift @@ -0,0 +1,43 @@ +// +// AddPortfolioViewController.swift +// GetRestIOS +// +// Created by 최리안 on 06/07/2019. +// Copyright © 2019 최리안. All rights reserved. ㄴㄴ +// + +import UIKit + +class AddPortfolioViewController: UIViewController { + + @IBOutlet var categoryLabel: UILabel! + @IBOutlet var cateBtnClick: UIView! +// var label: String = "" + + override func viewDidLoad() { + super.viewDidLoad() + + + let gesture = UITapGestureRecognizer(target: self, action: #selector(AddPortfolioViewController.goCategory(sender:))) + self.cateBtnClick.addGestureRecognizer(gesture) +// categoryLabel.text = "카테고리??" + NotificationCenter.default.addObserver(forName: .CategoryData, object: nil, queue: OperationQueue.main) { (notification) in + let dateVc = notification.object as! CategoryVC + self.categoryLabel.text = dateVc.CategoryLabel + } + } + + @objc func goCategory(sender:UIGestureRecognizer) { + + let storyboard = UIStoryboard(name: "Portfolio", bundle: nil) + let vc = storyboard.instantiateViewController(withIdentifier: "CategoryVC") +// let vc = storyboard?.instantiateViewController(withIdentifier: "CategoryVC") as! CategoryVC + self.present(vc, animated: true) + + } + + + + + +} diff --git a/GetRestIOS/Controllers/Portfolio/CategoryCell.swift b/GetRestIOS/Controllers/Portfolio/CategoryCell.swift new file mode 100644 index 0000000..3ffa3f3 --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/CategoryCell.swift @@ -0,0 +1,30 @@ +// +// CategoryCell.swift +// GetRestIOS +// +// Created by 최리안 on 11/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class CategoryCell: UITableViewCell { + + @IBOutlet var cellBackground: UIView! + @IBOutlet var cateLabel: UILabel! + @IBOutlet var bottomLine: UIView! + var isChceked = false + + override func awakeFromNib() { + super.awakeFromNib() + bottomLine.backgroundColor = .bottomGray + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/GetRestIOS/Controllers/Portfolio/CategoryVC.swift b/GetRestIOS/Controllers/Portfolio/CategoryVC.swift new file mode 100644 index 0000000..bf2dd99 --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/CategoryVC.swift @@ -0,0 +1,95 @@ +// +// CategoryVC.swift +// GetRestIOS +// +// Created by 최리안 on 11/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class CategoryVC: UIViewController, UITableViewDelegate, UITableViewDataSource { + + @IBOutlet var backBtnView: UIView! + @IBOutlet var cateTV: UITableView! + var cate: [String] = ["대외활동", "학교활동", "공모전", "경력사항", "기타"] + var selectCate: Int = 10 + var selectCateIndex: IndexPath = [] + var CategoryLabel: String = "" + var ll: String = "" + + override func viewDidLoad() { + super.viewDidLoad() + + cateTV.delegate = self + cateTV.dataSource = self + let gesture = UITapGestureRecognizer(target: self, action: #selector(CategoryVC.goBack(sender:))) + self.backBtnView.addGestureRecognizer(gesture) + } + + @objc func goBack(sender:UIGestureRecognizer) { +// let storyboard = UIStoryboard(name: "Portfolio", bundle: nil) +// let dvc = storyboard.instantiateViewController(withIdentifier: "AddPortfolioViewController") as! AddPortfolioViewController + if selectCate == 10 { + CategoryLabel = "카테고리" + } else { + CategoryLabel = cate[selectCate] + } + NotificationCenter.default.post(name: .CategoryData, object: self) + dismiss(animated: true) + } + + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return cate.count + } + + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for: indexPath) as! CategoryCell + + cell.cateLabel.text = cate[indexPath.row] + + if ll == self.cate[indexPath.row] { + cell.isChceked = true + cell.cateLabel.textColor = .white + cell.backgroundColor = .barMainGreen + } + + return cell + } + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + + let cell = tableView.cellForRow(at: indexPath) as! CategoryCell + + if cell.isChceked { + print("off") + cell.cateLabel.textColor = .btnBarItemTitleColor + cell.backgroundColor = .white + cell.isChceked = false + selectCate = 10 + + } + else { + if (selectCate != indexPath.row) && (selectCate != 10) { + let cell_ = tableView.cellForRow(at: selectCateIndex) as! CategoryCell + cell_.cateLabel.textColor = .btnBarItemTitleColor + cell_.backgroundColor = .white + cell_.isChceked = false + + cell.isChceked = true + cell.cateLabel.textColor = .white + cell.backgroundColor = .barMainGreen + } else { + cell.isChceked = true + cell.cateLabel.textColor = .white + cell.backgroundColor = .barMainGreen + } + print("on") + selectCateIndex = indexPath + selectCate = indexPath.row + cell.isChceked = true + } + } + +} diff --git a/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC1.swift b/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC1.swift new file mode 100644 index 0000000..4db699c --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC1.swift @@ -0,0 +1,126 @@ +// +// PortfolioDetailVC1.swift +// GetRestIOS +// +// Created by 최리안 on 06/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit +import XLPagerTabStrip + +class PortfolioDetailVC1: UIViewController, IndicatorInfoProvider { + + @IBOutlet var portfolioTableView: UITableView! + + var tabTitle: String = "" + var list: [PortfoliolModel] = [] + + override func viewDidLoad() { + + portfolioTableView.delegate = self + portfolioTableView.dataSource = self + + super.viewDidLoad() + + let nibName = UINib(nibName: "PortfolioTableViewCell", bundle: nil) + portfolioTableView.register(nibName, forCellReuseIdentifier: "PortfolioCell") + + setData() + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { + return IndicatorInfo(title: "\(tabTitle)") + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + if let index = portfolioTableView.indexPathForSelectedRow { + portfolioTableView.deselectRow(at: index, animated: true) + } + } +} + +extension PortfolioDetailVC1: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + +// func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { +// return 160 +// } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = portfolioTableView.dequeueReusableCell(withIdentifier: "PortfolioCell", for: indexPath) as! PortfolioTableViewCell + + let data = list[indexPath.row] + +// if indexPath.row == 1 { +// cell.backgroundColor = .black +// +// } + cell.portfolioTitle.text = data.pfTitle + cell.portfolioDate.text = data.pfDate + cell.portfolioImg.image = data.pfImg +// cell.separatorInset = UIEdgeInsets.zero +// cell.portfolioTitle.sizeToFit() + + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { +// let dvc = storyboard?.instantiateViewController(withIdentifier: "") as! + +// let music = musicList[indexPath.row] +// +// dvc.albumImg = music.albumImg +// dvc.musicTitle = music.musicTitle +// dvc.singer = music.singer +// +// present(dvc, animated: true) + // navigationController?.pushViewController(dvc, animated: true) + } + + func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + return true + } + + func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { + /* + 테이블 뷰 의 row 를 변화시키면 그에 따라 대응되는 모델(데이터)도 변화시켜주어야 합니다. + sourceIndexPath와 destinationIndexPath를 통해 이동을 시작한 index와 새롭게 설정된 index를 가져올 수 있습니다. + */ + let movingIndex = list[sourceIndexPath.row] + + list.remove(at: sourceIndexPath.row) + list.insert(movingIndex, at: destinationIndexPath.row) + } + + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + list.remove(at: indexPath.row) + tableView.deleteRows(at: [indexPath], with: .automatic) + } + } +} + +extension PortfolioDetailVC1 { + func setData() { + let pf1 = PortfoliolModel(img: "icImg", title: "솝트1", date: "2019.03 ~ 2019.07") + let pf2 = PortfoliolModel(img: "icImg", title: "솝트2", date: "2019.03 ~ 2019.07") + let pf3 = PortfoliolModel(img: "icImg", title: "솝트3", date: "2019.03 ~ 2019.07") + let pf4 = PortfoliolModel(img: "icImg", title: "솝트4", date: "2019.03 ~ 2019.07") + let pf5 = PortfoliolModel(img: "icImg", title: "솝트5", date: "2019.03 ~ 2019.07") + let pf6 = PortfoliolModel(img: "icImg", title: "솝트6", date: "2019.03 ~ 2019.07") + let pf7 = PortfoliolModel(img: "icImg", title: "솝트7", date: "2019.03 ~ 2019.07") + let pf8 = PortfoliolModel(img: "icImg", title: "솝트8", date: "2019.03 ~ 2019.07") + + list = [pf1, pf2, pf3, pf4, pf5, pf6, pf7, pf8] + } +} + diff --git a/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC2.swift b/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC2.swift new file mode 100644 index 0000000..eb1650f --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/PortfolioDetailVC2.swift @@ -0,0 +1,40 @@ +// +// PortfolioDetailVC2.swift +// GetRestIOS +// +// Created by 최리안 on 06/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit +import XLPagerTabStrip + +class PortfolioDetailVC2: UIViewController, IndicatorInfoProvider { + + @IBOutlet weak var label: UILabel! + var tabTitle: String = "" + + override func viewDidLoad() { + super.viewDidLoad() + + // label.text = tabTitle + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { + return IndicatorInfo(title: "\(tabTitle)") + } + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Controllers/Portfolio/PortfolioViewController.swift b/GetRestIOS/Controllers/Portfolio/PortfolioViewController.swift new file mode 100644 index 0000000..3341872 --- /dev/null +++ b/GetRestIOS/Controllers/Portfolio/PortfolioViewController.swift @@ -0,0 +1,161 @@ +// +// PortfolioViewController.swift +// GetRestIOS +// +// Created by 최리안 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit +import XLPagerTabStrip + +class PortfolioViewController: ButtonBarPagerTabStripViewController { + override func viewDidLoad() { + configureButtonBar() + + super.viewDidLoad() + setNavigationBar() + + + // Do any additional setup after loading the view. + } + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + + // MARK: - Configuration + + func configureButtonBar() { + // Sets the background colour of the pager strip and the pager strip item + settings.style.buttonBarBackgroundColor = .white + settings.style.buttonBarItemBackgroundColor = .white + + // Sets the pager strip item font and font color + settings.style.buttonBarItemFont = UIFont(name: "Apple SD 산돌고딕 Neo", size: 17.0 )! + settings.style.buttonBarItemTitleColor = .btnBarItemTitleColor + + // Sets the pager strip item offsets + settings.style.buttonBarMinimumLineSpacing = 0 + settings.style.buttonBarItemsShouldFillAvailableWidth = true + settings.style.buttonBarLeftContentInset = 16 + settings.style.buttonBarRightContentInset = 16 + + // Sets the height and colour of the slider bar of the selected pager tab + settings.style.selectedBarHeight = 3.0 + settings.style.selectedBarBackgroundColor = .barMainGreen + +// settings.style.buttonBarHeight = 100 + + // Changing item text color on swipe + changeCurrentIndexProgressive = { [weak self] (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in + guard changeCurrentIndex == true else { return } + oldCell?.label.textColor = .btnBarItemTitleColor + newCell?.label.textColor = .barMainGreen + } + } + + // MARK: - PagerTabStripDataSource + + override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { + + let tab1 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC1") as! PortfolioDetailVC1 + tab1.tabTitle = "전체" + + let tab2 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC2") as! PortfolioDetailVC2 + tab2.tabTitle = "대외활동" + + let tab3 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC1") as! PortfolioDetailVC1 + tab3.tabTitle = "학교활동" + + let tab4 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC2") as! PortfolioDetailVC2 + tab4.tabTitle = "공모전" + + let tab5 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC1") as! PortfolioDetailVC1 + tab5.tabTitle = "경력사항" + + let tab6 = UIStoryboard.init(name: "Portfolio", bundle: nil).instantiateViewController(withIdentifier: "PortfolioDetailVC1") as! PortfolioDetailVC1 + tab6.tabTitle = "기타" + + return [tab1, tab2, tab3, tab4, tab5, tab6] + } + + + @IBAction func addBtn(_ sender: Any) { + + guard let dvc = storyboard?.instantiateViewController(withIdentifier: "AddPortfolioViewController") as? AddPortfolioViewController + else { + return + } + + //네비게이션 컨트롤러를 이용하여 push를 해줍니다. + navigationController?.pushViewController(dvc, animated: true) + } + + func setNavigationBar(){ + navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44) + navigationController?.navigationBar.isTranslucent = false + + + let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 78, height: 17)) + imageView.contentMode = .scaleAspectFit + + let image = UIImage(named: "icPortfolio") + imageView.image = image + + self.navigationItem.titleView = imageView + self.navigationController?.navigationBar.tintColor = .barMainGreen + self.navigationController?.navigationBar.barTintColor = .white + self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) + + self.navigationController?.navigationBar.clipsToBounds = true + + let backBarButtton = UIBarButtonItem(title: "기록보기", style: .plain, target: nil, action: nil) + navigationItem.backBarButtonItem = backBarButtton + } + + +} + + + +//class PortfolioViewController: UIViewController { +// +// override func viewDidLoad() { +// super.viewDidLoad() +// setNavigationBar() +// +// +// // Do any additional setup after loading the view. +// } +// @IBAction func addBtn(_ sender: Any) { +// +// guard let dvc = storyboard?.instantiateViewController(withIdentifier: "AddPortfolio") as? AddPortfolioViewController +// else { +// return +// } +// +// //네비게이션 컨트롤러를 이용하여 push를 해줍니다. +// navigationController?.pushViewController(dvc, animated: true) +// } +// +// func setNavigationBar(){ +// navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44) +// navigationController?.navigationBar.isTranslucent = false +// +// +// let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 78, height: 17)) +// imageView.contentMode = .scaleAspectFit +// +// let image = UIImage(named: "icPortfolio") +// imageView.image = image +// +// self.navigationItem.titleView = imageView +// self.navigationController?.navigationBar.tintColor = .white +// self.navigationController?.navigationBar.barTintColor = UIColor.mainGreen +// +// let backBarButtton = UIBarButtonItem(title: "기록보기", style: .plain, target: nil, action: nil) +// navigationItem.backBarButtonItem = backBarButtton +// } +// +// +//} diff --git a/GetRestIOS/Controllers/PortfolioDetailViewController.swift b/GetRestIOS/Controllers/PortfolioDetailViewController.swift new file mode 100644 index 0000000..0cf896e --- /dev/null +++ b/GetRestIOS/Controllers/PortfolioDetailViewController.swift @@ -0,0 +1,102 @@ +// +// PortfolioDetailViewController.swift +// GetRestIOS +// +// Created by 박경선 on 04/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class PortfolioDetailTableViewController: UITableViewController { + var portfolioDetail : PortfolioDetailModel = + PortfolioDetailModel("동아리", "솝트", "2019.03 ~ 2019.07", ["UI디자인", "동아리"], "여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나여행이 취미인 트리플 직원들은 어디로 가야하나 허허허허ㅓ허허ㅓㅇ여행이 취미인 트리플 직원들은 어디로 가야하나") + + @IBOutlet weak var categoryLabel: UILabel! + @IBOutlet weak var titleLabel: UILabel! + @IBOutlet weak var durationLabel: UILabel! + @IBOutlet weak var hashTagsCollectionView: UICollectionView! + @IBOutlet weak var contentTextView: UITextView! + @IBOutlet weak var contentView: UIView! + + override func viewDidLoad() { + super.viewDidLoad() + setTableData() + setCollectionView() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + setNavigationBar() + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + navigationController?.navigationBar.setBackgroundImage(UIImage(named: "navigationBarWithLogo"), for: .default) + } + + func setNavigationBar() { + navigationController?.navigationBar.backItem?.backBarButtonItem?.title = "기록보기" + navigationController?.navigationBar.barTintColor = UIColor.mainGreen + navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) + navigationController?.navigationBar.shadowImage = UIImage() + } + + func setTableData(){ + self.categoryLabel.text = portfolioDetail.portfolioCategory + self.titleLabel.text = portfolioDetail.portfolioTitle + self.durationLabel.text = portfolioDetail.portfolioDuration + self.contentTextView.text = portfolioDetail.portfolioContent + + // 내용에 따라 테이블 셀 높이 지정 ( 40은 gap ) + contentView.frame.size.height = contentTextView.frame.height + 40 + contentTextView.isScrollEnabled = false + + var frame = self.contentTextView.frame + frame.size.height = self.contentTextView.contentSize.height + self.contentTextView.frame = frame + + // 테이블 뷰 크기 조정 + let tableViewImageView = UIImageView(image: UIImage(named: "portfolioTestImg")) + tableViewImageView.contentMode = .top + self.tableView.backgroundView = tableViewImageView + self.tableView.estimatedRowHeight = 174 + self.tableView.rowHeight = UITableView.automaticDimension + } + + func setCollectionView(){ + let nibName = UINib(nibName: "HashTagCollectionViewCell", bundle: nil) + self.hashTagsCollectionView.delegate = self + self.hashTagsCollectionView.dataSource = self + self.hashTagsCollectionView.register(nibName, forCellWithReuseIdentifier: "hashTagCell") + let hashTagsCVFlowLayout = hashTagsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout + hashTagsCVFlowLayout.estimatedItemSize = CGSize(width: 64, height: 27) + } + +// func calculationContentHeight(setLabel: UILabel) -> CGFloat { +// let widthSizeMinus: CGFloat = 102 +// let maxLabelSize: CGSize = CGSize(width: self.view.frame.size.width - widthSizeMinus, height: CGFloat(9999)) +//// let options: NSStringDrawingOptions = [.UsersLineFragmentOrigin] +// let contentNSString = setLabel.text! as NSString +// let expectedabelSize = contentNSString.boundingRect(with: maxLabelSize, context: nil) +// return expectedabelSize.size.height +// } + + override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + cell.roundCorners(corners: [.topLeft, .topRight], radius: 15) + cell.frame.size.height = 1000 + } +} + +extension PortfolioDetailTableViewController : UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return portfolioDetail.portfolioHashTags!.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashTagCell", for: indexPath) as! HashTagCollectionViewCell + let tagString = (portfolioDetail.portfolioHashTags![indexPath.row]) + " " + cell.hashTagLabel?.text = tagString + return cell + } +} diff --git a/GetRestIOS/Controllers/Recruit/DatePickerVC.swift b/GetRestIOS/Controllers/Recruit/DatePickerVC.swift new file mode 100644 index 0000000..c48d5e4 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/DatePickerVC.swift @@ -0,0 +1,62 @@ +// +// DatePickerVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class DatePickerVC: UIViewController { + + + +// @IBOutlet var titleLabel: UILabel! + @IBOutlet var datePicker: UIDatePicker! + + var formmatedDate: String { + get { + let formatter = DateFormatter() + formatter.locale = NSLocale(localeIdentifier: "ko_KO") as Locale; + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + formatter.dateStyle = .medium + print(formatter.string(from: datePicker.date)) + return formatter.string(from: datePicker.date) + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + @IBAction func saveAction(_ sender: UIButton) { + NotificationCenter.default.post(name: .RecruitDate, object: self) + + + dismiss(animated: true) + } + + @IBAction func cancelAction(_ sender: UIButton) { + dismiss(animated: true) + } + + + + + + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Controllers/Recruit/Filter/FIlterListCellCVC.swift b/GetRestIOS/Controllers/Recruit/Filter/FIlterListCellCVC.swift new file mode 100644 index 0000000..f003536 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Filter/FIlterListCellCVC.swift @@ -0,0 +1,26 @@ +// +// FIlterListCellCVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class FIlterListCellCVC: UICollectionViewCell { + @IBOutlet var filterCellBtn: UIButton! + var isChecked = false + + @IBAction func filterClickAction(_ sender: UIButton) { + isChecked = !isChecked + if isChecked { + filterCellBtn.backgroundColor = .mainGreen + filterCellBtn.setTitleColor(.white, for: .normal) + } else { + filterCellBtn.backgroundColor = .white + filterCellBtn.setTitleColor(.mainGreen, for: .normal) + } + } + +} diff --git a/GetRestIOS/Controllers/Recruit/Filter/FIlterListTVC.swift b/GetRestIOS/Controllers/Recruit/Filter/FIlterListTVC.swift new file mode 100644 index 0000000..c1543bc --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Filter/FIlterListTVC.swift @@ -0,0 +1,39 @@ +// +// FIlterListTVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class FIlterListTVC: UITableViewCell { + + @IBOutlet private weak var collectionView: UICollectionView! + + func setCollectionViewDataSourceDelegate(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate, forRow row: Int) { + collectionView.delegate = dataSourceDelegate + collectionView.dataSource = dataSourceDelegate + collectionView.tag = row + collectionView.reloadData() + } + + var collectionViewOffset: CGFloat { + set { collectionView.contentOffset.x = newValue } + get { return collectionView.contentOffset.x } + } + + +// override func awakeFromNib() { +// super.awakeFromNib() +// // Initialization code +// } +// +// override func setSelected(_ selected: Bool, animated: Bool) { +// super.setSelected(selected, animated: animated) +// +// // Configure the view for the selected state +// } + +} diff --git a/GetRestIOS/Controllers/Recruit/Filter/RecruitFilterVC.swift b/GetRestIOS/Controllers/Recruit/Filter/RecruitFilterVC.swift new file mode 100644 index 0000000..8338882 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Filter/RecruitFilterVC.swift @@ -0,0 +1,99 @@ +// +// RecruitFilterVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class RecruitFilterVC: UIViewController { + + @IBOutlet var navBar: UINavigationBar! + var model: [[String]] = [] + var storedOffsets = [Int: CGFloat]() + var sections: [String] = [] + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + @IBAction func closeAction(_ sender: UIBarButtonItem) { + // 데이터 넘겨주기 및 통신필요? + dismiss(animated: true) + } + + +} +extension RecruitFilterVC: UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "FliterList",for: indexPath) as! FIlterListTVC + cell.backgroundColor = .blue + return cell + } + func numberOfSections(in tableView: UITableView) -> Int { + return sections.count + } + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + switch (section) { + case 1: + return sections[section] + case 2: + return sections[section] + case 3: + return sections[section] + default: + return "" + } + } +} + +//extension RecruitFilterVC: UITableViewDelegate, UITableViewDataSource { +// +// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { +// return model.count +// } +// +// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { +// let cell = tableView.dequeueReusableCell(withIdentifier: "FliterList",for: indexPath) +// +// return cell +// } +// +// func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { +// guard let tableViewCell = cell as? FIlterListTVC else { return } +// tableViewCell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self as UICollectionViewDataSource & UICollectionViewDelegate, forRow: indexPath.row) +// } +//} +// +//extension RecruitFilterVC: UICollectionViewDelegate, UICollectionViewDataSource { +// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { +// return model[collectionView.tag].count +// } +// +// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { +// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FilterListCell", for: indexPath) as! FIlterListCellCVC +// +// cell.filterCellBtn.setTitle(model[collectionView.tag][indexPath.item], for: .normal) +// +// return cell +// } +// +// +//} +extension RecruitFilterVC { + func setData() { + sections = ["채용형태", "희망근무지역", "관심분야"] + let cell1: [String] = ["경력무관", "신입", "정규직", "계약직", "인턴직"] + let cell2: [String] = ["전국", "서울", "경기", "인천", "부산", "대구", "광주", "대전", "울산", "세종", "강원", "경남", "경북", "전남", "전북", "충남", "충북", "제주"] + let cell3: [String] = ["전체", "경영·사무", "영업·고객상담", "디자인", "IT·인터넷", "전문직"] + model = [cell1, cell2, cell3] + } +} + + diff --git a/GetRestIOS/Controllers/Recruit/RecruitDetailVC.swift b/GetRestIOS/Controllers/Recruit/RecruitDetailVC.swift new file mode 100644 index 0000000..fea0f58 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/RecruitDetailVC.swift @@ -0,0 +1,55 @@ +// +// RecruitDetailVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class RecruitDetailVC: UIViewController { + + @IBOutlet var corprImg: UIImageView! + @IBOutlet var corporNameLabel: UILabel! + @IBOutlet var corporFieldLabel: UILabel! + @IBOutlet var corporDurationLabel: UILabel! + @IBOutlet var careerLabel: UILabel! + @IBOutlet var academicLabel: UILabel! + @IBOutlet var serviceLabel: UILabel! + @IBOutlet var positionLabel: UILabel! + @IBOutlet var areaLabel: UILabel! + @IBOutlet var detailBackground: UIView! + @IBOutlet var corporImg: UIImageView! + + + + override func viewDidLoad() { + super.viewDidLoad() + setLabel() + self.navigationItem.title = "상세정보" + let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.barMainGreen] + navigationController?.navigationBar.titleTextAttributes = textAttributes + detailBackground.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 28) + detailBackground.dropShadow(color: UIColor.black, offSet: CGSize(width: 0, height: 10), opacity: 1, radius: 28) + + } + @IBAction func writeAction(_ sender: UIButton) { + } + @IBAction func goHomepageAction(_ sender: UIButton) { + } + +} + +extension RecruitDetailVC { + func setLabel() { + corporNameLabel.sizeToFit() + corporFieldLabel.sizeToFit() + corporDurationLabel.sizeToFit() + careerLabel.sizeToFit() + academicLabel.sizeToFit() + serviceLabel.sizeToFit() + positionLabel.sizeToFit() + areaLabel.sizeToFit() + } +} diff --git a/GetRestIOS/Controllers/Recruit/RecruitListCell.swift b/GetRestIOS/Controllers/Recruit/RecruitListCell.swift new file mode 100644 index 0000000..4d071be --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/RecruitListCell.swift @@ -0,0 +1,45 @@ +// +// RecruitListCell.swift +// GetRestIOS +// +// Created by 최리안 on 08/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class RecruitListCell: UITableViewCell { + @IBOutlet var recruitImg: UIImageView! + @IBOutlet var recruitTitle: UILabel! + @IBOutlet var recruitField: UILabel! + @IBOutlet var recruitDate: UILabel! + @IBOutlet var starBtn: UIButton! + var isChecked = false +// var checkedList: [Int] = [] + + + override func awakeFromNib() { + super.awakeFromNib() + + } + + + @IBAction func starOnOff(_ sender: UIButton) { + isChecked = !isChecked + if isChecked { + starBtn.setImage(UIImage(named: "icStarOn"), for: .normal) + + + } else { + starBtn.setImage(UIImage(named: "icStarOff"), for: .normal) + } + } + + +// override func setSelected(_ selected: Bool, animated: Bool) { +// super.setSelected(selected, animated: animated) +// +// // Configure the view for the selected state +// } + +} diff --git a/GetRestIOS/Controllers/Recruit/RecruitListVC.swift b/GetRestIOS/Controllers/Recruit/RecruitListVC.swift new file mode 100644 index 0000000..fbb2ea1 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/RecruitListVC.swift @@ -0,0 +1,30 @@ +// +// RecruitListVC.swift +// GetRestIOS +// +// Created by 최리안 on 08/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class RecruitListVC: UITableViewCell { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Controllers/Recruit/RecruitViewController.swift b/GetRestIOS/Controllers/Recruit/RecruitViewController.swift new file mode 100644 index 0000000..87ecc3f --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/RecruitViewController.swift @@ -0,0 +1,202 @@ +// +// RecruitViewController.swift +// GetRestIOS +// +// Created by 최리안 on 08/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + + + +class RecruitViewController: UIViewController { + + @IBOutlet var recruitListTableView: UITableView! + @IBOutlet var starFilterBtn: UIButton! + @IBOutlet var selectDatePickerBtn: UIView! + @IBOutlet var dateLabel: UILabel! + + var list: [RecruitListModel] = [] + var checkedList: [RecruitListModel] = [] + var starIsChecked = false + + + @IBAction func searchAction(_ sender: UIBarButtonItem) { + let storyboard = UIStoryboard(name: "Recruit", bundle: nil) + // 아까 입력했던 storyboard id -> writeview_yw를 입력해주자ㅏ. + let vc = storyboard.instantiateViewController(withIdentifier: "SearchVC") + self.present(vc, animated: false) + } + @IBAction func filterAction(_ sender: UIButton) { + + } + @IBAction func starFilterAction(_ sender: UIButton) { + + starIsChecked = !starIsChecked + if starIsChecked { + starFilterBtn.setImage(UIImage(named: "icStarFilterOn"), for: .normal) + +// for cell in list { +// if cell.isChecked == true { +// checkedList.append(cell) +// } +// } + recruitListTableView.reloadData() + + } else { + starFilterBtn.setImage(UIImage(named: "icStarFilterOff"), for: .normal) + } + } + override func viewDidLoad() { + + recruitListTableView.delegate = self + recruitListTableView.dataSource = self + + super.viewDidLoad() + + setNavigationBar() + setToday() + setData() + + let gesture = UITapGestureRecognizer(target: self, action: #selector(RecruitViewController.goPage(sender:))) + self.selectDatePickerBtn.addGestureRecognizer(gesture) + + NotificationCenter.default.addObserver(forName: .RecruitDate, object: nil, queue: OperationQueue.main) { (notification) in + let dateVc = notification.object as! DatePickerVC + self.dateLabel.text = dateVc.formmatedDate + } + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + if let index = recruitListTableView.indexPathForSelectedRow { + recruitListTableView.deselectRow(at: index, animated: true) + } + } + + @objc func goPage(sender:UIGestureRecognizer) { + // Story board 상수를 지정하고 (Main.storyboard 기 때문에 "Main"을 입력해주자.) + let storyboard = UIStoryboard(name: "Recruit", bundle: nil) + // 아까 입력했던 storyboard id -> writeview_yw를 입력해주자ㅏ. + let vc = storyboard.instantiateViewController(withIdentifier: "DatePicker") + self.present(vc, animated: true) + } +} + +extension RecruitViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = recruitListTableView.dequeueReusableCell(withIdentifier: "RecruitListTableViewCell") as! RecruitListCell + + let data = list[indexPath.row] + + cell.recruitTitle.text = data.rcTitle + cell.recruitField.text = data.rcField + cell.recruitDate.text = data.rcDate + cell.recruitImg.image = data.rcImg + + + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let dvc = storyboard?.instantiateViewController(withIdentifier: "RecruitDetailVC") as! RecruitDetailVC + +// present(dvc, animated: true) + navigationController?.pushViewController(dvc, animated: true) + } + + func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + return true + } + +} + +@IBDesignable extension UIButton { + + @IBInspectable var borderWidth: CGFloat { + set { + layer.borderWidth = newValue + } + get { + return layer.borderWidth + } + } + + @IBInspectable var cornerRadius: CGFloat { + set { + layer.cornerRadius = newValue + } + get { + return layer.cornerRadius + } + } + + @IBInspectable var borderColor: UIColor? { + set { + guard let uiColor = newValue else { return } + layer.borderColor = uiColor.cgColor + } + get { + guard let color = layer.borderColor else { return nil } + return UIColor(cgColor: color) + } + } +} + +extension RecruitViewController { + func setNavigationBar(){ + let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 62, height: 17)) + imageView.contentMode = .scaleAspectFit + + let image = UIImage(named: "icRecruit") + imageView.image = image + + self.navigationItem.titleView = imageView + self.navigationController?.navigationBar.tintColor = .barMainGreen + self.navigationController?.navigationBar.clipsToBounds = true + + let backBarButtton = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) + navigationItem.backBarButtonItem = backBarButtton + navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44) + navigationController?.navigationBar.isTranslucent = false + + self.navigationController?.navigationBar.barTintColor = .white + self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) + + self.navigationController?.navigationBar.clipsToBounds = true + + } + + func setToday() { + let date = Date() + let formatter = DateFormatter() + formatter.locale = NSLocale(localeIdentifier: "ko_KO") as Locale; + formatter.dateFormat = "yyyy-MM-dd" + formatter.dateStyle = .medium + let today = formatter.string(from: date) + + self.dateLabel.text = today + } + + func setData() { + let rc1 = RecruitListModel(img: "icDefaultImg", title: "솝트1", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc2 = RecruitListModel(img: "icDefaultImg", title: "솝트2", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc3 = RecruitListModel(img: "icDefaultImg", title: "솝트3", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc4 = RecruitListModel(img: "icDefaultImg", title: "솝트4", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc5 = RecruitListModel(img: "icDefaultImg", title: "솝트5", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc6 = RecruitListModel(img: "icDefaultImg", title: "솝트6", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc7 = RecruitListModel(img: "icDefaultImg", title: "솝트7", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + let rc8 = RecruitListModel(img: "icDefaultImg", title: "솝트8", field: "Web 디자이너 / 모바일. App 디자이너", date: "~06월 19일 18시 00분") + + list = [rc1, rc2, rc3, rc4, rc5, rc6, rc7, rc8] + checkedList = [rc1, rc2, rc3, rc4, rc5, rc6, rc7, rc8] + } +} + diff --git a/GetRestIOS/Controllers/Recruit/SearchVC.swift b/GetRestIOS/Controllers/Recruit/SearchVC.swift new file mode 100644 index 0000000..a87bacd --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/SearchVC.swift @@ -0,0 +1,40 @@ +// +// SearchVC.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class SearchVC: UIViewController { + + @IBOutlet var dismissView: UIView! + + override func viewDidLoad() { + super.viewDidLoad() + + let gesture = UITapGestureRecognizer(target: self, action: #selector(RecruitViewController.goPage(sender:))) + self.dismissView.addGestureRecognizer(gesture) + + // Do any additional setup after loading the view. + } + + @objc func goPage(sender:UIGestureRecognizer) { + + dismiss(animated: false) + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Controllers/Recruit/Select/PortfolioSelectVC.swift b/GetRestIOS/Controllers/Recruit/Select/PortfolioSelectVC.swift new file mode 100644 index 0000000..2bc2a4a --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Select/PortfolioSelectVC.swift @@ -0,0 +1,30 @@ +// +// PortfolioSelectVC.swift +// GetRestIOS +// +// Created by 최리안 on 11/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class PortfolioSelectVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Controllers/Recruit/Select/QuestionCell.swift b/GetRestIOS/Controllers/Recruit/Select/QuestionCell.swift new file mode 100644 index 0000000..717e17f --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Select/QuestionCell.swift @@ -0,0 +1,70 @@ +// +// QuestionCell.swift +// GetRestIOS +// +// Created by 최리안 on 10/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class QuestionCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate { + + @IBOutlet var askNum: UILabel! + @IBOutlet var askLabel: UILabel! + @IBOutlet var selectTV: UITableView! + var img: UIImage? = UIImage(named: "ex") + + var data = ["쉬자", "솝트", "쉬자"] as [Any] + + override func awakeFromNib() { + super.awakeFromNib() + +// selectTV.frame.size.height = CGFloat((118+20)*data.count) + selectTV.delegate = self + selectTV.dataSource = self + + // Initialization code + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + + let cell = selectTV.dequeueReusableCell(withIdentifier: "SelectCell") as! SelectCell + + if indexPath.row == data.count { + print("외부?") + + cell.pfImg.backgroundColor = .lightGray + cell.pfImg.roundCorners(corners: .allCorners, radius: 5) + cell.addBtn.setImage(UIImage(named: "icAddPortfolio"), for: .normal) + cell.pfDate.text = "" + cell.pfTitle.text = "" + return cell + } + + cell.pfTitle.text = self.data[indexPath.row] as? String + cell.pfImg.image = img + cell.pfImg.contentMode = .scaleToFill + cell.pfImg.clipsToBounds = true + return cell + + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + print("넘 count") + return (data.count+1) + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 143 + } + func numberOfSectionsInTableView(tableView: UITableView) -> Int { + return 1 + } + +} diff --git a/GetRestIOS/Controllers/Recruit/Select/SelectCell.swift b/GetRestIOS/Controllers/Recruit/Select/SelectCell.swift new file mode 100644 index 0000000..5918e1d --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Select/SelectCell.swift @@ -0,0 +1,29 @@ +// +// SelectCell.swift +// GetRestIOS +// +// Created by 최리안 on 10/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class SelectCell: UITableViewCell { + + @IBOutlet var pfImg: UIImageView! + @IBOutlet var pfTitle: UILabel! + @IBOutlet var pfDate: UILabel! + @IBOutlet var addBtn: UIButton! + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + pfImg.roundCorners(corners: .allCorners, radius: 5) + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/GetRestIOS/Controllers/Recruit/Select/SelectTVC.swift b/GetRestIOS/Controllers/Recruit/Select/SelectTVC.swift new file mode 100644 index 0000000..d89aee8 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Select/SelectTVC.swift @@ -0,0 +1,99 @@ +// +// SelectTVC.swift +// GetRestIOS +// +// Created by 최리안 on 10/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class SelectTVC: UITableViewController { + var num = ["일번", "이번", "삼번"] + var q = ["tlqkfqltlqfkasldkfajs;ldkfjdas", ";sdlkfj;lqkwjf;oiejf;osdkjfl;sdkjf", ";sldkfj;asdlkfjas;dlkfjs;lf"] + + @IBOutlet var askTV: UITableView! +// @IBOutlet var selectTV: UITableView! + override func viewDidLoad() { + super.viewDidLoad() +// askTV.delegate = self +// askTV.dataSource = self + + // Uncomment the following line to preserve selection between presentations + // self.clearsSelectionOnViewWillAppear = false + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem + } + + // MARK: - Table view data source + +// override func numberOfSections(in tableView: UITableView) -> Int { +// // #warning Incomplete implementation, return the number of sections +// return num.count +// } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + // #warning Incomplete implementation, return the number of rows + return num.count + } + + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionCell", for: indexPath) as! QuestionCell + + cell.askLabel.text = q[indexPath.row] + cell.askNum.text = num[indexPath.row] + + return cell + } + + /* + // Override to support conditional editing of the table view. + override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the specified item to be editable. + return true + } + */ + + /* + // Override to support editing the table view. + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + // Delete the row from the data source + tableView.deleteRows(at: [indexPath], with: .fade) + } else if editingStyle == .insert { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + + /* + // Override to support rearranging the table view. + override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { + + } + */ + + /* + // Override to support conditional rearranging of the table view. + override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the item to be re-orderable. + return true + } + */ + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} +extension SelectTVC { + +} diff --git a/GetRestIOS/Controllers/Recruit/Select/SelectVC.swift b/GetRestIOS/Controllers/Recruit/Select/SelectVC.swift new file mode 100644 index 0000000..ac14ff6 --- /dev/null +++ b/GetRestIOS/Controllers/Recruit/Select/SelectVC.swift @@ -0,0 +1,75 @@ +// +// SelectVC.swift +// GetRestIOS +// +// Created by 최리안 on 10/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class SelectVC: UIViewController, UITableViewDataSource, UITableViewDelegate { + + + @IBOutlet var askTV: UITableView! + var num = ["문항", "문항", "문항"] + var q = ["내가 생각하는 최고의 서비스디자인이란 무엇인가?", "다른 사람들과 함께 목표를 달성하기 위해 노력했던 경험은 무엇인지 서술하세요.", "내가 생각하는 최고의 서비스디자인이란 무엇인가?"] + + + + override func viewDidLoad() { + super.viewDidLoad() +// let cell = self.askTV.dequeueReusableCell(withIdentifier: "QuestionCell") as! QuestionCell +// askTV.rowHeight = UITableView.automaticDimension +// askTV.estimatedRowHeight = CGFloat(cell.data.count) + askTV.delegate = self + askTV.dataSource = self +// askTV.register(QuestionCell.self, forCellReuseIdentifier: "QuestionCell") + print("뷰로드") + } + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + if let index = askTV.indexPathForSelectedRow { + askTV.deselectRow(at: index, animated: true) + } + } + + + private func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) { + + } + private func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + return UITableView.automaticDimension + } + + private func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + return UITableView.automaticDimension + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = self.askTV.dequeueReusableCell(withIdentifier: "QuestionCell") as! QuestionCell +// cell. + cell.askLabel.lineBreakMode = .byWordWrapping + cell.askLabel.numberOfLines = 0 + cell.askLabel.translatesAutoresizingMaskIntoConstraints = false + cell.askLabel.preferredMaxLayoutWidth = 353 + + cell.askLabel.text = q[indexPath.row] + cell.askNum.text = "문항\(indexPath.row+1)" + cell.askNum.sizeToFit() + print("여기3") + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + print("넘 카운트") + return num.count; + } + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + print("여기 한번오나?") + let cell = self.askTV.dequeueReusableCell(withIdentifier: "QuestionCell") as! QuestionCell + return CGFloat(90+(125+20) * (cell.data.count+1)) + } +} + + diff --git a/GetRestIOS/Controllers/ViewController.swift b/GetRestIOS/Controllers/ViewController.swift deleted file mode 100644 index 45b6d29..0000000 --- a/GetRestIOS/Controllers/ViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// ViewController.swift -// GetRestIOS -// -// Created by 최리안 on 28/06/2019. -// Copyright © 2019 최리안. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/GetRestIOS/Extensions/NotificationNameExtension.swift b/GetRestIOS/Extensions/NotificationNameExtension.swift new file mode 100644 index 0000000..7e0959f --- /dev/null +++ b/GetRestIOS/Extensions/NotificationNameExtension.swift @@ -0,0 +1,15 @@ +// +// NotificationNameExtension.swift +// GetRestIOS +// +// Created by 최리안 on 09/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import Foundation + +extension Notification.Name { + static let RecruitDate = Notification.Name(rawValue: "RecruitDate") + static let PortfolioDate = Notification.Name(rawValue: "PortfolioDate") + static let CategoryData = Notification.Name(rawValue: "CategoryData") +} diff --git a/GetRestIOS/Extensions/UIView+Extensions.swift b/GetRestIOS/Extensions/UIView+Extensions.swift index c59ebfe..8c18d3b 100644 --- a/GetRestIOS/Extensions/UIView+Extensions.swift +++ b/GetRestIOS/Extensions/UIView+Extensions.swift @@ -31,7 +31,7 @@ extension UIView { // 그림자의 blur 설정 layer.shadowRadius = radius // 구글링 해보세요! - layer.masksToBounds = false + layer.masksToBounds = true } // Set UIView's Border diff --git a/GetRestIOS/Extensions/bubbleTransition.swift b/GetRestIOS/Extensions/bubbleTransition.swift new file mode 100644 index 0000000..d1703d7 --- /dev/null +++ b/GetRestIOS/Extensions/bubbleTransition.swift @@ -0,0 +1,172 @@ +// +// bubbleTransition.swift +// GetRestIOS +// +// Created by 박경선 on 05/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit +import Foundation + +@objc public class BubbleTransition: NSObject +{ + /// Point in which we situate the bubble. + /// By default Upper Left corner + public var startingPoint: CGPoint + + /// The transition direction. + public var transitionMode: TransitionMode + + /// The color of the bubble. + /// Non defined? We use the presented controller background color + public var bubbleColor: UIColor? + + /// The bubble + private var bubble: UIView! + /// Transition duration + private var presentingDuration: Double + /// Dismiss duration + private var dismissDuration: Double + + /** + Initializer + */ + public override init() + { + self.presentingDuration = 0.5 + self.dismissDuration = 0.35 + + self.startingPoint = CGPoint(x: 0.0, y: 0.0) + self.transitionMode = TransitionMode.Present + } + + /** + Calculate the circle needed to cover the screen completly + + - Parameters: + - originalSize: Size that must be covered + - start: Where the bubble starts to growth + */ + private func frameForBubbleWithSize(originalSize: CGSize, start: CGPoint) -> CGRect + { + let lengthX = fmax(start.x, originalSize.width - start.x); + let lengthY = fmax(start.y, originalSize.height - start.y) + + let offset = sqrt(lengthX * lengthX + lengthY * lengthY) * 2; + + return CGRect(x: 0, y: 0, width: offset, height: offset) + } +} + +// +// MARK: - UIViewControllerAnimatedTransitioning Protocol +// + +extension BubbleTransition: UIViewControllerAnimatedTransitioning +{ + /** + Transition duration + */ + public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval + { + return self.transitionMode == .Present ? self.presentingDuration : self.dismissDuration + } + + /** + Where the magic happends :) + */ + + public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) + { + + let containerView = transitionContext.containerView + guard let toView = transitionContext.view(forKey: UITransitionContextViewKey.to), + let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from) + else + { + return + } + + if transitionMode == TransitionMode.Present + { + let originalCenter = toView.center + let originalSize = toView.frame.size + + let frame: CGRect = self.frameForBubbleWithSize(originalSize: originalSize, start: self.startingPoint) + + self.bubble = UIView(frame: frame) +// self.bubble.layer.cornerRadius = self.bubble.frame.height / 2 + self.bubble.center = self.startingPoint + self.bubble.transform = CGAffineTransform(scaleX: 0.001, y: 0.001) + + if let bubbleColor = self.bubbleColor + { + self.bubble.backgroundColor = bubbleColor + } + else + { + self.bubble.backgroundColor = toView.backgroundColor + } + + toView.center = startingPoint + toView.transform = CGAffineTransform(scaleX: 0.001, y: 0.001) + toView.alpha = 0 + + containerView.addSubview(toView) + containerView.addSubview(self.bubble) + + UIView.animate(withDuration: self.presentingDuration, + animations: + { + self.bubble.transform = CGAffineTransform.identity + + toView.transform = CGAffineTransform.identity + toView.alpha = 1 + toView.center = originalCenter + }, + completion: { (finished: Bool) -> (Void) in + if finished + { + self.bubble.removeFromSuperview() + + transitionContext.completeTransition(true) + } + } + ) + } + else + { + let originalSize = fromView.frame.size + + self.bubble.frame = self.frameForBubbleWithSize(originalSize: originalSize, start: startingPoint) + self.bubble.layer.cornerRadius = self.bubble.frame.height / 2 + self.bubble.center = self.startingPoint + + containerView.addSubview(toView) + containerView.addSubview(self.bubble) + + UIView.animate(withDuration: self.dismissDuration, + animations: + { + self.bubble.transform = CGAffineTransform(scaleX: 0.001, y: 0.001) + }, + completion: { (finished: Bool) -> (Void) in + if finished + { + toView.removeFromSuperview() + self.bubble.removeFromSuperview() + + transitionContext.completeTransition(true) + } + } + ) + } + } +} + +@objc public enum TransitionMode: Int +{ + case Present + case Dismiss +} diff --git a/GetRestIOS/Models/PortfolioModel.swift b/GetRestIOS/Models/PortfolioModel.swift new file mode 100644 index 0000000..cdef607 --- /dev/null +++ b/GetRestIOS/Models/PortfolioModel.swift @@ -0,0 +1,57 @@ +// +// PortfolioModel.swift +// GetRestIOS +// +// Created by 최리안 on 07/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import Foundation +import UIKit + +struct PortfoliolModel{ + var pfImg: UIImage? + var pfTitle: String + var pfDate: String + + init(img: String, title: String, date: String){ + self.pfImg = UIImage(named: img) + self.pfTitle = title + self.pfDate = date + } +} +// +//struct PortfoliolModel : Codable { +// var pfImg: UIImage? +// var pfTitle: String +// var pfDate: String +// +// enum CodingKeys: String, CodingKey { +// case pfImg +// case pfTitle +// case pfDate +// } +// +// init(from decoder: Decoder) throws { +// let container = try decoder.container(keyedBy: CodingKeys.self) +// pfTitle = try container.decode(String.self, forKey: .pfTitle) +// pfDate = try container.decode(String.self, forKey: .pfDate) +// +// if let text = try container.decodeIfPresent(String.self, forKey: .pfImg) { +// if let data = Data(base64Encoded: text) { +// pfImg = UIImage(data: data) +// } +// } +// } +// +// func encode(to encoder: Encoder) throws { +// var container = encoder.container(keyedBy: CodingKeys.self) +// +// if let pfImg = pfImg, let data = pfImg.pngData() { +// try container.encode(data, forKey: .pfImg) +// } +// try container.encode(pfTitle, forKey: .pfTitle) +// try container.encode(pfDate, forKey: .pfDate) +// } +//} +// diff --git a/GetRestIOS/Models/RecruitListModel.swift b/GetRestIOS/Models/RecruitListModel.swift new file mode 100644 index 0000000..a04979d --- /dev/null +++ b/GetRestIOS/Models/RecruitListModel.swift @@ -0,0 +1,67 @@ +// +// RecruitListModel.swift +// GetRestIOS +// +// Created by 최리안 on 08/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import Foundation +import UIKit + +struct RecruitListModel{ + var rcImg: UIImage? + var rcTitle: String + var rcField: String + var rcDate: String + var starChecked: Bool + + init(img: String, title: String, field: String, date: String){ + self.rcImg = UIImage(named: img) + self.rcTitle = title + self.rcField = field + self.rcDate = date + self.starChecked = false + } +} +// +//struct RecruitListlModel : Codable { +// var rcImg: UIImage? +// var rcTitle: String +// var rcField: String +// var rcDate: String +// +// enum CodingKeys: String, CodingKey { +// case rcImg +// case rcTitle +// case rcField +// case rcDate +// +// } +// +// init(from decoder: Decoder) throws { +// let container = try decoder.container(keyedBy: CodingKeys.self) +// rcTitle = try container.decode(String.self, forKey: .rcTitle) +// rcField = try container.decode(String.self, forKey: .rcField) +// rcDate = try container.decode(String.self, forKey: .rcDate) +// +// if let text = try container.decodeIfPresent(String.self, forKey: .rcImg) { +// if let data = Data(base64Encoded: text) { +// rcImg = UIImage(data: data) +// } +// } +// } +// +// func encode(to encoder: Encoder) throws { +// var container = encoder.container(keyedBy: CodingKeys.self) +// +// if let rcImg = rcImg, let data = rcImg.pngData() { +// try container.encode(data, forKey: .rcImg) +// } +// try container.encode(rcTitle, forKey: .rcTitle) +// try container.encode(rcField, forKey: .rcField) +// try container.encode(rcDate, forKey: .rcDate) +// } +//} +// + diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/Contents.json b/GetRestIOS/Resources/Assets.xcassets/PopUP/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/PopUP/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796.png new file mode 100644 index 0000000..516554c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@2x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@2x.png new file mode 100644 index 0000000..c1c6667 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@3x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@3x.png new file mode 100644 index 0000000..71bf2dd Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/3796@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/Contents.json new file mode 100644 index 0000000..ed39f6d --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/PopUP/areYouReallyGO?.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "3796.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "3796@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "3796@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/Contents.json new file mode 100644 index 0000000..69eb4e2 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "invalidName.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "invalidName@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "invalidName@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName.png new file mode 100644 index 0000000..d2f276c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@2x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@2x.png new file mode 100644 index 0000000..407e63c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@3x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@3x.png new file mode 100644 index 0000000..c94e523 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofo.imageset/invalidName@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/Contents.json new file mode 100644 index 0000000..69eb4e2 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "invalidName.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "invalidName@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "invalidName@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName.png new file mode 100644 index 0000000..33336e1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@2x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@2x.png new file mode 100644 index 0000000..2b71fac Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@3x.png b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@3x.png new file mode 100644 index 0000000..1109128 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/PopUP/myPofoStop.imageset/invalidName@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/Contents.json new file mode 100644 index 0000000..bb48de7 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "chip.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "chip@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "chip@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip.png new file mode 100644 index 0000000..f5bc87f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@2x.png new file mode 100644 index 0000000..de900c4 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@3x.png new file mode 100644 index 0000000..726df53 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icAddChip.imageset/chip@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/Contents.json new file mode 100644 index 0000000..6b55038 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icArrowDropDown.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icArrowDropDown@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icArrowDropDown@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown.png new file mode 100644 index 0000000..70954f6 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@2x.png new file mode 100644 index 0000000..d144713 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@3x.png new file mode 100644 index 0000000..47e3925 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icArrowDropDown.imageset/icArrowDropDown@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/Contents.json new file mode 100644 index 0000000..52d92a0 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "imageAddBtn.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "imageAddBtn@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "imageAddBtn@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn.png new file mode 100644 index 0000000..a95a429 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@2x.png new file mode 100644 index 0000000..3f8f9dd Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@3x.png new file mode 100644 index 0000000..914057e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImageAddBtn.imageset/imageAddBtn@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/Contents.json new file mode 100644 index 0000000..cde2127 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "image.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image.png new file mode 100644 index 0000000..710c2e6 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@2x.png new file mode 100644 index 0000000..0a0eecd Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@3x.png new file mode 100644 index 0000000..c7955e7 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImg.imageset/image@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/Contents.json new file mode 100644 index 0000000..cde2127 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "image.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image.png new file mode 100644 index 0000000..b0779f9 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@2x.png new file mode 100644 index 0000000..c367e34 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@3x.png new file mode 100644 index 0000000..1168fe2 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icImgBlanck.imageset/image@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/Contents.json new file mode 100644 index 0000000..f53a5bb --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "writeBtn.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "writeBtn@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "writeBtn@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn.png new file mode 100644 index 0000000..54e11e4 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@2x.png new file mode 100644 index 0000000..9127d7f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@3x.png new file mode 100644 index 0000000..545119d Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icNavBarAdd.imageset/writeBtn@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/Contents.json new file mode 100644 index 0000000..d775fc8 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "title.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "title@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "title@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title.png new file mode 100644 index 0000000..8eb68f1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@2x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@2x.png new file mode 100644 index 0000000..cb0b6f2 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@3x.png b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@3x.png new file mode 100644 index 0000000..1212870 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Portfoio/icPortfolio.imageset/title@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/Contents.json new file mode 100644 index 0000000..cde2127 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "image.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image.png new file mode 100644 index 0000000..0030f28 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@2x.png new file mode 100644 index 0000000..2d492ff Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@3x.png new file mode 100644 index 0000000..320c046 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/ex.imageset/image@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/Contents.json new file mode 100644 index 0000000..f20a195 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnAddMemory.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnAddMemory@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnAddMemory@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory.png new file mode 100644 index 0000000..046c0b1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@2x.png new file mode 100644 index 0000000..95cbc8c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@3x.png new file mode 100644 index 0000000..7cb5e8c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icAddPortfolio.imageset/btnAddMemory@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/Contents.json new file mode 100644 index 0000000..d428c12 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnFilter.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnFilter@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnFilter@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter.png new file mode 100644 index 0000000..6110bd8 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@2x.png new file mode 100644 index 0000000..a3287c7 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@3x.png new file mode 100644 index 0000000..1c41d64 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnFilter.imageset/btnFilter@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/Contents.json new file mode 100644 index 0000000..9bc565a --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnSearch.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnSearch@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnSearch@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch.png new file mode 100644 index 0000000..f4d777f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@2x.png new file mode 100644 index 0000000..754748d Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@3x.png new file mode 100644 index 0000000..8a8b98e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icBtnSearch.imageset/btnSearch@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/Contents.json new file mode 100644 index 0000000..55d22ac --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "imgShimpyo.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "imgShimpyo@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "imgShimpyo@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo.png new file mode 100644 index 0000000..5b58103 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@2x.png new file mode 100644 index 0000000..4483e7e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@3x.png new file mode 100644 index 0000000..79209a1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icComma.imageset/imgShimpyo@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/Contents.json new file mode 100644 index 0000000..ffbc6e0 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "logo@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "logo@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo.png new file mode 100644 index 0000000..cc842ad Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@2x.png new file mode 100644 index 0000000..a6f0b7d Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@3x.png new file mode 100644 index 0000000..bd6070f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDefaultImg.imageset/logo@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/Contents.json new file mode 100644 index 0000000..adc1b0f --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnDropdown.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnDropdown@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnDropdown@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown.png new file mode 100644 index 0000000..c8c4ec0 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@2x.png new file mode 100644 index 0000000..15726b6 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@3x.png new file mode 100644 index 0000000..5b5dedb Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icDropDown.imageset/btnDropdown@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8.png new file mode 100644 index 0000000..6f4e56d Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@2x.png new file mode 100644 index 0000000..c0817af Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@3x.png new file mode 100644 index 0000000..3d27ae3 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/8@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/Contents.json new file mode 100644 index 0000000..c7326df --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrion.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "8.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "8@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "8@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7.png new file mode 100644 index 0000000..a533c21 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@2x.png new file mode 100644 index 0000000..cf73d87 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@3x.png new file mode 100644 index 0000000..aa2ecf2 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/7@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/Contents.json new file mode 100644 index 0000000..97a586c --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icOrionDetail.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "7.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "7@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "7@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/Contents.json new file mode 100644 index 0000000..d775fc8 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "title.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "title@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "title@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title.png new file mode 100644 index 0000000..a8bd6ca Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@2x.png new file mode 100644 index 0000000..8d2e101 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@3x.png new file mode 100644 index 0000000..a25a673 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icRecruit.imageset/title@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/Contents.json new file mode 100644 index 0000000..197d9aa --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnSearch.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnSearch@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnSearch@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch.png new file mode 100644 index 0000000..fd76f56 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@2x.png new file mode 100644 index 0000000..eb40774 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@3x.png new file mode 100644 index 0000000..0d38a61 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icSearch.imageset/btnSearch@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/Contents.json new file mode 100644 index 0000000..35a3b66 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnLike.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnLike@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnLike@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike.png new file mode 100644 index 0000000..79e744e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@2x.png new file mode 100644 index 0000000..1822a5b Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@3x.png new file mode 100644 index 0000000..93d4c3a Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOff.imageset/btnLike@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/Contents.json new file mode 100644 index 0000000..35a3b66 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnLike.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnLike@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnLike@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike.png new file mode 100644 index 0000000..38ffff4 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@2x.png new file mode 100644 index 0000000..a295db9 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@3x.png new file mode 100644 index 0000000..75da18a Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarFilterOn.imageset/btnLike@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/Contents.json new file mode 100644 index 0000000..487e805 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnSmallUnlike.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnSmallUnlike@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnSmallUnlike@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike.png new file mode 100644 index 0000000..60b7afe Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@2x.png new file mode 100644 index 0000000..e8ee961 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@3x.png new file mode 100644 index 0000000..65e82ac Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOff.imageset/btnSmallUnlike@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/Contents.json new file mode 100644 index 0000000..1187924 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnSmallLike.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnSmallLike@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnSmallLike@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike.png new file mode 100644 index 0000000..267c4a7 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@2x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@2x.png new file mode 100644 index 0000000..74cd6b1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@3x.png b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@3x.png new file mode 100644 index 0000000..528ca2a Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/Recruit/icStarOn.imageset/btnSmallLike@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/Contents.json new file mode 100644 index 0000000..f15a9ff --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "imgIllust.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "imgIllust@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "imgIllust@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust.png b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust.png new file mode 100644 index 0000000..6b0746c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@2x.png b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@2x.png new file mode 100644 index 0000000..ac8060f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@3x.png b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@3x.png new file mode 100644 index 0000000..044f35e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/homeTopSideViewImg.imageset/imgIllust@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/Contents.json new file mode 100644 index 0000000..f927814 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnBack.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnBack@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnBack@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack.png b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack.png new file mode 100644 index 0000000..c461638 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@2x.png b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@2x.png new file mode 100644 index 0000000..6747999 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@3x.png b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@3x.png new file mode 100644 index 0000000..ac12788 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icGoPortfolioButton.imageset/btnBack@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/Contents.json new file mode 100644 index 0000000..ffbc6e0 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "logo@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "logo@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo.png b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo.png new file mode 100644 index 0000000..0c151d9 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@2x.png b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@2x.png new file mode 100644 index 0000000..f251ddd Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@3x.png b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@3x.png new file mode 100644 index 0000000..e388c74 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMainLogoGetRest.imageset/logo@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/Contents.json new file mode 100644 index 0000000..0ff397f --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "mypageIcon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "mypageIcon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "mypageIcon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon.png b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon.png new file mode 100644 index 0000000..8797a5e Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@2x.png b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@2x.png new file mode 100644 index 0000000..267c8f0 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@3x.png b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@3x.png new file mode 100644 index 0000000..b77e4dd Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icMypage.imageset/mypageIcon@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/Contents.json new file mode 100644 index 0000000..75be328 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnTrash.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnTrash@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnTrash@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash.png b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash.png new file mode 100644 index 0000000..d52f4a0 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@2x.png b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@2x.png new file mode 100644 index 0000000..7d8864b Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@3x.png b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@3x.png new file mode 100644 index 0000000..a97327b Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortflioDelect.imageset/btnTrash@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/Contents.json new file mode 100644 index 0000000..84c9446 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btnEdit.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btnEdit@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btnEdit@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit.png b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit.png new file mode 100644 index 0000000..f5524e9 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@2x.png b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@2x.png new file mode 100644 index 0000000..3f85f71 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@3x.png b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@3x.png new file mode 100644 index 0000000..e196e5a Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icPortfolioEdit.imageset/btnEdit@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/Contents.json new file mode 100644 index 0000000..2129695 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icHome.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icHome@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icHome@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome.png new file mode 100644 index 0000000..df3da7b Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@2x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@2x.png new file mode 100644 index 0000000..40fdf10 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@3x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@3x.png new file mode 100644 index 0000000..85fddc6 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarHome.imageset/icHome@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/Contents.json new file mode 100644 index 0000000..6e58ae5 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icMyfolder.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icMyfolder@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icMyfolder@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder.png new file mode 100644 index 0000000..e250fbb Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@2x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@2x.png new file mode 100644 index 0000000..13a43ce Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@3x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@3x.png new file mode 100644 index 0000000..099aa1a Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarMyfolder.imageset/icMyfolder@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/Contents.json new file mode 100644 index 0000000..f57e7de --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icNotice.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icNotice@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icNotice@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice.png new file mode 100644 index 0000000..3f47dd6 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@2x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@2x.png new file mode 100644 index 0000000..e749fb8 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@3x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@3x.png new file mode 100644 index 0000000..ad79644 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarNotice.imageset/icNotice@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/Contents.json new file mode 100644 index 0000000..752c6ad --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icPortfolio.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icPortfolio@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icPortfolio@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio.png new file mode 100644 index 0000000..3c05628 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@2x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@2x.png new file mode 100644 index 0000000..3567c1d Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@3x.png b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@3x.png new file mode 100644 index 0000000..6a389da Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/icTabBarPortfolio.imageset/icPortfolio@3x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/Contents.json new file mode 100644 index 0000000..cbba182 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "top-1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "top@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "top.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top-1.png b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top-1.png new file mode 100644 index 0000000..cbfc85f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top-1.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top.png b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top.png new file mode 100644 index 0000000..cbfc85f Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top@2x.png b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top@2x.png new file mode 100644 index 0000000..4c060c1 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/navigationBarWithLogo.imageset/top@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/Contents.json b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/Contents.json new file mode 100644 index 0000000..cde2127 --- /dev/null +++ b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "image.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "image@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "image@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image.png b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image.png new file mode 100644 index 0000000..2d93d66 Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@2x.png b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@2x.png new file mode 100644 index 0000000..836691b Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@2x.png differ diff --git a/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@3x.png b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@3x.png new file mode 100644 index 0000000..eb5a90c Binary files /dev/null and b/GetRestIOS/Resources/Assets.xcassets/portfolioTestImg.imageset/image@3x.png differ diff --git a/GetRestIOS/Storyboards/Base.lproj/Home.storyboard b/GetRestIOS/Storyboards/Base.lproj/Home.storyboard index a60ba49..4a0be36 100644 --- a/GetRestIOS/Storyboards/Base.lproj/Home.storyboard +++ b/GetRestIOS/Storyboards/Base.lproj/Home.storyboard @@ -18,29 +18,253 @@ - - - + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + + + + + + - + @@ -60,5 +284,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Storyboards/Base.lproj/Main.storyboard b/GetRestIOS/Storyboards/Base.lproj/Main.storyboard index 735f43e..3c11f4d 100644 --- a/GetRestIOS/Storyboards/Base.lproj/Main.storyboard +++ b/GetRestIOS/Storyboards/Base.lproj/Main.storyboard @@ -29,7 +29,7 @@ - + @@ -49,8 +49,17 @@ + + + + + + + + + @@ -82,7 +91,7 @@ - + @@ -108,14 +117,14 @@ - + - + @@ -141,14 +150,14 @@ - + - + @@ -163,4 +172,10 @@ + + + + + + diff --git a/GetRestIOS/Storyboards/HomeGraphDetailModel.swift b/GetRestIOS/Storyboards/HomeGraphDetailModel.swift new file mode 100644 index 0000000..b3b907e --- /dev/null +++ b/GetRestIOS/Storyboards/HomeGraphDetailModel.swift @@ -0,0 +1,34 @@ +// +// homeGraphDetailModel.swift +// GetRestIOS +// +// Created by 박경선 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import Foundation + +struct HomeGraphDetailModel : Codable { + let portfolioTitle : String? + let portfolioDuration : String? + let portfolioHashTags : [String]? + +// enum CodingKeys: String, CodingKey { +// case userIdx = "userIdx" +// case storeIdx = "storeIdx" +// case isFavorite = "isFavorite" +// } +// +// init(from decoder: Decoder) throws {} +// let values = try decoder.container(keyedBy: CodingKeys.self) +// portfolioTitle = try values.decodeIfPresent(String.self, forKey: .portfolioTitle) +// portfolioDuration = try values.decodeIfPresent(String.self, forKey: .portfolioDuration) +// portfolioHashTags = try values.decodeIfPresent(String.self, forKey: .portfolioHashTags) +// } + init(_ title: String, _ duration: String, _ hashTag: [String] = []){ + self.portfolioTitle = title + self.portfolioDuration = duration + self.portfolioHashTags = hashTag + } + +} diff --git a/GetRestIOS/Storyboards/PopUp.storyboard b/GetRestIOS/Storyboards/PopUp.storyboard new file mode 100644 index 0000000..9569bc7 --- /dev/null +++ b/GetRestIOS/Storyboards/PopUp.storyboard @@ -0,0 +1,609 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Storyboards/Portfolio.storyboard b/GetRestIOS/Storyboards/Portfolio.storyboard index d12d878..356f031 100644 --- a/GetRestIOS/Storyboards/Portfolio.storyboard +++ b/GetRestIOS/Storyboards/Portfolio.storyboard @@ -10,21 +10,234 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -44,5 +257,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Storyboards/PortfolioDetailModel.swift b/GetRestIOS/Storyboards/PortfolioDetailModel.swift new file mode 100644 index 0000000..8668fc7 --- /dev/null +++ b/GetRestIOS/Storyboards/PortfolioDetailModel.swift @@ -0,0 +1,38 @@ +// +// PortfolioDetailModel.swift +// GetRestIOS +// +// Created by 박경선 on 04/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import Foundation + +struct PortfolioDetailModel : Codable { + let portfolioCategory : String? + let portfolioTitle : String? + let portfolioDuration : String? + let portfolioHashTags : [String]? + let portfolioContent: String? + + // enum CodingKeys: String, CodingKey { + // case userIdx = "userIdx" + // case storeIdx = "storeIdx" + // case isFavorite = "isFavorite" + // } + // + // init(from decoder: Decoder) throws {} + // let values = try decoder.container(keyedBy: CodingKeys.self) + // portfolioTitle = try values.decodeIfPresent(String.self, forKey: .portfolioTitle) + // portfolioDuration = try values.decodeIfPresent(String.self, forKey: .portfolioDuration) + // portfolioHashTags = try values.decodeIfPresent(String.self, forKey: .portfolioHashTags) + // } + init(_ category: String, _ title: String, _ duration: String, _ hashTag: [String] = [], _ content: String){ + self.portfolioCategory = category + self.portfolioTitle = title + self.portfolioDuration = duration + self.portfolioHashTags = hashTag + self.portfolioContent = content + } + +} diff --git a/GetRestIOS/Storyboards/Recruit.storyboard b/GetRestIOS/Storyboards/Recruit.storyboard index ef44265..340f8bd 100644 --- a/GetRestIOS/Storyboards/Recruit.storyboard +++ b/GetRestIOS/Storyboards/Recruit.storyboard @@ -10,22 +10,356 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -44,5 +378,631 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Storyboards/TableViewController.swift b/GetRestIOS/Storyboards/TableViewController.swift new file mode 100644 index 0000000..1c2885e --- /dev/null +++ b/GetRestIOS/Storyboards/TableViewController.swift @@ -0,0 +1,90 @@ +// +// TableViewController.swift +// GetRestIOS +// +// Created by 박경선 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class TableViewController: UITableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Uncomment the following line to preserve selection between presentations + // self.clearsSelectionOnViewWillAppear = false + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + // #warning Incomplete implementation, return the number of sections + return 0 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + // #warning Incomplete implementation, return the number of rows + return 0 + } + + /* + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) + + // Configure the cell... + + return cell + } + */ + + /* + // Override to support conditional editing of the table view. + override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the specified item to be editable. + return true + } + */ + + /* + // Override to support editing the table view. + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + // Delete the row from the data source + tableView.deleteRows(at: [indexPath], with: .fade) + } else if editingStyle == .insert { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + + /* + // Override to support rearranging the table view. + override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { + + } + */ + + /* + // Override to support conditional rearranging of the table view. + override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the item to be re-orderable. + return true + } + */ + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Storyboards/UIColor+Extensions.swift b/GetRestIOS/Storyboards/UIColor+Extensions.swift index 2cfbf71..ea10767 100644 --- a/GetRestIOS/Storyboards/UIColor+Extensions.swift +++ b/GetRestIOS/Storyboards/UIColor+Extensions.swift @@ -12,7 +12,71 @@ extension UIColor { // Usage : UIColor.mainGreen @nonobjc class var mainGreen: UIColor { + return UIColor(red: 130.0/255.0, green: 191.0/255.0, blue: 89.0/255.0, alpha: 1.0) + } + + @nonobjc class var graphBackgroundWhite: UIColor { + return UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0) + } + + @nonobjc class var graphBarGray: UIColor { + return UIColor(red: 219.0/255.0, green: 219.0/255.0, blue: 219.0/255.0, alpha: 1.0) + } + + @nonobjc class var graphLineGray: UIColor { + return UIColor(red: 238.0/255.0, green: 238.0/255.0, blue: 238.0/255.0, alpha: 1.0) + } + + @nonobjc class var mainColorBlue: UIColor { + return UIColor(red: 30.0/255.0, green: 48.0/255.0, blue: 91.0/255.0, alpha: 1.0) + } + + @nonobjc class var mainColorGreen: UIColor { + return UIColor(red: 130.0/255.0, green: 191.0/255.0, blue: 89.0/255.0, alpha: 1.0) + } + + @nonobjc class var selectedBarColorBlue: UIColor { return UIColor(red: 155.0/255.0, green: 203.0/255.0, blue: 125.0/255.0, alpha: 1.0) } + @nonobjc class var mainBackgroudGray: UIColor { + return UIColor(red: 247.0/255.0, green: 247.0/255.0, blue: 247.0/255.0, alpha: 1.0) + } + + @nonobjc class var shadow: UIColor { + return UIColor(red: 30.0/255.0, green: 48.0/255.0, blue: 91.0/255.0, alpha: 1.0) + } + + @nonobjc class var btnBarBackgroundColor: UIColor { + return UIColor(red: 248.0/255.0, green: 249.0/255.0, blue: 249.0/255.0, alpha: 1.0) + } + + @nonobjc class var btnBarItemTitleColor: UIColor { + return UIColor(red: 30.0/255.0, green: 30.0/255.0, blue: 30.0/255.0, alpha: 1.0) + } + + @nonobjc class var selectedBtnBarColor: UIColor { + return UIColor(red: 30.0/255.0, green: 48.0/255.0, blue: 91.0/255.0, alpha: 1.0) + } + + @nonobjc class var barMainGreen: UIColor { + return UIColor(red: 130.0/255.0, green: 191.0/255.0, blue: 89.0/255.0, alpha: 1.0) + } + + @nonobjc class var lightGray: UIColor { + return UIColor(red: 245.0/255.0, green: 245.0/255.0, blue: 245.0/255.0, alpha: 1.0) + } + + @nonobjc class var bottomGray: UIColor { + return UIColor(red: 216.0/255.0, green: 216.0/255.0, blue: 216.0/255.0, alpha: 1.0) + } + + + + + + + + + } diff --git a/GetRestIOS/TableViewController.swift b/GetRestIOS/TableViewController.swift new file mode 100644 index 0000000..1c2885e --- /dev/null +++ b/GetRestIOS/TableViewController.swift @@ -0,0 +1,90 @@ +// +// TableViewController.swift +// GetRestIOS +// +// Created by 박경선 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class TableViewController: UITableViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Uncomment the following line to preserve selection between presentations + // self.clearsSelectionOnViewWillAppear = false + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + // #warning Incomplete implementation, return the number of sections + return 0 + } + + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + // #warning Incomplete implementation, return the number of rows + return 0 + } + + /* + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) + + // Configure the cell... + + return cell + } + */ + + /* + // Override to support conditional editing of the table view. + override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the specified item to be editable. + return true + } + */ + + /* + // Override to support editing the table view. + override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + // Delete the row from the data source + tableView.deleteRows(at: [indexPath], with: .fade) + } else if editingStyle == .insert { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } + } + */ + + /* + // Override to support rearranging the table view. + override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) { + + } + */ + + /* + // Override to support conditional rearranging of the table view. + override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + // Return false if you do not want the item to be re-orderable. + return true + } + */ + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/GetRestIOS/Views/CardView.swift b/GetRestIOS/Views/CardView.swift new file mode 100644 index 0000000..2320041 --- /dev/null +++ b/GetRestIOS/Views/CardView.swift @@ -0,0 +1,41 @@ +// +// CardView.swift +// GetRestIOS +// +// Created by 박경선 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +@IBDesignable +class CardView: UIView { + + @IBInspectable var cornerRadius: CGFloat = 2 + + @IBInspectable var shadowOffsetWidth: Int = 0 + @IBInspectable var shadowOffsetHeight: Int = 3 + @IBInspectable var shadowOpacity: Float = 0.5 + + let presentingDuration = 0.5 + let dismissDuration = 0.35 + + override func layoutSubviews() { + layer.cornerRadius = cornerRadius + let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius) + layer.masksToBounds = false + layer.shadowColor = UIColor(red: 30.0/255.0, green: 48.0/255.0, blue: 91.0/255.0, alpha: 0.4).cgColor + layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight); + layer.shadowOpacity = shadowOpacity + layer.shadowPath = shadowPath.cgPath + } + + @IBAction func goPortfolioPageAction(_ sender: UIButton) { + layer.backgroundColor = UIColor.mainGreen.cgColor +// let bubble: BubbleTransition = BubbleTransition() +// bubble.startingPoint = sender.center +// bubble.transitionMode = TransitionMode.Present +// bubble.bubbleColor = UIColor.mainGreen + + } +} diff --git a/GetRestIOS/Views/ChipCollectionViewCell.swift b/GetRestIOS/Views/ChipCollectionViewCell.swift new file mode 100644 index 0000000..58e9923 --- /dev/null +++ b/GetRestIOS/Views/ChipCollectionViewCell.swift @@ -0,0 +1,23 @@ +// +// ChipCollectionViewCell.swift +// GetRestIOS +// +// Created by 최리안 on 06/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class ChipCollectionViewCell: UICollectionViewCell { + + + @IBOutlet var roundChip: UIView! + @IBOutlet var chipLabel: UILabel! + + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + } + +} diff --git a/GetRestIOS/Views/ChipCollectionViewCell.xib b/GetRestIOS/Views/ChipCollectionViewCell.xib new file mode 100644 index 0000000..278ea01 --- /dev/null +++ b/GetRestIOS/Views/ChipCollectionViewCell.xib @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Views/HashTagCollectionViewCell.xib b/GetRestIOS/Views/HashTagCollectionViewCell.xib new file mode 100644 index 0000000..66e31af --- /dev/null +++ b/GetRestIOS/Views/HashTagCollectionViewCell.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.swift b/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.swift new file mode 100644 index 0000000..8da42b6 --- /dev/null +++ b/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.swift @@ -0,0 +1,25 @@ +// +// HashTagCollectionViewCell.swift +// GetRestIOS +// +// Created by 박경선 on 03/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class HashTagCollectionViewCell: UICollectionViewCell { + + @IBOutlet weak var hashTagView: UIView! + @IBOutlet weak var hashTagLabel: UILabel! + override func awakeFromNib() { + super.awakeFromNib() + + if let hashTagLabel = hashTagLabel { + hashTagLabel.layer.cornerRadius = hashTagLabel.frame.size.height/2 + hashTagLabel.layer.backgroundColor = UIColor.mainGreen.cgColor +// hashTagLabel.layer.borderColor = UIColor.mainColorBlue.cgColor +// hashTagLabel.layer.borderWidth = 0.5 + } + } +} diff --git a/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.xib b/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.xib new file mode 100644 index 0000000..ea5f53f --- /dev/null +++ b/GetRestIOS/Views/HashTagView/HashTagCollectionViewCell.xib @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GetRestIOS/Views/HomeGraphDetailTableViewCell.swift b/GetRestIOS/Views/HomeGraphDetailTableViewCell.swift new file mode 100644 index 0000000..f902cc0 --- /dev/null +++ b/GetRestIOS/Views/HomeGraphDetailTableViewCell.swift @@ -0,0 +1,28 @@ +// +// HomeGraphTableView.swift +// GetRestIOS +// +// Created by 박경선 on 02/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class HomeGraphDetailTableViewCell: UITableViewCell { + + @IBOutlet weak var portfolioTitle: UILabel! + @IBOutlet weak var portfolioDuration: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + } + func addWhitespace(tag: String) -> String { + return tag + " " + } + + @IBAction func goPortfolioPageAction(_ sender: UIButton) { + sender.tintColor = UIColor.white + portfolioTitle.textColor = UIColor.white + portfolioDuration.textColor = UIColor.white + } +} diff --git a/GetRestIOS/Views/PortfolioDetailTableViewCell.swift b/GetRestIOS/Views/PortfolioDetailTableViewCell.swift new file mode 100644 index 0000000..cbccebe --- /dev/null +++ b/GetRestIOS/Views/PortfolioDetailTableViewCell.swift @@ -0,0 +1,47 @@ +//// +//// PortfolioDetailTableViewCell.swift +//// Alamofire +//// +//// Created by 박경선 on 04/07/2019. +//// +// +//import UIKit +// +//class PortfolioDetailTableViewaCell: UITableViewCell { +// +// @IBOutlet weak var categoryLabel: UILabel! +// @IBOutlet weak var titleLabel: UILabel! +// @IBOutlet weak var durationLabel: UILabel! +// @IBOutlet weak var hashTagsCollectionView: UICollectionView! +// @IBOutlet weak var contentLabel: UILabel! +// var portfolioHashTags: [String] = [] +// +// override func awakeFromNib() { +// super.awakeFromNib() +// let nibName = UINib(nibName: "HashTagCollectionViewCell", bundle: nil) +// self.hashTagsCollectionView.delegate = self +// self.hashTagsCollectionView.dataSource = self +// self.hashTagsCollectionView.register(nibName, forCellWithReuseIdentifier: "hashTagCell") +// let hashTagsCVFlowLayout = hashTagsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout +// hashTagsCVFlowLayout.estimatedItemSize = CGSize(width: 64, height: 27) +// contentLabel.numberOfLines = 0 +// } +// +// override func setSelected(_ selected: Bool, animated: Bool) { +// super.setSelected(selected, animated: animated) +// } +// +//} +// +//extension PortfolioDetailTableViewCell : UICollectionViewDelegate, UICollectionViewDataSource { +// func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { +// return portfolioHashTags.count +// } +// +// func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { +// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashTagCell", for: indexPath) as! HashTagCollectionViewCell +// let tagString = (portfolioHashTags[indexPath.row]) + " " +// cell.hashTagLabel?.text = tagString +// return cell +// } +//} diff --git a/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.swift b/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.swift new file mode 100644 index 0000000..55bea7e --- /dev/null +++ b/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.swift @@ -0,0 +1,30 @@ +// +// PortfolioTableViewCell.swift +// GetRestIOS +// +// Created by 최리안 on 06/07/2019. +// Copyright © 2019 최리안. All rights reserved. +// + +import UIKit + +class PortfolioTableViewCell: UITableViewCell { + + @IBOutlet var portfolioImg: UIImageView! + @IBOutlet var portfolioTitle: UILabel! + @IBOutlet var portfolioDate: UILabel! + @IBOutlet var chipCollection: UICollectionView! + + override func awakeFromNib() { + super.awakeFromNib() + // Initialization code + portfolioImg.layer.cornerRadius = 5 + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.xib b/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.xib new file mode 100644 index 0000000..478378f --- /dev/null +++ b/GetRestIOS/Views/PortfolioView/PortfolioTableViewCell.xib @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Podfile b/Podfile index 50ea986..be406ce 100644 --- a/Podfile +++ b/Podfile @@ -10,4 +10,6 @@ target 'GetRestIOS' do pod 'AlamofireObjectMapper', '~> 5.2.0' pod 'Kingfisher', '~> 4.10.1' pod 'ObjectMapper', '~> 3.4.2' + pod 'ScrollableGraphView' + pod 'XLPagerTabStrip', '~> 9.0' end diff --git a/Podfile.lock b/Podfile.lock index 69ea998..294bed1 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -5,12 +5,16 @@ PODS: - ObjectMapper (~> 3.4) - Kingfisher (4.10.1) - ObjectMapper (3.4.2) + - ScrollableGraphView (4.0.6) + - XLPagerTabStrip (9.0.0) DEPENDENCIES: - Alamofire (~> 4.8.2) - AlamofireObjectMapper (~> 5.2.0) - Kingfisher (~> 4.10.1) - ObjectMapper (~> 3.4.2) + - ScrollableGraphView + - XLPagerTabStrip (~> 9.0) SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -18,13 +22,17 @@ SPEC REPOS: - AlamofireObjectMapper - Kingfisher - ObjectMapper + - ScrollableGraphView + - XLPagerTabStrip SPEC CHECKSUMS: Alamofire: ae5c501addb7afdbb13687d7f2f722c78734c2d3 AlamofireObjectMapper: 92b6ce2423a9d159e686f6a1d514a009bf903ddc Kingfisher: c148cd7b47ebde9989f6bc7c27dcaa79d81279a0 ObjectMapper: 0d4402610f4e468903ae64629eec4784531e5c51 + ScrollableGraphView: 4af35d4ea9ecdec665d34a74da51da161ddff8ac + XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: 66eb3c51d45025db9eb25be3040e5f5c144134de +PODFILE CHECKSUM: 1b37073836683472ca008485d68210d5dc2b9d89 COCOAPODS: 1.6.1 diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index 69ea998..294bed1 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -5,12 +5,16 @@ PODS: - ObjectMapper (~> 3.4) - Kingfisher (4.10.1) - ObjectMapper (3.4.2) + - ScrollableGraphView (4.0.6) + - XLPagerTabStrip (9.0.0) DEPENDENCIES: - Alamofire (~> 4.8.2) - AlamofireObjectMapper (~> 5.2.0) - Kingfisher (~> 4.10.1) - ObjectMapper (~> 3.4.2) + - ScrollableGraphView + - XLPagerTabStrip (~> 9.0) SPEC REPOS: https://github.com/cocoapods/specs.git: @@ -18,13 +22,17 @@ SPEC REPOS: - AlamofireObjectMapper - Kingfisher - ObjectMapper + - ScrollableGraphView + - XLPagerTabStrip SPEC CHECKSUMS: Alamofire: ae5c501addb7afdbb13687d7f2f722c78734c2d3 AlamofireObjectMapper: 92b6ce2423a9d159e686f6a1d514a009bf903ddc Kingfisher: c148cd7b47ebde9989f6bc7c27dcaa79d81279a0 ObjectMapper: 0d4402610f4e468903ae64629eec4784531e5c51 + ScrollableGraphView: 4af35d4ea9ecdec665d34a74da51da161ddff8ac + XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 -PODFILE CHECKSUM: 66eb3c51d45025db9eb25be3040e5f5c144134de +PODFILE CHECKSUM: 1b37073836683472ca008485d68210d5dc2b9d89 COCOAPODS: 1.6.1 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index dfb4003..b8e8238 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -3,126 +3,189 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ - 059603888075C317971A67A7C0FB2BDF /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4255134418730644F5FA8363F15E2D8F /* Alamofire.framework */; }; - 059D92B7BBFBEC53E9A3B6E11C5C3B3A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D9773CA4B1686C673ED6201A7FBE437 /* Response.swift */; }; - 0A39AF55285A3A4F7CBABB6D822FA4A3 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 859C45B7E06016B33C01650FE8E7F918 /* Alamofire.swift */; }; - 0DA85BF427253C535FE9342734550328 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */; }; - 12DDF5D318C9D3751C849911AEC01252 /* DateFormatterTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44FFD6F1D1857E466CCEE4F199694AB4 /* DateFormatterTransform.swift */; }; - 18CD6ACC5D6B35DDF71828D362BFC8DA /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76885D5D3123A4314F1D74F4BE12932E /* Resource.swift */; }; - 1C8C653AEC6D8C5FC8A878DFAC54FFBC /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A5A4D8C198D0E089F6A67B52A12679 /* String+MD5.swift */; }; - 1D29D2ACADF961F69D32B06FA6A09E28 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39926F7C8239ACC4026E1A40D199E5C3 /* Notifications.swift */; }; - 1E19BE549007C32EA9CB5B34BCE0AB18 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = E77EE86EDC2A7914429626F2467AE2FB /* Kingfisher.swift */; }; - 1F13C2E572C245E1CFEC1C8BFC632D16 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44C518042B4A53AF8527CB85E8B373E /* ImageDownloader.swift */; }; - 1FE848F3B55196B7E9AF9A0A60A8858D /* CodableTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21ECC437C69287ECE940E1D07C5F37F0 /* CodableTransform.swift */; }; - 231223CA805B03D9461EBC81252C59E1 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A27C1950E95A41FAAB6EC87AD598D35 /* CFNetwork.framework */; }; - 248CB57DC59B3C3E323C72F3F3592E25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */; }; - 2EA629538196B86B6890040FE2B952A7 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3476A7731838FF67CCC062E609615F98 /* Indicator.swift */; }; - 33E1D1AABC1408623B60017EB8DA0A88 /* ObjectMapper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE46D64CBCC85526D9A6FC8A3847ACB /* ObjectMapper.framework */; }; - 355C18EEC82624A06A6CC93965258E33 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E4E5671C167BED48AC7BF9D60EA7EFC /* Request.swift */; }; - 3E0248F4337A68863FDECB5976691738 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C85BE459F8C97CC387CDA34555579DB0 /* ImageProcessor.swift */; }; - 3E0749AF6C51BCF0E4A41CF1D6A76FED /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B503ADC91284D0D43D3D0DA06B8D07A /* DispatchQueue+Alamofire.swift */; }; - 4185FE9A95B12CC0D37F69E0218B4430 /* TransformOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16D74C25427434557C97CA31CE0023D8 /* TransformOperators.swift */; }; - 44378244C508499FA64E0DD67E921A47 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EEC54DA472B6D8E9FBE06C027C3468E0 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 46D2B00CB67EFC58897132DDD7035FCF /* DataTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A661CAF0D7CED3DDCDCB26FE178492 /* DataTransform.swift */; }; - 475F0230FDB114B5AAF04C2FC9646334 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = A33FAB021477544550E0484538F39D04 /* ImagePrefetcher.swift */; }; - 548F7B688D02591CEF8DE9E61936138C /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = 06B91D8C89C7099D9D9C4689331A840C /* Kingfisher.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 564F4F2F244081DAE769DE4A746A2F9E /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8E0B7D165C4ABFECCDA1E3CF311A99 /* KingfisherManager.swift */; }; - 570066534F8EABF93881D924B0B872E3 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA74144E6C71B4D56311916DCF6B23F3 /* CacheSerializer.swift */; }; - 5DB0B564B21758D9647AB5441EEAA88C /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63143E25F0EECF2DBB6282505A59A67B /* KingfisherOptionsInfo.swift */; }; - 60B6C2A003864AAD3A426448152F67BE /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA7F04056A57C86FDFFB4BEBD71D7E3 /* Timeline.swift */; }; - 6347B1BA6D146FE1BF6D4C140D5CDA04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */; }; - 65B777FA3048CEBE127F501E9B053C0A /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42FE39508FEBD9AB434D294E6E652776 /* Placeholder.swift */; }; - 6747171D3A39E70D1C7A83325AAA0589 /* ISO8601DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 081A385E133F9E514152B2B7F39F0A00 /* ISO8601DateTransform.swift */; }; - 6B5F278ECD2B9B60B94C38AE81A38DED /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26F1FD75EC50095D98937FDE65E2F4F1 /* UIButton+Kingfisher.swift */; }; - 6D6A2EF2CB5DD5F283DA18AD8CF8E449 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9770B58667C7130802B59828F60356F /* ImageTransition.swift */; }; - 6E6B0785C10AD5D4E15AB57B9DF999F8 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 484BD670A85D89264544DF134D2FE7D4 /* FormatIndicatedCacheSerializer.swift */; }; - 6EFD003458AE7F689DEA720A2030C261 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBBE04A0D479CB656A3B95014C27A21E /* ResponseSerialization.swift */; }; - 700D3D95AF9520CB227846DFD943A2DA /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B8FF044E8D6809DBC4028646847C09 /* ParameterEncoding.swift */; }; - 7379A39BC638AEA0AA074DCA25AA47FC /* AlamofireObjectMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A64AA90C724E10B7A4AE18CB07F84BEF /* AlamofireObjectMapper.swift */; }; - 73AB05789A4982944AF68DBD013E3EB7 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A39D51892D67AD7B6F7826C8041033 /* NetworkReachabilityManager.swift */; }; - 760AA26FB53D5C927B5C125845C50BB1 /* EnumOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BB966369055580593063ECFCD67DB0 /* EnumOperators.swift */; }; - 772911DA6E33D1CBBC30131B7C8BDBB3 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F040ED1FF22031BE793CE58C15BA980 /* Alamofire-dummy.m */; }; - 77E8F0EB9FFBE2E3EB0C77095C644606 /* TaskDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02B0B844C8BB6ACE78934CE1BE235738 /* TaskDelegate.swift */; }; - 7E3538A6992A38276764936A9733493D /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CCA6AECAF1F1FFC3C7009ACD667485B /* AFError.swift */; }; - 7F424C046646FE578B5BAA8AE3D30B37 /* ObjectMapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = FD5E3ED772B559F275F7AAA6D57D777F /* ObjectMapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 87646781F3CA197B0FADF65A73F36CDD /* TransformOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC062D6C5AB671F83AD33C941FD3DEC8 /* TransformOf.swift */; }; - 896017153BF6DB61AC97C92B1F848A60 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0986D2553648F0746A217E033FB09BD8 /* ImageModifier.swift */; }; - 8CCDCE25A6246A1829FFC0745F48459F /* EnumTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68FB2636BCF0264F8B2075E77728E7F8 /* EnumTransform.swift */; }; - 8D2A6A90A6DDAF75EA52D471258545CC /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC265EDC639233AB0FCA13E30A54E6E2 /* ServerTrustPolicy.swift */; }; - 912AA912DC5113A3F4C4DBDCBF2FC639 /* ToJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EA0A029FEC1907605E9D863C545E9A0 /* ToJSON.swift */; }; - 92303AD98115DD45A7DF2827BB0F5E1F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */; }; - 991BD190737B8F4F6BA3EE4E1F79A050 /* CustomDateFormatTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = D41D72942B51E7E4D598F5F509EB9778 /* CustomDateFormatTransform.swift */; }; - 9FDB93E1D2AB4FCC476B39B6C178CE6D /* AlamofireObjectMapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 32676DA2198AB81AC5B1778F61F5F1CD /* AlamofireObjectMapper-dummy.m */; }; - A1EC41966B261DCE460BCDE5124A1DBE /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1BE85A224ACF4ED7D542F0DEAACC9D9 /* SessionDelegate.swift */; }; - A1F0EC361B7E6719A92C899459A44D5A /* Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8428186A0EBD623DC176DCE57C95E473 /* Mapper.swift */; }; - AA56769D8733D3F3E7976742D5ABA998 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063ED47B3A6B7EBA7FAA307C9CE26454 /* Validation.swift */; }; - AC41EFB3A536B92D9C635FEC9DBBB7F4 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B73420B939F155CE0DACD44FEAFCD5 /* Box.swift */; }; - AC8143A6AFC14DC3F0338EF36445BF38 /* NSDecimalNumberTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44E660163495097D6C8F07AA0EE5D9DB /* NSDecimalNumberTransform.swift */; }; - AEA829AB1A8AF2AD077A808AED6B178A /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B278F635359E6D2AA75C3095CC4A57 /* MultipartFormData.swift */; }; - B26DBECE911AB60775C6BE6FC6F7B5FE /* AlamofireObjectMapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 265ADD9480EBB2BA8B942FF7009CB94C /* AlamofireObjectMapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B3B39EB8A9162DE9F256CBDDDBB1141E /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FD982A938881006D4EDFA5CD6ABDB87 /* RequestModifier.swift */; }; - B3CD844F6AB8701256B0931EAC4780DD /* ImmutableMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F9FDB8A1BF8A12399EEEA39767E1E6D /* ImmutableMappable.swift */; }; - B6F6E4CC26451E91B59FAE0F6841DC1F /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AF759A7875241995843338214EBEAE93 /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CBB9F2B42B5927CD6DE5F7AA3E0CAC85 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4BE99B771521C0D185E9D417F06D5D6 /* Image.swift */; }; - CCD2951D6F2996525953F148B99568AD /* Pods-GetRestIOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EF35C02E663D07829AE36222CA625417 /* Pods-GetRestIOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CEC9BB6496ACA4458CBDAC895780E692 /* TransformType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 590478C5EBDEFAA438EA754CB1062C72 /* TransformType.swift */; }; - D1EBE884C11FF785A91711AF378CAA16 /* MapError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8C946D49463345DE68F51C4F05D13B /* MapError.swift */; }; - D331786C87892C26B432086A93BB6634 /* DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65CFE28DA5E9100DF0F00C16E2DC8044 /* DateTransform.swift */; }; - D3FA0AA634AAEA99AB3FABC36BB4958C /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E0D38D19A85ECDA8664D49E35AEBFC /* SessionManager.swift */; }; - DF8309B711A4635FD438BF1F8C2D494B /* FromJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7C63F137ADA1291A83D42F8B26692FF /* FromJSON.swift */; }; - E303598CA94725108F75FBC0253E7C0E /* ObjectMapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C5888FB7491CE4BB850BFB065358EB28 /* ObjectMapper-dummy.m */; }; - E66567F8C1A941AC2B74B649A01918BF /* Pods-GetRestIOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 56D8899538F67365E25B874E436A3636 /* Pods-GetRestIOS-dummy.m */; }; - E6711889B27F4D746B9367919BEDC39E /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F15BCF2644E13B6E0E4CC8A7DF462122 /* Filter.swift */; }; - E6DE03E3E1E37473B26BDB3B302A0D2D /* DictionaryTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E3B48B123104E0BE7BBE19C29E41B5B /* DictionaryTransform.swift */; }; - E95148DBC748BC43DA3F1ACAE3AA5D4D /* ThreadHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 139FA5FCB8E6F3B1A372C16D78E0FBF0 /* ThreadHelper.swift */; }; - E9EEAA672984812FFBF3CBA15826BB6F /* HexColorTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 090193265B0CD8D9028273CE12F56A8B /* HexColorTransform.swift */; }; - EB0DD8CEA1A69867A30267439C970440 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF6624042A7DEEF20CB03340E756F4F0 /* Result.swift */; }; - EC3217AEA6906A7EC227471D29EE5093 /* Mappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A222F3A3D2549F6C0EBEE7354F7DCDF /* Mappable.swift */; }; - EE86D619512E9C8FD79CC9F90C173579 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B5EB0943660D8666E85F2977E6B301 /* ImageCache.swift */; }; - F562EBBB71DFA269B42FD4D8E0BACC35 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5C4F316CF414D6E615CFFD150F4C7BD /* Map.swift */; }; - F5B7B673E69BDFB360FA71EEB91B31A7 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9908EC83A140886F26FEC8422443D95 /* AnimatedImageView.swift */; }; - F7BF69DBCE70A59684FEC6778DA219A6 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A45391F54CDF31BBFE4606B3892900C /* ImageView+Kingfisher.swift */; }; - FA6272678233EBE00A54CBF3E92E4E92 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */; }; - FB2FF2FBF0AE83FF31DE1B6B6D08DF59 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEC43837BB965A8CCDAAF75C72A1F533 /* Operators.swift */; }; - FD7578F183AA83B2949887C4C1EADF76 /* IntegerOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63BCB4CFE1F5AFD4424122B257731C95 /* IntegerOperators.swift */; }; - FDD25EFD99DD6732AE1BE5F3F0036505 /* URLTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD6A71BD6370D469BBB9C90975B2628D /* URLTransform.swift */; }; - FF3E0B16F554EB26CA3185D006FE357A /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E0C5323C879F05F46A45E8686D67E83 /* Kingfisher-dummy.m */; }; + 023AE5E73991D565BF5C879492D85D87 /* BaseButtonBarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 482D9F2306210A23ABF322A7C871F20B /* BaseButtonBarPagerTabStripViewController.swift */; }; + 025A3E121CFC95A918072DCC749B9820 /* Pods-GetRestIOS-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 56D8899538F67365E25B874E436A3636 /* Pods-GetRestIOS-dummy.m */; }; + 059603888075C317971A67A7C0FB2BDF /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C373132FA716EB448679FD92D213E1A /* Alamofire.framework */; }; + 059D92B7BBFBEC53E9A3B6E11C5C3B3A /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59BE684F52FD0C1BC4287B5D21366202 /* Response.swift */; }; + 07942666EC70498FC0CE360ACDC04D3A /* FXPageControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B53D94C0B9FE436D110395B0E6AF3ED /* FXPageControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0A2F1AEDDCF1CE5E556D9092B9FB4A54 /* FXPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5448C36BC45DA3C80A9EAC9EFEF19C27 /* FXPageControl.m */; }; + 0A39AF55285A3A4F7CBABB6D822FA4A3 /* Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19383E6298DB0C3211FFD100F3092492 /* Alamofire.swift */; }; + 0DA85BF427253C535FE9342734550328 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 12DDF5D318C9D3751C849911AEC01252 /* DateFormatterTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC5A0DE9E55BE79437FB5CA0791E6AE /* DateFormatterTransform.swift */; }; + 14A69231E9B356F73BF669FE8A0A98BF /* Pods-GetRestIOS-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EF35C02E663D07829AE36222CA625417 /* Pods-GetRestIOS-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 18CD6ACC5D6B35DDF71828D362BFC8DA /* Resource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9A712BEA8EEE22DEF0C1E2394AB5188 /* Resource.swift */; }; + 1C8C653AEC6D8C5FC8A878DFAC54FFBC /* String+MD5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A7F57C3FE0F83A32AB42C9F50ADE083 /* String+MD5.swift */; }; + 1D29D2ACADF961F69D32B06FA6A09E28 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40D33A9C9C21FF91DEF00DE74B61F7A6 /* Notifications.swift */; }; + 1E19BE549007C32EA9CB5B34BCE0AB18 /* Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63D453B9D697B3E58A4B054AA8B5F925 /* Kingfisher.swift */; }; + 1F13C2E572C245E1CFEC1C8BFC632D16 /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58194FC78E57E424CCD6A5499B346874 /* ImageDownloader.swift */; }; + 1FE848F3B55196B7E9AF9A0A60A8858D /* CodableTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3A26E62E83C727157AD429CFB1AA81 /* CodableTransform.swift */; }; + 231223CA805B03D9461EBC81252C59E1 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC69BB97A9D32BEE90E92E203F897EAE /* CFNetwork.framework */; }; + 248CB57DC59B3C3E323C72F3F3592E25 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 291C8ED59FCD3874D694E4BB67B3039B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 29B1A621E9EF143374D3D1705060F31E /* TwitterPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16BDA92AAD327B63574B7B1F52F879DA /* TwitterPagerTabStripViewController.swift */; }; + 2EA629538196B86B6890040FE2B952A7 /* Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0355AB3BC139259660241D81207E46 /* Indicator.swift */; }; + 33E1D1AABC1408623B60017EB8DA0A88 /* ObjectMapper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C1631ECBA1E8484DCCC5266D4E5F05D1 /* ObjectMapper.framework */; }; + 355C18EEC82624A06A6CC93965258E33 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B0C39B9A0747D1CBF8F7253CD393D7E /* Request.swift */; }; + 3D761F9B1CD980D1E1B0441D05E8FD09 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 3E0248F4337A68863FDECB5976691738 /* ImageProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287EF0A55C55781536CD26441DDCBA03 /* ImageProcessor.swift */; }; + 3E0749AF6C51BCF0E4A41CF1D6A76FED /* DispatchQueue+Alamofire.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF7298AE840E47712DEA79230FAE7694 /* DispatchQueue+Alamofire.swift */; }; + 4185FE9A95B12CC0D37F69E0218B4430 /* TransformOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5FAA5238EE2370609D01B43A4AF65DD /* TransformOperators.swift */; }; + 44378244C508499FA64E0DD67E921A47 /* Kingfisher-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B02E60A2228663BA06071EC4C9CBF9B1 /* Kingfisher-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 456B9D594F9E045823CC03B1A692F7CB /* ButtonBarViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C27973BB051B91C449BF29951175E3B5 /* ButtonBarViewCell.swift */; }; + 46D2B00CB67EFC58897132DDD7035FCF /* DataTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0E66A30373F212DBE1B636648395C03 /* DataTransform.swift */; }; + 475F0230FDB114B5AAF04C2FC9646334 /* ImagePrefetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71D787740C8D6B17DF369ED0179C372E /* ImagePrefetcher.swift */; }; + 4D5B30B36079E7CF6788A9404A1A1B94 /* BarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2257392425B9FC8FE7DC5B8095480985 /* BarPagerTabStripViewController.swift */; }; + 50E7AC236E46DA2903C80227393CB8AE /* GraphPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = D186D786A94E470E1857506D33C478D4 /* GraphPoint.swift */; }; + 52CBFC5C47D4072474CD951AD373D5BC /* IndicatorInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1FE093FAAB7C44666B5A8D775B2BE67 /* IndicatorInfo.swift */; }; + 548F7B688D02591CEF8DE9E61936138C /* Kingfisher.h in Headers */ = {isa = PBXBuildFile; fileRef = 3A959D62A4E9FEF5388D9BFD56339B21 /* Kingfisher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 564F4F2F244081DAE769DE4A746A2F9E /* KingfisherManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 071546085B39C5EBDCC89FC3DBACE514 /* KingfisherManager.swift */; }; + 567B0E636EEDC38CA73441BC2284A4E9 /* LineDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 681C5140E52BEDE25DAFEFABF4584E3E /* LineDrawingLayer.swift */; }; + 570066534F8EABF93881D924B0B872E3 /* CacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4514390946338881CF9BE7B0495C0B8A /* CacheSerializer.swift */; }; + 5B8E9B2484D4F4367D0244BD8FF8E948 /* XLPagerTabStrip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B0503EF175F4BEA7A81BE77D2277EB3 /* XLPagerTabStrip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5CD00709C49E904F708725B90316CBC6 /* BarDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8EE119C76C786A623216BDE69E20A62 /* BarDrawingLayer.swift */; }; + 5DB0B564B21758D9647AB5441EEAA88C /* KingfisherOptionsInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BC07248A46CC125113CE2C30CEA3C5F /* KingfisherOptionsInfo.swift */; }; + 5F4B7A4C9FFE0D3DB9AFD57EBC182E30 /* ScrollableGraphViewDrawingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B8DAFEAA10C5233BF36F2B1BF361033 /* ScrollableGraphViewDrawingDelegate.swift */; }; + 60B6C2A003864AAD3A426448152F67BE /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6BE12C2C3E7BCBBA238959F7E2D64C /* Timeline.swift */; }; + 6347B1BA6D146FE1BF6D4C140D5CDA04 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 65B777FA3048CEBE127F501E9B053C0A /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31276D9479F7A8A96A23AFC48D338CAA /* Placeholder.swift */; }; + 65E87B29E22B78A63FC86023BF0264B7 /* SegmentedPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A93EAFE31888336421F6D3D22A81982 /* SegmentedPagerTabStripViewController.swift */; }; + 6747171D3A39E70D1C7A83325AAA0589 /* ISO8601DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A272D6646A72A83DFE3AA54F3D9D310 /* ISO8601DateTransform.swift */; }; + 68EAE4F9EBA06D7D834206C4FAEBE36C /* ScrollableGraphView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3D44D7803A27A489426E10F4FDB427 /* ScrollableGraphView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6B5F278ECD2B9B60B94C38AE81A38DED /* UIButton+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758471292657321B219103490AE38DA7 /* UIButton+Kingfisher.swift */; }; + 6D6A2EF2CB5DD5F283DA18AD8CF8E449 /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = B463F2B96CD19C438F374BCC02C4F997 /* ImageTransition.swift */; }; + 6E6B0785C10AD5D4E15AB57B9DF999F8 /* FormatIndicatedCacheSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A08C53FC1F7E625C0D6D75B3820971A /* FormatIndicatedCacheSerializer.swift */; }; + 6EFD003458AE7F689DEA720A2030C261 /* ResponseSerialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 336205F45C9149396E080557B23946E4 /* ResponseSerialization.swift */; }; + 700D3D95AF9520CB227846DFD943A2DA /* ParameterEncoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C888BE4C402E6B5ED7125EA6BA55602 /* ParameterEncoding.swift */; }; + 7029EDDF782D6A4D7065ADB970065D57 /* Plot.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F7CBAC4B35DC776B09272F91613DE8 /* Plot.swift */; }; + 7379A39BC638AEA0AA074DCA25AA47FC /* AlamofireObjectMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E68E54859490ED3EDE52295924D0967C /* AlamofireObjectMapper.swift */; }; + 73AB05789A4982944AF68DBD013E3EB7 /* NetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E795872C69C8D8410973E82FBDD6DAA3 /* NetworkReachabilityManager.swift */; }; + 760AA26FB53D5C927B5C125845C50BB1 /* EnumOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60E0C08D9A74A0561B6BEF1DEB62F988 /* EnumOperators.swift */; }; + 772911DA6E33D1CBBC30131B7C8BDBB3 /* Alamofire-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E6831ED1EAE2F53B745790C1F8CFE22 /* Alamofire-dummy.m */; }; + 77E8F0EB9FFBE2E3EB0C77095C644606 /* TaskDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F477600F9218288C098618175DC7F622 /* TaskDelegate.swift */; }; + 79EA9C787417F6CEB3E1666F3234F7BC /* LinePlot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 388606EE6EFA76148FB2D79573DBB3A6 /* LinePlot.swift */; }; + 7E3538A6992A38276764936A9733493D /* AFError.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB3A743CD02031166893E78E41F287ED /* AFError.swift */; }; + 7F424C046646FE578B5BAA8AE3D30B37 /* ObjectMapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D89A00EB509B55B6C47435C586DCCA18 /* ObjectMapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 815A942158A2A9033C8CF892C0E9D42C /* PagerTabStripBehaviour.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D2698E77FA9001529C2BE746B535CB1 /* PagerTabStripBehaviour.swift */; }; + 849F6F5ED2DCFA725F0DA892F7020E73 /* ButtonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A2903B37D2E0C3DC4C1BD68031F8BAA3 /* ButtonCell.xib */; }; + 87646781F3CA197B0FADF65A73F36CDD /* TransformOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27368A4248280BB278CD91A4D3062EFC /* TransformOf.swift */; }; + 896017153BF6DB61AC97C92B1F848A60 /* ImageModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 642C623E19BB3031D369D16A70136236 /* ImageModifier.swift */; }; + 8992EB524FA3B181B2A5B0931B7AB835 /* DotPlot.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB21AF578F5EF0E2AA714BE7A6A3F783 /* DotPlot.swift */; }; + 8CCDCE25A6246A1829FFC0745F48459F /* EnumTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = E03008CEE402D6F6AE453E119D6475C0 /* EnumTransform.swift */; }; + 8D2A6A90A6DDAF75EA52D471258545CC /* ServerTrustPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC2AA462C4057CF70747E961D929900F /* ServerTrustPolicy.swift */; }; + 8EA6D69F71B0FB44A169563C491B43F3 /* ButtonBarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0EF37CC7FB45F50A748D753BD4FEF02 /* ButtonBarPagerTabStripViewController.swift */; }; + 912AA912DC5113A3F4C4DBDCBF2FC639 /* ToJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = C015B603DAF4B79DE58EF72EA32EFB8F /* ToJSON.swift */; }; + 92303AD98115DD45A7DF2827BB0F5E1F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + 95644C8A14F1F77F1D0D77592C2D6B5A /* FillDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCAE054B0D98D013C8306CF8F2D8C460 /* FillDrawingLayer.swift */; }; + 991BD190737B8F4F6BA3EE4E1F79A050 /* CustomDateFormatTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A6E85F2586EA3645783E734878EF4FE /* CustomDateFormatTransform.swift */; }; + 9CE49D8096A1CB52CDA2DFEE70D0AD35 /* XLPagerTabStrip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 279C1541DFB55EF919CDD30EAC4EB85E /* XLPagerTabStrip-dummy.m */; }; + 9D0B00EAA4282312840787D9A4CEE4AB /* LabelPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8A1E27C84AE0F02149E1E7AF0B45DA02 /* LabelPool.swift */; }; + 9D98A81426C3604FB3084DEA56EEB0BA /* GraphPointAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478B759C865EE900E018EB4D35DE9CFC /* GraphPointAnimation.swift */; }; + 9FDB93E1D2AB4FCC476B39B6C178CE6D /* AlamofireObjectMapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DCEAD5244CC26F1CA5DC0A1372ACD59 /* AlamofireObjectMapper-dummy.m */; }; + A0520FC66695256426D743FA2D42D8FF /* BarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CCF99BC62103EB3B3ED4AF859924FF4 /* BarView.swift */; }; + A1EC41966B261DCE460BCDE5124A1DBE /* SessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55E27F1214B30F1DF77D84188B9C775 /* SessionDelegate.swift */; }; + A1F0EC361B7E6719A92C899459A44D5A /* Mapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49708E87077B90FFDD0C2B3436324325 /* Mapper.swift */; }; + A615C52520DE484B41D7CBBC67E0FDB4 /* ReferenceLineDrawingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8B1B71428493C07C5CFB396270D3A64 /* ReferenceLineDrawingView.swift */; }; + AA56769D8733D3F3E7976742D5ABA998 /* Validation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 609B52F9224367546F2395C0014AD14A /* Validation.swift */; }; + AC41EFB3A536B92D9C635FEC9DBBB7F4 /* Box.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8DA6FD51672F9002E1076D7AA96625E /* Box.swift */; }; + AC8143A6AFC14DC3F0338EF36445BF38 /* NSDecimalNumberTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E81290EF70675F31652388CD135E09B /* NSDecimalNumberTransform.swift */; }; + AEA829AB1A8AF2AD077A808AED6B178A /* MultipartFormData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F6B7C83F1CD39BE7D26BF10F196C29 /* MultipartFormData.swift */; }; + B0091594D9D26432A7AB3F212D7C4933 /* PagerTabStripError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D5EE3A418086BD6CBB44A6349B7B71E /* PagerTabStripError.swift */; }; + B26DBECE911AB60775C6BE6FC6F7B5FE /* AlamofireObjectMapper-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 03EB1BB5410BF3212336C56D489D32A3 /* AlamofireObjectMapper-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B3B39EB8A9162DE9F256CBDDDBB1141E /* RequestModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C17725F6B1B0D98A634B5B391B504F /* RequestModifier.swift */; }; + B3CD844F6AB8701256B0931EAC4780DD /* ImmutableMappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F42FCFB86E5633C4BF258CADEF4A792B /* ImmutableMappable.swift */; }; + B6F6E4CC26451E91B59FAE0F6841DC1F /* Alamofire-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 688746BDA70A8705D02F243EC5D1C22F /* Alamofire-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BFCAA4B4BD33CB5C396C8121585B3E3C /* SwipeDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E9F7439CA4FA17227A573431EE73C24 /* SwipeDirection.swift */; }; + C0CCAF0F0FCCA68395A8E3285B9EB2C8 /* XLPagerTabStrip.bundle in Resources */ = {isa = PBXBuildFile; fileRef = BD15204CDC32C3C1384C9D149C6D0900 /* XLPagerTabStrip.bundle */; }; + C1EA47EF9B498F4E9C92BD62A28249EF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B535AB9324C02900D60997DE28D2D730 /* UIKit.framework */; }; + C4B4950DCDE41CA8BA2D64DE05234C2A /* PagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94557283D4398624BBB4BE5BADD657C5 /* PagerTabStripViewController.swift */; }; + C8FB3580B6FBF73C82A99C35B5E53840 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */; }; + CBB9F2B42B5927CD6DE5F7AA3E0CAC85 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2D55EE884A7D1AC76E4F140C2357FF2 /* Image.swift */; }; + CBE2D21662DBEDC43071D7C2DC406103 /* ScrollableGraphViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA01BA715C06D5D0B8036CFAC2EAE2FF /* ScrollableGraphViewDataSource.swift */; }; + CEC9BB6496ACA4458CBDAC895780E692 /* TransformType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29E2C0834384B57CF05156B885AB72DD /* TransformType.swift */; }; + CF5DCB055E7C52404F277F98DCDEB28B /* ScrollableGraphView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8386D95E8882037330407E9C532E8679 /* ScrollableGraphView-dummy.m */; }; + D1EBE884C11FF785A91711AF378CAA16 /* MapError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32DA86E93085BE1C4A8583B7F78CD8FD /* MapError.swift */; }; + D331786C87892C26B432086A93BB6634 /* DateTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7277145C96D37B4B216379F1067ADF43 /* DateTransform.swift */; }; + D3FA0AA634AAEA99AB3FABC36BB4958C /* SessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E5B75972D43E1CC87EBB7EE9319581E /* SessionManager.swift */; }; + DF8309B711A4635FD438BF1F8C2D494B /* FromJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27E59DF4567C7C9751A45ABEDC00E42D /* FromJSON.swift */; }; + E1FCC9513457B776C59AED1FD86917F5 /* ScrollableGraphViewDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D3F2435C6DF2E715450D0EDA95A182F /* ScrollableGraphViewDrawingLayer.swift */; }; + E303598CA94725108F75FBC0253E7C0E /* ObjectMapper-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = BA914714473F39073B0A2307CF4A1C74 /* ObjectMapper-dummy.m */; }; + E6711889B27F4D746B9367919BEDC39E /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9E4AAC09932A580A55532EAE683979 /* Filter.swift */; }; + E6DE03E3E1E37473B26BDB3B302A0D2D /* DictionaryTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932A9E9503C227D5E984338512DEE82B /* DictionaryTransform.swift */; }; + E7BB386A78DE89D8CD138D09A0173F8C /* ButtonBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDF3ED71A0731EE9CFFC7B6E9E640C94 /* ButtonBarView.swift */; }; + E95148DBC748BC43DA3F1ACAE3AA5D4D /* ThreadHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFC3965899E4FB0B43D0F41897BAEAC5 /* ThreadHelper.swift */; }; + E9D7DEC99FDBFB0E2E7BC01B388BB7D0 /* BarPlot.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED30501CC6CA178CD9564DE65D63CEE0 /* BarPlot.swift */; }; + E9EEAA672984812FFBF3CBA15826BB6F /* HexColorTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEF96B0960C49D23A1A1C383CDB3EE17 /* HexColorTransform.swift */; }; + EB0DD8CEA1A69867A30267439C970440 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFBD82A77372DCF858E1C0356FC534F /* Result.swift */; }; + EC3217AEA6906A7EC227471D29EE5093 /* Mappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5ABBF189F89C148B98C240840EA6F34B /* Mappable.swift */; }; + EE137952E4142821A09FC27DFBE108F1 /* ScrollableGraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A26AF103240EA161625F296CE997E88 /* ScrollableGraphView.swift */; }; + EE86D619512E9C8FD79CC9F90C173579 /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35685E91008C0C90D24A9114B359E651 /* ImageCache.swift */; }; + F339C07FB4C8DC00884EBD80E38E7FB0 /* ReferenceLines.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A4B2CA663A801F43C2B89A19F97FF4D /* ReferenceLines.swift */; }; + F562EBBB71DFA269B42FD4D8E0BACC35 /* Map.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54E86165286F83A130B89C9F9D8D856A /* Map.swift */; }; + F5B7B673E69BDFB360FA71EEB91B31A7 /* AnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74EE2922114950461F54D42A574E931B /* AnimatedImageView.swift */; }; + F681AACAD4F67208C9C4D934EE911596 /* DotDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28AD2D3D2517B66DC39EF018A8877D2A /* DotDrawingLayer.swift */; }; + F7BF69DBCE70A59684FEC6778DA219A6 /* ImageView+Kingfisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1160B39AE013E090625A8ED69438550 /* ImageView+Kingfisher.swift */; }; + FB2FF2FBF0AE83FF31DE1B6B6D08DF59 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CAD378B9EC75B6EC18048B6A052B131 /* Operators.swift */; }; + FB84E320678BF2FC15BD7DC165E46438 /* GradientDrawingLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25EBF4D4FB8DA84A1893353EB8891D5 /* GradientDrawingLayer.swift */; }; + FD7578F183AA83B2949887C4C1EADF76 /* IntegerOperators.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8DDB34418DB793F10E66F5A6BE6EB7E /* IntegerOperators.swift */; }; + FDD25EFD99DD6732AE1BE5F3F0036505 /* URLTransform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803B12E815A84748016464290D8646C5 /* URLTransform.swift */; }; + FF3E0B16F554EB26CA3185D006FE357A /* Kingfisher-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A211583F182A0B6249248BB91FA3196 /* Kingfisher-dummy.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 5438FAD39C104426A0D9199DB1F44873 /* PBXContainerItemProxy */ = { + 016B2062743B2143F41291F7AFD705C4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4A0A22DC77365EB37D44E9B9E0F3ABD4; - remoteInfo = Kingfisher; + remoteGlobalIDString = 3383968E74B5371B20BB519B170DC7FD; + remoteInfo = Alamofire; }; - 7E48B9BBB9301A913A419E63ED7EE9F5 /* PBXContainerItemProxy */ = { + 1B98A957FC26CEA42F28018C0B0C840C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 743E4A349913BA26BF7AEE81D0D0DC34; remoteInfo = AlamofireObjectMapper; }; - 9F95E621710F4B7EBD56B83C134F6AD5 /* PBXContainerItemProxy */ = { + 2199626C60CA466ABC00BA6842138A5E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; - remoteGlobalIDString = 3383968E74B5371B20BB519B170DC7FD; - remoteInfo = Alamofire; + remoteGlobalIDString = 2AFE7E73274862DFD5D580BF0BA03CE2; + remoteInfo = "XLPagerTabStrip-XLPagerTabStrip"; + }; + 40E92A3CE60424D36E29455A40BF40EE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BC8911E7CB00F6759DE6DE6DC45570D4; + remoteInfo = XLPagerTabStrip; + }; + 78FFFE21F72F86AECBFBF2C33ABD9354 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4A0A22DC77365EB37D44E9B9E0F3ABD4; + remoteInfo = Kingfisher; + }; + 9F060D2E07F4C24B36819659E02C161A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5EDBAC25970E4256AFA87C97F6E6C6E5; + remoteInfo = ScrollableGraphView; }; - B0A0000AACCAE782312410793228CA71 /* PBXContainerItemProxy */ = { + 9F95E621710F4B7EBD56B83C134F6AD5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; remoteGlobalIDString = 3383968E74B5371B20BB519B170DC7FD; remoteInfo = Alamofire; }; - B979B35D2514B358C0175B8BB71C5599 /* PBXContainerItemProxy */ = { + C3BAD0237695BD05AE76DDF201393FDE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; @@ -139,133 +202,208 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 02B0B844C8BB6ACE78934CE1BE235738 /* TaskDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TaskDelegate.swift; path = Source/TaskDelegate.swift; sourceTree = ""; }; - 063ED47B3A6B7EBA7FAA307C9CE26454 /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; - 06B91D8C89C7099D9D9C4689331A840C /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; }; - 081A385E133F9E514152B2B7F39F0A00 /* ISO8601DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISO8601DateTransform.swift; path = Sources/ISO8601DateTransform.swift; sourceTree = ""; }; - 090193265B0CD8D9028273CE12F56A8B /* HexColorTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HexColorTransform.swift; path = Sources/HexColorTransform.swift; sourceTree = ""; }; - 0986D2553648F0746A217E033FB09BD8 /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/ImageModifier.swift; sourceTree = ""; }; + 03EB1BB5410BF3212336C56D489D32A3 /* AlamofireObjectMapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AlamofireObjectMapper-umbrella.h"; sourceTree = ""; }; + 0681AA5487811D0965B4B01D0CD5714F /* Alamofire.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.xcconfig; sourceTree = ""; }; + 071546085B39C5EBDCC89FC3DBACE514 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/KingfisherManager.swift; sourceTree = ""; }; 0B2CDB4FA13BD80A2CBD5F64B735936B /* Pods-GetRestIOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GetRestIOS.debug.xcconfig"; sourceTree = ""; }; - 10B5EB0943660D8666E85F2977E6B301 /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/ImageCache.swift; sourceTree = ""; }; - 139FA5FCB8E6F3B1A372C16D78E0FBF0 /* ThreadHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadHelper.swift; path = Sources/ThreadHelper.swift; sourceTree = ""; }; - 150681E90CBB4FCF4430C430C3D5FC4E /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; - 16D74C25427434557C97CA31CE0023D8 /* TransformOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOperators.swift; path = Sources/TransformOperators.swift; sourceTree = ""; }; - 1B5B72BFED64BB60C4E621C7C60060D7 /* AlamofireObjectMapper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "AlamofireObjectMapper-Info.plist"; sourceTree = ""; }; - 1E5F17FA4415992DFA715D85411DB63C /* AlamofireObjectMapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = AlamofireObjectMapper.modulemap; sourceTree = ""; }; - 1F040ED1FF22031BE793CE58C15BA980 /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; - 21ECC437C69287ECE940E1D07C5F37F0 /* CodableTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CodableTransform.swift; path = Sources/CodableTransform.swift; sourceTree = ""; }; - 2343C987478E4125F9DB74A8E36BE80E /* Kingfisher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.xcconfig; sourceTree = ""; }; - 265ADD9480EBB2BA8B942FF7009CB94C /* AlamofireObjectMapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AlamofireObjectMapper-umbrella.h"; sourceTree = ""; }; - 26F1FD75EC50095D98937FDE65E2F4F1 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/UIButton+Kingfisher.swift"; sourceTree = ""; }; - 312E85EB5EABD6DE0A2BA0DFFD6E7E5B /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; - 32676DA2198AB81AC5B1778F61F5F1CD /* AlamofireObjectMapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "AlamofireObjectMapper-dummy.m"; sourceTree = ""; }; - 337664B936424144E8ADB5996E57CA14 /* ObjectMapper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ObjectMapper-Info.plist"; sourceTree = ""; }; - 3476A7731838FF67CCC062E609615F98 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Indicator.swift; sourceTree = ""; }; - 37A39D51892D67AD7B6F7826C8041033 /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; }; - 39926F7C8239ACC4026E1A40D199E5C3 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; }; - 3D9773CA4B1686C673ED6201A7FBE437 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; }; - 3FD982A938881006D4EDFA5CD6ABDB87 /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/RequestModifier.swift; sourceTree = ""; }; - 4255134418730644F5FA8363F15E2D8F /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 42FE39508FEBD9AB434D294E6E652776 /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Placeholder.swift; sourceTree = ""; }; - 44E660163495097D6C8F07AA0EE5D9DB /* NSDecimalNumberTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NSDecimalNumberTransform.swift; path = Sources/NSDecimalNumberTransform.swift; sourceTree = ""; }; - 44FFD6F1D1857E466CCEE4F199694AB4 /* DateFormatterTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateFormatterTransform.swift; path = Sources/DateFormatterTransform.swift; sourceTree = ""; }; - 484BD670A85D89264544DF134D2FE7D4 /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + 0F37485DB577398A7FDCCE0F8F05162A /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Alamofire.framework; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 16BDA92AAD327B63574B7B1F52F879DA /* TwitterPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TwitterPagerTabStripViewController.swift; path = Sources/TwitterPagerTabStripViewController.swift; sourceTree = ""; }; + 19383E6298DB0C3211FFD100F3092492 /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; + 1A211583F182A0B6249248BB91FA3196 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; + 1A26AF103240EA161625F296CE997E88 /* ScrollableGraphView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScrollableGraphView.swift; path = Classes/ScrollableGraphView.swift; sourceTree = ""; }; + 1B0C39B9A0747D1CBF8F7253CD393D7E /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; + 1B53D94C0B9FE436D110395B0E6AF3ED /* FXPageControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FXPageControl.h; path = Sources/FXPageControl.h; sourceTree = ""; }; + 2257392425B9FC8FE7DC5B8095480985 /* BarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarPagerTabStripViewController.swift; path = Sources/BarPagerTabStripViewController.swift; sourceTree = ""; }; + 245C2F5251A7A866CA3B25D86EBC04AD /* XLPagerTabStrip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "XLPagerTabStrip-Info.plist"; sourceTree = ""; }; + 27368A4248280BB278CD91A4D3062EFC /* TransformOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOf.swift; path = Sources/TransformOf.swift; sourceTree = ""; }; + 279C1541DFB55EF919CDD30EAC4EB85E /* XLPagerTabStrip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "XLPagerTabStrip-dummy.m"; sourceTree = ""; }; + 27E59DF4567C7C9751A45ABEDC00E42D /* FromJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FromJSON.swift; path = Sources/FromJSON.swift; sourceTree = ""; }; + 287EF0A55C55781536CD26441DDCBA03 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/ImageProcessor.swift; sourceTree = ""; }; + 28AD2D3D2517B66DC39EF018A8877D2A /* DotDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DotDrawingLayer.swift; path = Classes/Drawing/DotDrawingLayer.swift; sourceTree = ""; }; + 28EC2FDC1CF0CA23AAC33148B9339D98 /* AlamofireObjectMapper.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = AlamofireObjectMapper.xcconfig; sourceTree = ""; }; + 28F2E4DBF9A55E142D00BE46122AD5FF /* ObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = ObjectMapper.framework; path = ObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 29E2C0834384B57CF05156B885AB72DD /* TransformType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformType.swift; path = Sources/TransformType.swift; sourceTree = ""; }; + 2A7F57C3FE0F83A32AB42C9F50ADE083 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/String+MD5.swift"; sourceTree = ""; }; + 2BA7597337AFFFECAE7431FC975543EB /* ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist"; sourceTree = ""; }; + 2E81290EF70675F31652388CD135E09B /* NSDecimalNumberTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NSDecimalNumberTransform.swift; path = Sources/NSDecimalNumberTransform.swift; sourceTree = ""; }; + 31276D9479F7A8A96A23AFC48D338CAA /* Placeholder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Placeholder.swift; path = Sources/Placeholder.swift; sourceTree = ""; }; + 32DA86E93085BE1C4A8583B7F78CD8FD /* MapError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MapError.swift; path = Sources/MapError.swift; sourceTree = ""; }; + 336205F45C9149396E080557B23946E4 /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; }; + 35685E91008C0C90D24A9114B359E651 /* ImageCache.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCache.swift; path = Sources/ImageCache.swift; sourceTree = ""; }; + 36DB14260A585709B21F8B144D17F5F2 /* XLPagerTabStrip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = XLPagerTabStrip.modulemap; sourceTree = ""; }; + 384692B23E1442E80482478705AC8EF4 /* AlamofireObjectMapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = AlamofireObjectMapper.modulemap; sourceTree = ""; }; + 388606EE6EFA76148FB2D79573DBB3A6 /* LinePlot.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LinePlot.swift; path = Classes/Plots/LinePlot.swift; sourceTree = ""; }; + 39014AD8BA68AEB595685FA742E5564B /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; + 3A959D62A4E9FEF5388D9BFD56339B21 /* Kingfisher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Kingfisher.h; path = Sources/Kingfisher.h; sourceTree = ""; }; + 3BBDAF3AA0D8858E27887AEB968514D2 /* ScrollableGraphView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = ScrollableGraphView.framework; path = ScrollableGraphView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3CAD378B9EC75B6EC18048B6A052B131 /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Sources/Operators.swift; sourceTree = ""; }; + 3E6831ED1EAE2F53B745790C1F8CFE22 /* Alamofire-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Alamofire-dummy.m"; sourceTree = ""; }; + 3E9F7439CA4FA17227A573431EE73C24 /* SwipeDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwipeDirection.swift; path = Sources/SwipeDirection.swift; sourceTree = ""; }; + 40D33A9C9C21FF91DEF00DE74B61F7A6 /* Notifications.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Notifications.swift; path = Source/Notifications.swift; sourceTree = ""; }; + 4514390946338881CF9BE7B0495C0B8A /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/CacheSerializer.swift; sourceTree = ""; }; + 46C9E820A2681B199EACC4823F75E8EB /* ScrollableGraphView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = ScrollableGraphView.modulemap; sourceTree = ""; }; + 478B759C865EE900E018EB4D35DE9CFC /* GraphPointAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphPointAnimation.swift; path = Classes/Plots/Animation/GraphPointAnimation.swift; sourceTree = ""; }; + 47C943CCF0D864EA766432033124C0AB /* Kingfisher-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-prefix.pch"; sourceTree = ""; }; + 482D9F2306210A23ABF322A7C871F20B /* BaseButtonBarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseButtonBarPagerTabStripViewController.swift; path = Sources/BaseButtonBarPagerTabStripViewController.swift; sourceTree = ""; }; + 49708E87077B90FFDD0C2B3436324325 /* Mapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mapper.swift; path = Sources/Mapper.swift; sourceTree = ""; }; 4A959B427D7D79404C61C4E5DAD293FE /* Pods-GetRestIOS-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GetRestIOS-acknowledgements.plist"; sourceTree = ""; }; - 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 513E6D4F332D1EE4C1E8D047DBEBC13C /* AlamofireObjectMapper.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = AlamofireObjectMapper.xcconfig; sourceTree = ""; }; + 4C3A26E62E83C727157AD429CFB1AA81 /* CodableTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CodableTransform.swift; path = Sources/CodableTransform.swift; sourceTree = ""; }; + 4D3F2435C6DF2E715450D0EDA95A182F /* ScrollableGraphViewDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScrollableGraphViewDrawingLayer.swift; path = Classes/Drawing/ScrollableGraphViewDrawingLayer.swift; sourceTree = ""; }; + 5448C36BC45DA3C80A9EAC9EFEF19C27 /* FXPageControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FXPageControl.m; path = Sources/FXPageControl.m; sourceTree = ""; }; + 54E86165286F83A130B89C9F9D8D856A /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = Sources/Map.swift; sourceTree = ""; }; 56D8899538F67365E25B874E436A3636 /* Pods-GetRestIOS-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-GetRestIOS-dummy.m"; sourceTree = ""; }; - 590478C5EBDEFAA438EA754CB1062C72 /* TransformType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformType.swift; path = Sources/TransformType.swift; sourceTree = ""; }; - 5A222F3A3D2549F6C0EBEE7354F7DCDF /* Mappable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mappable.swift; path = Sources/Mappable.swift; sourceTree = ""; }; - 5A45391F54CDF31BBFE4606B3892900C /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/ImageView+Kingfisher.swift"; sourceTree = ""; }; - 5E0C5323C879F05F46A45E8686D67E83 /* Kingfisher-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Kingfisher-dummy.m"; sourceTree = ""; }; - 5E3B48B123104E0BE7BBE19C29E41B5B /* DictionaryTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DictionaryTransform.swift; path = Sources/DictionaryTransform.swift; sourceTree = ""; }; - 5E70E1B3CF33763DC5865855EB67C9E7 /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; - 5F3CC3E812FD37F9869C00A9DB86380E /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; - 608F27D594B4FC0692990626061228AF /* Kingfisher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Kingfisher.framework; path = Kingfisher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 63143E25F0EECF2DBB6282505A59A67B /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/KingfisherOptionsInfo.swift; sourceTree = ""; }; - 63BCB4CFE1F5AFD4424122B257731C95 /* IntegerOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerOperators.swift; path = Sources/IntegerOperators.swift; sourceTree = ""; }; - 65CFE28DA5E9100DF0F00C16E2DC8044 /* DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateTransform.swift; path = Sources/DateTransform.swift; sourceTree = ""; }; - 68FB2636BCF0264F8B2075E77728E7F8 /* EnumTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumTransform.swift; path = Sources/EnumTransform.swift; sourceTree = ""; }; - 6B503ADC91284D0D43D3D0DA06B8D07A /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; - 6F9E1BC587627058C17DFC27655974D3 /* AlamofireObjectMapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AlamofireObjectMapper-prefix.pch"; sourceTree = ""; }; + 58194FC78E57E424CCD6A5499B346874 /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/ImageDownloader.swift; sourceTree = ""; }; + 59BE684F52FD0C1BC4287B5D21366202 /* Response.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Response.swift; path = Source/Response.swift; sourceTree = ""; }; + 5A08C53FC1F7E625C0D6D75B3820971A /* FormatIndicatedCacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FormatIndicatedCacheSerializer.swift; path = Sources/FormatIndicatedCacheSerializer.swift; sourceTree = ""; }; + 5A6E85F2586EA3645783E734878EF4FE /* CustomDateFormatTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CustomDateFormatTransform.swift; path = Sources/CustomDateFormatTransform.swift; sourceTree = ""; }; + 5ABBF189F89C148B98C240840EA6F34B /* Mappable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mappable.swift; path = Sources/Mappable.swift; sourceTree = ""; }; + 5C373132FA716EB448679FD92D213E1A /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 609B52F9224367546F2395C0014AD14A /* Validation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Validation.swift; path = Source/Validation.swift; sourceTree = ""; }; + 60E0C08D9A74A0561B6BEF1DEB62F988 /* EnumOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumOperators.swift; path = Sources/EnumOperators.swift; sourceTree = ""; }; + 63D453B9D697B3E58A4B054AA8B5F925 /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/Kingfisher.swift; sourceTree = ""; }; + 642C623E19BB3031D369D16A70136236 /* ImageModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageModifier.swift; path = Sources/ImageModifier.swift; sourceTree = ""; }; + 681C5140E52BEDE25DAFEFABF4584E3E /* LineDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LineDrawingLayer.swift; path = Classes/Drawing/LineDrawingLayer.swift; sourceTree = ""; }; + 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = XLPagerTabStrip.xcconfig; sourceTree = ""; }; + 688746BDA70A8705D02F243EC5D1C22F /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; + 6A93EAFE31888336421F6D3D22A81982 /* SegmentedPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SegmentedPagerTabStripViewController.swift; path = Sources/SegmentedPagerTabStripViewController.swift; sourceTree = ""; }; + 6B0503EF175F4BEA7A81BE77D2277EB3 /* XLPagerTabStrip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XLPagerTabStrip-umbrella.h"; sourceTree = ""; }; + 6B8DAFEAA10C5233BF36F2B1BF361033 /* ScrollableGraphViewDrawingDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScrollableGraphViewDrawingDelegate.swift; path = Classes/Protocols/ScrollableGraphViewDrawingDelegate.swift; sourceTree = ""; }; + 6BC07248A46CC125113CE2C30CEA3C5F /* KingfisherOptionsInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherOptionsInfo.swift; path = Sources/KingfisherOptionsInfo.swift; sourceTree = ""; }; + 6C888BE4C402E6B5ED7125EA6BA55602 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; }; 7017A9A681D7F3FD97550F06C789B8DF /* Pods-GetRestIOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-GetRestIOS.release.xcconfig"; sourceTree = ""; }; - 725B0129C0F42053232DAE9B80E2D145 /* Kingfisher.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Kingfisher.modulemap; sourceTree = ""; }; - 74344AAA3AB486A0F108AF009AB853D3 /* Alamofire.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Alamofire.xcconfig; sourceTree = ""; }; - 76885D5D3123A4314F1D74F4BE12932E /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/Resource.swift; sourceTree = ""; }; - 788C983A7EF86108DAD81A6DB0890C9F /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; - 7A27C1950E95A41FAAB6EC87AD598D35 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; - 7F9FDB8A1BF8A12399EEEA39767E1E6D /* ImmutableMappable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmutableMappable.swift; path = Sources/ImmutableMappable.swift; sourceTree = ""; }; - 813BE20269FDB8E362958A033991622E /* ObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = ObjectMapper.framework; path = ObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 81A5A4D8C198D0E089F6A67B52A12679 /* String+MD5.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "String+MD5.swift"; path = "Sources/String+MD5.swift"; sourceTree = ""; }; - 8428186A0EBD623DC176DCE57C95E473 /* Mapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Mapper.swift; path = Sources/Mapper.swift; sourceTree = ""; }; - 859C45B7E06016B33C01650FE8E7F918 /* Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Alamofire.swift; path = Source/Alamofire.swift; sourceTree = ""; }; + 71D787740C8D6B17DF369ED0179C372E /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/ImagePrefetcher.swift; sourceTree = ""; }; + 7277145C96D37B4B216379F1067ADF43 /* DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateTransform.swift; path = Sources/DateTransform.swift; sourceTree = ""; }; + 74EE2922114950461F54D42A574E931B /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/AnimatedImageView.swift; sourceTree = ""; }; + 758471292657321B219103490AE38DA7 /* UIButton+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UIButton+Kingfisher.swift"; path = "Sources/UIButton+Kingfisher.swift"; sourceTree = ""; }; + 79DB06FCF2E92865E9B6785B1C8D7C80 /* Kingfisher-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Kingfisher-Info.plist"; sourceTree = ""; }; + 7A272D6646A72A83DFE3AA54F3D9D310 /* ISO8601DateTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ISO8601DateTransform.swift; path = Sources/ISO8601DateTransform.swift; sourceTree = ""; }; + 7CC462D9015BB835C023A24E055E04E0 /* XLPagerTabStrip-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XLPagerTabStrip-prefix.pch"; sourceTree = ""; }; + 7D2698E77FA9001529C2BE746B535CB1 /* PagerTabStripBehaviour.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripBehaviour.swift; path = Sources/PagerTabStripBehaviour.swift; sourceTree = ""; }; + 7E5B75972D43E1CC87EBB7EE9319581E /* SessionManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionManager.swift; path = Source/SessionManager.swift; sourceTree = ""; }; + 7EC5A0DE9E55BE79437FB5CA0791E6AE /* DateFormatterTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DateFormatterTransform.swift; path = Sources/DateFormatterTransform.swift; sourceTree = ""; }; + 7F75C87B819B9CE315BBF458692D7D6D /* Alamofire-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-prefix.pch"; sourceTree = ""; }; + 803B12E815A84748016464290D8646C5 /* URLTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLTransform.swift; path = Sources/URLTransform.swift; sourceTree = ""; }; + 8386D95E8882037330407E9C532E8679 /* ScrollableGraphView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ScrollableGraphView-dummy.m"; sourceTree = ""; }; + 8A1E27C84AE0F02149E1E7AF0B45DA02 /* LabelPool.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LabelPool.swift; path = Classes/Reference/LabelPool.swift; sourceTree = ""; }; 8A2B8577E4582C1D0832A4FDF06777BD /* Pods-GetRestIOS-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-GetRestIOS-Info.plist"; sourceTree = ""; }; - 8CCA6AECAF1F1FFC3C7009ACD667485B /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; }; - 8E4E5671C167BED48AC7BF9D60EA7EFC /* Request.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Request.swift; path = Source/Request.swift; sourceTree = ""; }; - 95BB966369055580593063ECFCD67DB0 /* EnumOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumOperators.swift; path = Sources/EnumOperators.swift; sourceTree = ""; }; - 96B8FF044E8D6809DBC4028646847C09 /* ParameterEncoding.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ParameterEncoding.swift; path = Source/ParameterEncoding.swift; sourceTree = ""; }; + 8AFBD82A77372DCF858E1C0356FC534F /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Source/Result.swift; sourceTree = ""; }; + 9288720FC3981ED4F9C176F0E7BDAC97 /* ObjectMapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-prefix.pch"; sourceTree = ""; }; + 932A9E9503C227D5E984338512DEE82B /* DictionaryTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DictionaryTransform.swift; path = Sources/DictionaryTransform.swift; sourceTree = ""; }; + 94557283D4398624BBB4BE5BADD657C5 /* PagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripViewController.swift; path = Sources/PagerTabStripViewController.swift; sourceTree = ""; }; + 9A4B2CA663A801F43C2B89A19F97FF4D /* ReferenceLines.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReferenceLines.swift; path = Classes/Reference/ReferenceLines.swift; sourceTree = ""; }; + 9CCF99BC62103EB3B3ED4AF859924FF4 /* BarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarView.swift; path = Sources/BarView.swift; sourceTree = ""; }; + 9D39AD829465084732ACF97222EBCD61 /* AlamofireObjectMapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AlamofireObjectMapper-prefix.pch"; sourceTree = ""; }; + 9D5EE3A418086BD6CBB44A6349B7B71E /* PagerTabStripError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripError.swift; path = Sources/PagerTabStripError.swift; sourceTree = ""; }; 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 9E384806E109B4030E4D837E95D5B81B /* Alamofire.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Alamofire.framework; path = Alamofire.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 9EA0A029FEC1907605E9D863C545E9A0 /* ToJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToJSON.swift; path = Sources/ToJSON.swift; sourceTree = ""; }; - A33FAB021477544550E0484538F39D04 /* ImagePrefetcher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImagePrefetcher.swift; path = Sources/ImagePrefetcher.swift; sourceTree = ""; }; - A5DCF64CA13205E73715D1AF348AA994 /* ObjectMapper-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-prefix.pch"; sourceTree = ""; }; - A64AA90C724E10B7A4AE18CB07F84BEF /* AlamofireObjectMapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireObjectMapper.swift; path = AlamofireObjectMapper/AlamofireObjectMapper.swift; sourceTree = ""; }; - A9B278F635359E6D2AA75C3095CC4A57 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; }; - AB8C946D49463345DE68F51C4F05D13B /* MapError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MapError.swift; path = Sources/MapError.swift; sourceTree = ""; }; - AC265EDC639233AB0FCA13E30A54E6E2 /* ServerTrustPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustPolicy.swift; path = Source/ServerTrustPolicy.swift; sourceTree = ""; }; + 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 9DCEAD5244CC26F1CA5DC0A1372ACD59 /* AlamofireObjectMapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "AlamofireObjectMapper-dummy.m"; sourceTree = ""; }; + 9F9E4AAC09932A580A55532EAE683979 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Filter.swift; sourceTree = ""; }; + A2903B37D2E0C3DC4C1BD68031F8BAA3 /* ButtonCell.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = ButtonCell.xib; path = Sources/ButtonCell.xib; sourceTree = ""; }; + A2D55EE884A7D1AC76E4F140C2357FF2 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image.swift; sourceTree = ""; }; + A32FB55E210472F93462990D6CD22898 /* ObjectMapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = ObjectMapper.modulemap; sourceTree = ""; }; + A5FAA5238EE2370609D01B43A4AF65DD /* TransformOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOperators.swift; path = Sources/TransformOperators.swift; sourceTree = ""; }; + A8EE119C76C786A623216BDE69E20A62 /* BarDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarDrawingLayer.swift; path = Classes/Drawing/BarDrawingLayer.swift; sourceTree = ""; }; + AB21AF578F5EF0E2AA714BE7A6A3F783 /* DotPlot.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DotPlot.swift; path = Classes/Plots/DotPlot.swift; sourceTree = ""; }; + AC2721B68FAD211CC3D6249E5D5750C1 /* ObjectMapper.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ObjectMapper.xcconfig; sourceTree = ""; }; + AC2AA462C4057CF70747E961D929900F /* ServerTrustPolicy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ServerTrustPolicy.swift; path = Source/ServerTrustPolicy.swift; sourceTree = ""; }; + AC3D44D7803A27A489426E10F4FDB427 /* ScrollableGraphView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ScrollableGraphView-umbrella.h"; sourceTree = ""; }; ADBC01608398EB43A55B8971A0E67A97 /* Pods-GetRestIOS.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-GetRestIOS.modulemap"; sourceTree = ""; }; - AEC43837BB965A8CCDAAF75C72A1F533 /* Operators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Operators.swift; path = Sources/Operators.swift; sourceTree = ""; }; - AF759A7875241995843338214EBEAE93 /* Alamofire-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Alamofire-umbrella.h"; sourceTree = ""; }; - AF8E0B7D165C4ABFECCDA1E3CF311A99 /* KingfisherManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KingfisherManager.swift; path = Sources/KingfisherManager.swift; sourceTree = ""; }; - B1BE85A224ACF4ED7D542F0DEAACC9D9 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; - B974C5C308E0C2A5EB9BE13E11CC1852 /* AlamofireObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = AlamofireObjectMapper.framework; path = AlamofireObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - BBBE04A0D479CB656A3B95014C27A21E /* ResponseSerialization.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ResponseSerialization.swift; path = Source/ResponseSerialization.swift; sourceTree = ""; }; - BC062D6C5AB671F83AD33C941FD3DEC8 /* TransformOf.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransformOf.swift; path = Sources/TransformOf.swift; sourceTree = ""; }; - BD6A71BD6370D469BBB9C90975B2628D /* URLTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = URLTransform.swift; path = Sources/URLTransform.swift; sourceTree = ""; }; - C5888FB7491CE4BB850BFB065358EB28 /* ObjectMapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ObjectMapper-dummy.m"; sourceTree = ""; }; - C5C4F316CF414D6E615CFFD150F4C7BD /* Map.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Map.swift; path = Sources/Map.swift; sourceTree = ""; }; - C7C63F137ADA1291A83D42F8B26692FF /* FromJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FromJSON.swift; path = Sources/FromJSON.swift; sourceTree = ""; }; - C85BE459F8C97CC387CDA34555579DB0 /* ImageProcessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageProcessor.swift; path = Sources/ImageProcessor.swift; sourceTree = ""; }; - D2B73420B939F155CE0DACD44FEAFCD5 /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Box.swift; sourceTree = ""; }; - D41D72942B51E7E4D598F5F509EB9778 /* CustomDateFormatTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CustomDateFormatTransform.swift; path = Sources/CustomDateFormatTransform.swift; sourceTree = ""; }; - D4BE99B771521C0D185E9D417F06D5D6 /* Image.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Image.swift; path = Sources/Image.swift; sourceTree = ""; }; - D9908EC83A140886F26FEC8422443D95 /* AnimatedImageView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AnimatedImageView.swift; path = Sources/AnimatedImageView.swift; sourceTree = ""; }; + AFC3965899E4FB0B43D0F41897BAEAC5 /* ThreadHelper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ThreadHelper.swift; path = Sources/ThreadHelper.swift; sourceTree = ""; }; + B02E60A2228663BA06071EC4C9CBF9B1 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; + B037CDD9E373F3B31AC3FE61516DB148 /* ScrollableGraphView-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ScrollableGraphView-Info.plist"; sourceTree = ""; }; + B21C86A5C4255093D77A2862F46BAB9B /* Kingfisher.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Kingfisher.framework; path = Kingfisher.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B463F2B96CD19C438F374BCC02C4F997 /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/ImageTransition.swift; sourceTree = ""; }; + B535AB9324C02900D60997DE28D2D730 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + B55E27F1214B30F1DF77D84188B9C775 /* SessionDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionDelegate.swift; path = Source/SessionDelegate.swift; sourceTree = ""; }; + B9BD77FCA32EF5F89D62A86DA2F776BC /* Alamofire-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Alamofire-Info.plist"; sourceTree = ""; }; + BA914714473F39073B0A2307CF4A1C74 /* ObjectMapper-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ObjectMapper-dummy.m"; sourceTree = ""; }; + BD15204CDC32C3C1384C9D149C6D0900 /* XLPagerTabStrip.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = XLPagerTabStrip.bundle; path = "XLPagerTabStrip-XLPagerTabStrip.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; + BD15D7F477CC17474FA3E412A01AF1F8 /* ScrollableGraphView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ScrollableGraphView.xcconfig; sourceTree = ""; }; + BD8AA3FE5AA67B9768E8D23A3C6CDE62 /* AlamofireObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = AlamofireObjectMapper.framework; path = AlamofireObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BDC6616722FED557AAE794DE2C8C7365 /* Alamofire.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = Alamofire.modulemap; sourceTree = ""; }; + C015B603DAF4B79DE58EF72EA32EFB8F /* ToJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToJSON.swift; path = Sources/ToJSON.swift; sourceTree = ""; }; + C0C17725F6B1B0D98A634B5B391B504F /* RequestModifier.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RequestModifier.swift; path = Sources/RequestModifier.swift; sourceTree = ""; }; + C1631ECBA1E8484DCCC5266D4E5F05D1 /* ObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C25EBF4D4FB8DA84A1893353EB8891D5 /* GradientDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GradientDrawingLayer.swift; path = Classes/Drawing/GradientDrawingLayer.swift; sourceTree = ""; }; + C27973BB051B91C449BF29951175E3B5 /* ButtonBarViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarViewCell.swift; path = Sources/ButtonBarViewCell.swift; sourceTree = ""; }; + C5B756AE75D1D19E8CE7F5DDF30459F9 /* ScrollableGraphView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ScrollableGraphView-prefix.pch"; sourceTree = ""; }; + C6E9FE7124AF14AAA4EA28B0910B370F /* XLPagerTabStrip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = XLPagerTabStrip.framework; path = XLPagerTabStrip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C94434B63792DE8A06167CA73672F4E8 /* ObjectMapper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ObjectMapper-Info.plist"; sourceTree = ""; }; + CA01BA715C06D5D0B8036CFAC2EAE2FF /* ScrollableGraphViewDataSource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScrollableGraphViewDataSource.swift; path = Classes/Protocols/ScrollableGraphViewDataSource.swift; sourceTree = ""; }; + CB3A743CD02031166893E78E41F287ED /* AFError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AFError.swift; path = Source/AFError.swift; sourceTree = ""; }; + CCAE054B0D98D013C8306CF8F2D8C460 /* FillDrawingLayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FillDrawingLayer.swift; path = Classes/Drawing/FillDrawingLayer.swift; sourceTree = ""; }; + CE6BE12C2C3E7BCBBA238959F7E2D64C /* Timeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeline.swift; path = Source/Timeline.swift; sourceTree = ""; }; + CEF96B0960C49D23A1A1C383CDB3EE17 /* HexColorTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HexColorTransform.swift; path = Sources/HexColorTransform.swift; sourceTree = ""; }; + D1160B39AE013E090625A8ED69438550 /* ImageView+Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ImageView+Kingfisher.swift"; path = "Sources/ImageView+Kingfisher.swift"; sourceTree = ""; }; + D186D786A94E470E1857506D33C478D4 /* GraphPoint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = GraphPoint.swift; path = Classes/Plots/Animation/GraphPoint.swift; sourceTree = ""; }; + D2F6B7C83F1CD39BE7D26BF10F196C29 /* MultipartFormData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MultipartFormData.swift; path = Source/MultipartFormData.swift; sourceTree = ""; }; + D4723F3CDBFBA8FA855765FD42332A7D /* Pods_GetRestIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_GetRestIOS.framework; path = "Pods-GetRestIOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + D89A00EB509B55B6C47435C586DCCA18 /* ObjectMapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-umbrella.h"; sourceTree = ""; }; DA35C53B1C60D2802568FED8C4A8D52D /* Pods-GetRestIOS-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-GetRestIOS-frameworks.sh"; sourceTree = ""; }; - DFA7F04056A57C86FDFFB4BEBD71D7E3 /* Timeline.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Timeline.swift; path = Source/Timeline.swift; sourceTree = ""; }; - E0274FBA440263A9D15DCCC6F51D75F0 /* ObjectMapper.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = ObjectMapper.xcconfig; sourceTree = ""; }; - E10F440BDB5FBEB291BF6199D2DF367A /* ObjectMapper.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = ObjectMapper.modulemap; sourceTree = ""; }; - E1A661CAF0D7CED3DDCDCB26FE178492 /* DataTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataTransform.swift; path = Sources/DataTransform.swift; sourceTree = ""; }; - E6E0D38D19A85ECDA8664D49E35AEBFC /* SessionManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SessionManager.swift; path = Source/SessionManager.swift; sourceTree = ""; }; - E77EE86EDC2A7914429626F2467AE2FB /* Kingfisher.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Kingfisher.swift; path = Sources/Kingfisher.swift; sourceTree = ""; }; - EA74144E6C71B4D56311916DCF6B23F3 /* CacheSerializer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CacheSerializer.swift; path = Sources/CacheSerializer.swift; sourceTree = ""; }; - EEC54DA472B6D8E9FBE06C027C3468E0 /* Kingfisher-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Kingfisher-umbrella.h"; sourceTree = ""; }; - EEE46D64CBCC85526D9A6FC8A3847ACB /* ObjectMapper.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ObjectMapper.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DC69BB97A9D32BEE90E92E203F897EAE /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12.2.sdk/System/Library/Frameworks/CFNetwork.framework; sourceTree = DEVELOPER_DIR; }; + DF7298AE840E47712DEA79230FAE7694 /* DispatchQueue+Alamofire.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "DispatchQueue+Alamofire.swift"; path = "Source/DispatchQueue+Alamofire.swift"; sourceTree = ""; }; + E03008CEE402D6F6AE453E119D6475C0 /* EnumTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EnumTransform.swift; path = Sources/EnumTransform.swift; sourceTree = ""; }; + E0E66A30373F212DBE1B636648395C03 /* DataTransform.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataTransform.swift; path = Sources/DataTransform.swift; sourceTree = ""; }; + E0F7CBAC4B35DC776B09272F91613DE8 /* Plot.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Plot.swift; path = Classes/Plots/Plot.swift; sourceTree = ""; }; + E1FE093FAAB7C44666B5A8D775B2BE67 /* IndicatorInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IndicatorInfo.swift; path = Sources/IndicatorInfo.swift; sourceTree = ""; }; + E68E54859490ED3EDE52295924D0967C /* AlamofireObjectMapper.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AlamofireObjectMapper.swift; path = AlamofireObjectMapper/AlamofireObjectMapper.swift; sourceTree = ""; }; + E795872C69C8D8410973E82FBDD6DAA3 /* NetworkReachabilityManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NetworkReachabilityManager.swift; path = Source/NetworkReachabilityManager.swift; sourceTree = ""; }; + E8DDB34418DB793F10E66F5A6BE6EB7E /* IntegerOperators.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IntegerOperators.swift; path = Sources/IntegerOperators.swift; sourceTree = ""; }; + E9A712BEA8EEE22DEF0C1E2394AB5188 /* Resource.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Resource.swift; path = Sources/Resource.swift; sourceTree = ""; }; + EC8BB4FD4527268EC4A39FAF8B79532A /* Kingfisher.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Kingfisher.xcconfig; sourceTree = ""; }; + ED30501CC6CA178CD9564DE65D63CEE0 /* BarPlot.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarPlot.swift; path = Classes/Plots/BarPlot.swift; sourceTree = ""; }; + EDF3ED71A0731EE9CFFC7B6E9E640C94 /* ButtonBarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarView.swift; path = Sources/ButtonBarView.swift; sourceTree = ""; }; EF35C02E663D07829AE36222CA625417 /* Pods-GetRestIOS-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-GetRestIOS-umbrella.h"; sourceTree = ""; }; - EF6624042A7DEEF20CB03340E756F4F0 /* Result.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Result.swift; path = Source/Result.swift; sourceTree = ""; }; - F15BCF2644E13B6E0E4CC8A7DF462122 /* Filter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Filter.swift; path = Sources/Filter.swift; sourceTree = ""; }; - F44C518042B4A53AF8527CB85E8B373E /* ImageDownloader.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageDownloader.swift; path = Sources/ImageDownloader.swift; sourceTree = ""; }; + F0EF37CC7FB45F50A748D753BD4FEF02 /* ButtonBarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarPagerTabStripViewController.swift; path = Sources/ButtonBarPagerTabStripViewController.swift; sourceTree = ""; }; + F42FCFB86E5633C4BF258CADEF4A792B /* ImmutableMappable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImmutableMappable.swift; path = Sources/ImmutableMappable.swift; sourceTree = ""; }; + F477600F9218288C098618175DC7F622 /* TaskDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TaskDelegate.swift; path = Source/TaskDelegate.swift; sourceTree = ""; }; F5B0A768A46180BA751EC3E4F7D199CE /* Pods-GetRestIOS-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-GetRestIOS-acknowledgements.markdown"; sourceTree = ""; }; - F62AEB5A7D0463195B6DE26564927E6A /* Pods_GetRestIOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_GetRestIOS.framework; path = "Pods-GetRestIOS.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; - F9770B58667C7130802B59828F60356F /* ImageTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageTransition.swift; path = Sources/ImageTransition.swift; sourceTree = ""; }; - FD5E3ED772B559F275F7AAA6D57D777F /* ObjectMapper-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ObjectMapper-umbrella.h"; sourceTree = ""; }; + F8B1B71428493C07C5CFB396270D3A64 /* ReferenceLineDrawingView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ReferenceLineDrawingView.swift; path = Classes/Drawing/ReferenceLineDrawingView.swift; sourceTree = ""; }; + F8DA6FD51672F9002E1076D7AA96625E /* Box.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Box.swift; path = Sources/Box.swift; sourceTree = ""; }; + FA0355AB3BC139259660241D81207E46 /* Indicator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Indicator.swift; path = Sources/Indicator.swift; sourceTree = ""; }; + FD8811A91F8CD0D34F4A54EB9AC4B328 /* AlamofireObjectMapper-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "AlamofireObjectMapper-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 2DE5D5012496E0ECD9EFE637BD212BF1 /* Frameworks */ = { + 45ED8B159A97749309D4BE4C9C29C665 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 059603888075C317971A67A7C0FB2BDF /* Alamofire.framework in Frameworks */, + 0DA85BF427253C535FE9342734550328 /* Foundation.framework in Frameworks */, + 33E1D1AABC1408623B60017EB8DA0A88 /* ObjectMapper.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5972F23ED21812D1422AC71C934A6979 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FA6272678233EBE00A54CBF3E92E4E92 /* Foundation.framework in Frameworks */, + C8FB3580B6FBF73C82A99C35B5E53840 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 45ED8B159A97749309D4BE4C9C29C665 /* Frameworks */ = { + 5A81103CEFC1A3F5FF22BD544B640EEB /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 059603888075C317971A67A7C0FB2BDF /* Alamofire.framework in Frameworks */, - 0DA85BF427253C535FE9342734550328 /* Foundation.framework in Frameworks */, - 33E1D1AABC1408623B60017EB8DA0A88 /* ObjectMapper.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8035A55A140FCC40B751668FF7DCD1CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 291C8ED59FCD3874D694E4BB67B3039B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8CAA4CAA81A34D92ECEBBFF8C11E1599 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D761F9B1CD980D1E1B0441D05E8FD09 /* Foundation.framework in Frameworks */, + C1EA47EF9B498F4E9C92BD62A28249EF /* UIKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -297,27 +435,54 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 131E2AC9AC9A470326E7E8B1D9C6AB15 /* Support Files */ = { + 03E92848BCA2089EC4E2901F3BCE54CE /* Support Files */ = { isa = PBXGroup; children = ( - 725B0129C0F42053232DAE9B80E2D145 /* Kingfisher.modulemap */, - 2343C987478E4125F9DB74A8E36BE80E /* Kingfisher.xcconfig */, - 5E0C5323C879F05F46A45E8686D67E83 /* Kingfisher-dummy.m */, - 5F3CC3E812FD37F9869C00A9DB86380E /* Kingfisher-Info.plist */, - 312E85EB5EABD6DE0A2BA0DFFD6E7E5B /* Kingfisher-prefix.pch */, - EEC54DA472B6D8E9FBE06C027C3468E0 /* Kingfisher-umbrella.h */, + A32FB55E210472F93462990D6CD22898 /* ObjectMapper.modulemap */, + AC2721B68FAD211CC3D6249E5D5750C1 /* ObjectMapper.xcconfig */, + BA914714473F39073B0A2307CF4A1C74 /* ObjectMapper-dummy.m */, + C94434B63792DE8A06167CA73672F4E8 /* ObjectMapper-Info.plist */, + 9288720FC3981ED4F9C176F0E7BDAC97 /* ObjectMapper-prefix.pch */, + D89A00EB509B55B6C47435C586DCCA18 /* ObjectMapper-umbrella.h */, ); name = "Support Files"; - path = "../Target Support Files/Kingfisher"; + path = "../Target Support Files/ObjectMapper"; sourceTree = ""; }; - 2528070EDF6A93CCECBEF2E82FA06E89 /* iOS */ = { + 0A9280645A8D49562038882F04B40922 /* Frameworks */ = { isa = PBXGroup; children = ( - 7A27C1950E95A41FAAB6EC87AD598D35 /* CFNetwork.framework */, - 4BAB0D06C6224EA1E329A97B5F41106A /* Foundation.framework */, + 5C373132FA716EB448679FD92D213E1A /* Alamofire.framework */, + C1631ECBA1E8484DCCC5266D4E5F05D1 /* ObjectMapper.framework */, + D9BEC53E8994EC082758024A845F54C3 /* iOS */, ); - name = iOS; + name = Frameworks; + sourceTree = ""; + }; + 0AD2A016324563D03CB98D25D328FE3F /* Alamofire */ = { + isa = PBXGroup; + children = ( + CB3A743CD02031166893E78E41F287ED /* AFError.swift */, + 19383E6298DB0C3211FFD100F3092492 /* Alamofire.swift */, + DF7298AE840E47712DEA79230FAE7694 /* DispatchQueue+Alamofire.swift */, + D2F6B7C83F1CD39BE7D26BF10F196C29 /* MultipartFormData.swift */, + E795872C69C8D8410973E82FBDD6DAA3 /* NetworkReachabilityManager.swift */, + 40D33A9C9C21FF91DEF00DE74B61F7A6 /* Notifications.swift */, + 6C888BE4C402E6B5ED7125EA6BA55602 /* ParameterEncoding.swift */, + 1B0C39B9A0747D1CBF8F7253CD393D7E /* Request.swift */, + 59BE684F52FD0C1BC4287B5D21366202 /* Response.swift */, + 336205F45C9149396E080557B23946E4 /* ResponseSerialization.swift */, + 8AFBD82A77372DCF858E1C0356FC534F /* Result.swift */, + AC2AA462C4057CF70747E961D929900F /* ServerTrustPolicy.swift */, + B55E27F1214B30F1DF77D84188B9C775 /* SessionDelegate.swift */, + 7E5B75972D43E1CC87EBB7EE9319581E /* SessionManager.swift */, + F477600F9218288C098618175DC7F622 /* TaskDelegate.swift */, + CE6BE12C2C3E7BCBBA238959F7E2D64C /* Timeline.swift */, + 609B52F9224367546F2395C0014AD14A /* Validation.swift */, + 55B5DAD6DD79F201FE48E7D8DE57B3D1 /* Support Files */, + ); + name = Alamofire; + path = Alamofire; sourceTree = ""; }; 2B536F91FF569A5BD6440B88DB8C40FF /* Pods-GetRestIOS */ = { @@ -337,42 +502,37 @@ path = "Target Support Files/Pods-GetRestIOS"; sourceTree = ""; }; - 2BB5A19B32F72B0217C3FFEF6A5FFC1E /* Alamofire */ = { + 3156CC8D860E030BEC3FEE3F4A5F5B54 /* Support Files */ = { isa = PBXGroup; children = ( - 8CCA6AECAF1F1FFC3C7009ACD667485B /* AFError.swift */, - 859C45B7E06016B33C01650FE8E7F918 /* Alamofire.swift */, - 6B503ADC91284D0D43D3D0DA06B8D07A /* DispatchQueue+Alamofire.swift */, - A9B278F635359E6D2AA75C3095CC4A57 /* MultipartFormData.swift */, - 37A39D51892D67AD7B6F7826C8041033 /* NetworkReachabilityManager.swift */, - 39926F7C8239ACC4026E1A40D199E5C3 /* Notifications.swift */, - 96B8FF044E8D6809DBC4028646847C09 /* ParameterEncoding.swift */, - 8E4E5671C167BED48AC7BF9D60EA7EFC /* Request.swift */, - 3D9773CA4B1686C673ED6201A7FBE437 /* Response.swift */, - BBBE04A0D479CB656A3B95014C27A21E /* ResponseSerialization.swift */, - EF6624042A7DEEF20CB03340E756F4F0 /* Result.swift */, - AC265EDC639233AB0FCA13E30A54E6E2 /* ServerTrustPolicy.swift */, - B1BE85A224ACF4ED7D542F0DEAACC9D9 /* SessionDelegate.swift */, - E6E0D38D19A85ECDA8664D49E35AEBFC /* SessionManager.swift */, - 02B0B844C8BB6ACE78934CE1BE235738 /* TaskDelegate.swift */, - DFA7F04056A57C86FDFFB4BEBD71D7E3 /* Timeline.swift */, - 063ED47B3A6B7EBA7FAA307C9CE26454 /* Validation.swift */, - 7865D78D6B992CFD375CF43C356A80CF /* Support Files */, + 2BA7597337AFFFECAE7431FC975543EB /* ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist */, + 36DB14260A585709B21F8B144D17F5F2 /* XLPagerTabStrip.modulemap */, + 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */, + 279C1541DFB55EF919CDD30EAC4EB85E /* XLPagerTabStrip-dummy.m */, + 245C2F5251A7A866CA3B25D86EBC04AD /* XLPagerTabStrip-Info.plist */, + 7CC462D9015BB835C023A24E055E04E0 /* XLPagerTabStrip-prefix.pch */, + 6B0503EF175F4BEA7A81BE77D2277EB3 /* XLPagerTabStrip-umbrella.h */, ); - name = Alamofire; - path = Alamofire; + name = "Support Files"; + path = "../Target Support Files/XLPagerTabStrip"; sourceTree = ""; }; - 2E423AA63AA1EC2281C71B98C3A75E5B /* Products */ = { + 38267FD3602C84616229C1F47F532779 /* Resources */ = { isa = PBXGroup; children = ( - 9E384806E109B4030E4D837E95D5B81B /* Alamofire.framework */, - B974C5C308E0C2A5EB9BE13E11CC1852 /* AlamofireObjectMapper.framework */, - 608F27D594B4FC0692990626061228AF /* Kingfisher.framework */, - 813BE20269FDB8E362958A033991622E /* ObjectMapper.framework */, - F62AEB5A7D0463195B6DE26564927E6A /* Pods_GetRestIOS.framework */, + A2903B37D2E0C3DC4C1BD68031F8BAA3 /* ButtonCell.xib */, ); - name = Products; + name = Resources; + sourceTree = ""; + }; + 39F502C86B6EB22BD1B7DE46FEDCFD6E /* AlamofireObjectMapper */ = { + isa = PBXGroup; + children = ( + E68E54859490ED3EDE52295924D0967C /* AlamofireObjectMapper.swift */, + A6855313795432FADD93AEAD95D4A9DA /* Support Files */, + ); + name = AlamofireObjectMapper; + path = AlamofireObjectMapper; sourceTree = ""; }; 3D5C68A8C0201CFBF1679597F74EC727 /* Targets Support Files */ = { @@ -383,154 +543,227 @@ name = "Targets Support Files"; sourceTree = ""; }; - 533BDBF263F1B25A14117744DBA49B22 /* Support Files */ = { + 3FB990D09288CA9C240D475A4B2D43E4 /* Support Files */ = { isa = PBXGroup; children = ( - E10F440BDB5FBEB291BF6199D2DF367A /* ObjectMapper.modulemap */, - E0274FBA440263A9D15DCCC6F51D75F0 /* ObjectMapper.xcconfig */, - C5888FB7491CE4BB850BFB065358EB28 /* ObjectMapper-dummy.m */, - 337664B936424144E8ADB5996E57CA14 /* ObjectMapper-Info.plist */, - A5DCF64CA13205E73715D1AF348AA994 /* ObjectMapper-prefix.pch */, - FD5E3ED772B559F275F7AAA6D57D777F /* ObjectMapper-umbrella.h */, + 46C9E820A2681B199EACC4823F75E8EB /* ScrollableGraphView.modulemap */, + BD15D7F477CC17474FA3E412A01AF1F8 /* ScrollableGraphView.xcconfig */, + 8386D95E8882037330407E9C532E8679 /* ScrollableGraphView-dummy.m */, + B037CDD9E373F3B31AC3FE61516DB148 /* ScrollableGraphView-Info.plist */, + C5B756AE75D1D19E8CE7F5DDF30459F9 /* ScrollableGraphView-prefix.pch */, + AC3D44D7803A27A489426E10F4FDB427 /* ScrollableGraphView-umbrella.h */, ); name = "Support Files"; - path = "../Target Support Files/ObjectMapper"; + path = "../Target Support Files/ScrollableGraphView"; sourceTree = ""; }; - 5D64215721863C0357CEA7D394B11611 /* ObjectMapper */ = { + 409CD76EB56818E48EF9A3F0AA0E2714 /* Pods */ = { isa = PBXGroup; children = ( - 21ECC437C69287ECE940E1D07C5F37F0 /* CodableTransform.swift */, - D41D72942B51E7E4D598F5F509EB9778 /* CustomDateFormatTransform.swift */, - E1A661CAF0D7CED3DDCDCB26FE178492 /* DataTransform.swift */, - 44FFD6F1D1857E466CCEE4F199694AB4 /* DateFormatterTransform.swift */, - 65CFE28DA5E9100DF0F00C16E2DC8044 /* DateTransform.swift */, - 5E3B48B123104E0BE7BBE19C29E41B5B /* DictionaryTransform.swift */, - 95BB966369055580593063ECFCD67DB0 /* EnumOperators.swift */, - 68FB2636BCF0264F8B2075E77728E7F8 /* EnumTransform.swift */, - C7C63F137ADA1291A83D42F8B26692FF /* FromJSON.swift */, - 090193265B0CD8D9028273CE12F56A8B /* HexColorTransform.swift */, - 7F9FDB8A1BF8A12399EEEA39767E1E6D /* ImmutableMappable.swift */, - 63BCB4CFE1F5AFD4424122B257731C95 /* IntegerOperators.swift */, - 081A385E133F9E514152B2B7F39F0A00 /* ISO8601DateTransform.swift */, - C5C4F316CF414D6E615CFFD150F4C7BD /* Map.swift */, - AB8C946D49463345DE68F51C4F05D13B /* MapError.swift */, - 5A222F3A3D2549F6C0EBEE7354F7DCDF /* Mappable.swift */, - 8428186A0EBD623DC176DCE57C95E473 /* Mapper.swift */, - 44E660163495097D6C8F07AA0EE5D9DB /* NSDecimalNumberTransform.swift */, - AEC43837BB965A8CCDAAF75C72A1F533 /* Operators.swift */, - 9EA0A029FEC1907605E9D863C545E9A0 /* ToJSON.swift */, - BC062D6C5AB671F83AD33C941FD3DEC8 /* TransformOf.swift */, - 16D74C25427434557C97CA31CE0023D8 /* TransformOperators.swift */, - 590478C5EBDEFAA438EA754CB1062C72 /* TransformType.swift */, - BD6A71BD6370D469BBB9C90975B2628D /* URLTransform.swift */, - 533BDBF263F1B25A14117744DBA49B22 /* Support Files */, + 0AD2A016324563D03CB98D25D328FE3F /* Alamofire */, + 39F502C86B6EB22BD1B7DE46FEDCFD6E /* AlamofireObjectMapper */, + AFA1DBAAB98DE5D57B4B70E4D842F9DE /* Kingfisher */, + A7201D46125484DDD0BEA7FFCF0541C0 /* ObjectMapper */, + E9698890C750DAA3FB6F962C09591465 /* ScrollableGraphView */, + 9648317CD0E2366A8C94850B51FF77C5 /* XLPagerTabStrip */, ); - name = ObjectMapper; - path = ObjectMapper; + name = Pods; sourceTree = ""; }; - 7865D78D6B992CFD375CF43C356A80CF /* Support Files */ = { + 55B5DAD6DD79F201FE48E7D8DE57B3D1 /* Support Files */ = { isa = PBXGroup; children = ( - 788C983A7EF86108DAD81A6DB0890C9F /* Alamofire.modulemap */, - 74344AAA3AB486A0F108AF009AB853D3 /* Alamofire.xcconfig */, - 1F040ED1FF22031BE793CE58C15BA980 /* Alamofire-dummy.m */, - 5E70E1B3CF33763DC5865855EB67C9E7 /* Alamofire-Info.plist */, - 150681E90CBB4FCF4430C430C3D5FC4E /* Alamofire-prefix.pch */, - AF759A7875241995843338214EBEAE93 /* Alamofire-umbrella.h */, + BDC6616722FED557AAE794DE2C8C7365 /* Alamofire.modulemap */, + 0681AA5487811D0965B4B01D0CD5714F /* Alamofire.xcconfig */, + 3E6831ED1EAE2F53B745790C1F8CFE22 /* Alamofire-dummy.m */, + B9BD77FCA32EF5F89D62A86DA2F776BC /* Alamofire-Info.plist */, + 7F75C87B819B9CE315BBF458692D7D6D /* Alamofire-prefix.pch */, + 688746BDA70A8705D02F243EC5D1C22F /* Alamofire-umbrella.h */, ); name = "Support Files"; path = "../Target Support Files/Alamofire"; sourceTree = ""; }; - 93FB93ABC86E26D9950A768D5D7AE0C8 /* Pods */ = { + 9648317CD0E2366A8C94850B51FF77C5 /* XLPagerTabStrip */ = { isa = PBXGroup; children = ( - 2BB5A19B32F72B0217C3FFEF6A5FFC1E /* Alamofire */, - DBE1E21018A344D246C19B749EAB6B89 /* AlamofireObjectMapper */, - D8B69D1C9679A091A5CB7DA7078B7E98 /* Kingfisher */, - 5D64215721863C0357CEA7D394B11611 /* ObjectMapper */, + 2257392425B9FC8FE7DC5B8095480985 /* BarPagerTabStripViewController.swift */, + 9CCF99BC62103EB3B3ED4AF859924FF4 /* BarView.swift */, + 482D9F2306210A23ABF322A7C871F20B /* BaseButtonBarPagerTabStripViewController.swift */, + F0EF37CC7FB45F50A748D753BD4FEF02 /* ButtonBarPagerTabStripViewController.swift */, + EDF3ED71A0731EE9CFFC7B6E9E640C94 /* ButtonBarView.swift */, + C27973BB051B91C449BF29951175E3B5 /* ButtonBarViewCell.swift */, + 1B53D94C0B9FE436D110395B0E6AF3ED /* FXPageControl.h */, + 5448C36BC45DA3C80A9EAC9EFEF19C27 /* FXPageControl.m */, + E1FE093FAAB7C44666B5A8D775B2BE67 /* IndicatorInfo.swift */, + 7D2698E77FA9001529C2BE746B535CB1 /* PagerTabStripBehaviour.swift */, + 9D5EE3A418086BD6CBB44A6349B7B71E /* PagerTabStripError.swift */, + 94557283D4398624BBB4BE5BADD657C5 /* PagerTabStripViewController.swift */, + 6A93EAFE31888336421F6D3D22A81982 /* SegmentedPagerTabStripViewController.swift */, + 3E9F7439CA4FA17227A573431EE73C24 /* SwipeDirection.swift */, + 16BDA92AAD327B63574B7B1F52F879DA /* TwitterPagerTabStripViewController.swift */, + 38267FD3602C84616229C1F47F532779 /* Resources */, + 3156CC8D860E030BEC3FEE3F4A5F5B54 /* Support Files */, ); - name = Pods; + name = XLPagerTabStrip; + path = XLPagerTabStrip; sourceTree = ""; }; - CF1408CF629C7361332E53B88F7BD30C = { + A6855313795432FADD93AEAD95D4A9DA /* Support Files */ = { isa = PBXGroup; children = ( - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - D47EE9DFC9A9399780A2E73F06F1E714 /* Frameworks */, - 93FB93ABC86E26D9950A768D5D7AE0C8 /* Pods */, - 2E423AA63AA1EC2281C71B98C3A75E5B /* Products */, - 3D5C68A8C0201CFBF1679597F74EC727 /* Targets Support Files */, + 384692B23E1442E80482478705AC8EF4 /* AlamofireObjectMapper.modulemap */, + 28EC2FDC1CF0CA23AAC33148B9339D98 /* AlamofireObjectMapper.xcconfig */, + 9DCEAD5244CC26F1CA5DC0A1372ACD59 /* AlamofireObjectMapper-dummy.m */, + FD8811A91F8CD0D34F4A54EB9AC4B328 /* AlamofireObjectMapper-Info.plist */, + 9D39AD829465084732ACF97222EBCD61 /* AlamofireObjectMapper-prefix.pch */, + 03EB1BB5410BF3212336C56D489D32A3 /* AlamofireObjectMapper-umbrella.h */, ); + name = "Support Files"; + path = "../Target Support Files/AlamofireObjectMapper"; sourceTree = ""; }; - D47EE9DFC9A9399780A2E73F06F1E714 /* Frameworks */ = { + A7201D46125484DDD0BEA7FFCF0541C0 /* ObjectMapper */ = { isa = PBXGroup; children = ( - 4255134418730644F5FA8363F15E2D8F /* Alamofire.framework */, - EEE46D64CBCC85526D9A6FC8A3847ACB /* ObjectMapper.framework */, - 2528070EDF6A93CCECBEF2E82FA06E89 /* iOS */, + 4C3A26E62E83C727157AD429CFB1AA81 /* CodableTransform.swift */, + 5A6E85F2586EA3645783E734878EF4FE /* CustomDateFormatTransform.swift */, + E0E66A30373F212DBE1B636648395C03 /* DataTransform.swift */, + 7EC5A0DE9E55BE79437FB5CA0791E6AE /* DateFormatterTransform.swift */, + 7277145C96D37B4B216379F1067ADF43 /* DateTransform.swift */, + 932A9E9503C227D5E984338512DEE82B /* DictionaryTransform.swift */, + 60E0C08D9A74A0561B6BEF1DEB62F988 /* EnumOperators.swift */, + E03008CEE402D6F6AE453E119D6475C0 /* EnumTransform.swift */, + 27E59DF4567C7C9751A45ABEDC00E42D /* FromJSON.swift */, + CEF96B0960C49D23A1A1C383CDB3EE17 /* HexColorTransform.swift */, + F42FCFB86E5633C4BF258CADEF4A792B /* ImmutableMappable.swift */, + E8DDB34418DB793F10E66F5A6BE6EB7E /* IntegerOperators.swift */, + 7A272D6646A72A83DFE3AA54F3D9D310 /* ISO8601DateTransform.swift */, + 54E86165286F83A130B89C9F9D8D856A /* Map.swift */, + 32DA86E93085BE1C4A8583B7F78CD8FD /* MapError.swift */, + 5ABBF189F89C148B98C240840EA6F34B /* Mappable.swift */, + 49708E87077B90FFDD0C2B3436324325 /* Mapper.swift */, + 2E81290EF70675F31652388CD135E09B /* NSDecimalNumberTransform.swift */, + 3CAD378B9EC75B6EC18048B6A052B131 /* Operators.swift */, + C015B603DAF4B79DE58EF72EA32EFB8F /* ToJSON.swift */, + 27368A4248280BB278CD91A4D3062EFC /* TransformOf.swift */, + A5FAA5238EE2370609D01B43A4AF65DD /* TransformOperators.swift */, + 29E2C0834384B57CF05156B885AB72DD /* TransformType.swift */, + 803B12E815A84748016464290D8646C5 /* URLTransform.swift */, + 03E92848BCA2089EC4E2901F3BCE54CE /* Support Files */, ); - name = Frameworks; + name = ObjectMapper; + path = ObjectMapper; sourceTree = ""; }; - D8B69D1C9679A091A5CB7DA7078B7E98 /* Kingfisher */ = { + AFA1DBAAB98DE5D57B4B70E4D842F9DE /* Kingfisher */ = { isa = PBXGroup; children = ( - D9908EC83A140886F26FEC8422443D95 /* AnimatedImageView.swift */, - D2B73420B939F155CE0DACD44FEAFCD5 /* Box.swift */, - EA74144E6C71B4D56311916DCF6B23F3 /* CacheSerializer.swift */, - F15BCF2644E13B6E0E4CC8A7DF462122 /* Filter.swift */, - 484BD670A85D89264544DF134D2FE7D4 /* FormatIndicatedCacheSerializer.swift */, - D4BE99B771521C0D185E9D417F06D5D6 /* Image.swift */, - 10B5EB0943660D8666E85F2977E6B301 /* ImageCache.swift */, - F44C518042B4A53AF8527CB85E8B373E /* ImageDownloader.swift */, - 0986D2553648F0746A217E033FB09BD8 /* ImageModifier.swift */, - A33FAB021477544550E0484538F39D04 /* ImagePrefetcher.swift */, - C85BE459F8C97CC387CDA34555579DB0 /* ImageProcessor.swift */, - F9770B58667C7130802B59828F60356F /* ImageTransition.swift */, - 5A45391F54CDF31BBFE4606B3892900C /* ImageView+Kingfisher.swift */, - 3476A7731838FF67CCC062E609615F98 /* Indicator.swift */, - 06B91D8C89C7099D9D9C4689331A840C /* Kingfisher.h */, - E77EE86EDC2A7914429626F2467AE2FB /* Kingfisher.swift */, - AF8E0B7D165C4ABFECCDA1E3CF311A99 /* KingfisherManager.swift */, - 63143E25F0EECF2DBB6282505A59A67B /* KingfisherOptionsInfo.swift */, - 42FE39508FEBD9AB434D294E6E652776 /* Placeholder.swift */, - 3FD982A938881006D4EDFA5CD6ABDB87 /* RequestModifier.swift */, - 76885D5D3123A4314F1D74F4BE12932E /* Resource.swift */, - 81A5A4D8C198D0E089F6A67B52A12679 /* String+MD5.swift */, - 139FA5FCB8E6F3B1A372C16D78E0FBF0 /* ThreadHelper.swift */, - 26F1FD75EC50095D98937FDE65E2F4F1 /* UIButton+Kingfisher.swift */, - 131E2AC9AC9A470326E7E8B1D9C6AB15 /* Support Files */, + 74EE2922114950461F54D42A574E931B /* AnimatedImageView.swift */, + F8DA6FD51672F9002E1076D7AA96625E /* Box.swift */, + 4514390946338881CF9BE7B0495C0B8A /* CacheSerializer.swift */, + 9F9E4AAC09932A580A55532EAE683979 /* Filter.swift */, + 5A08C53FC1F7E625C0D6D75B3820971A /* FormatIndicatedCacheSerializer.swift */, + A2D55EE884A7D1AC76E4F140C2357FF2 /* Image.swift */, + 35685E91008C0C90D24A9114B359E651 /* ImageCache.swift */, + 58194FC78E57E424CCD6A5499B346874 /* ImageDownloader.swift */, + 642C623E19BB3031D369D16A70136236 /* ImageModifier.swift */, + 71D787740C8D6B17DF369ED0179C372E /* ImagePrefetcher.swift */, + 287EF0A55C55781536CD26441DDCBA03 /* ImageProcessor.swift */, + B463F2B96CD19C438F374BCC02C4F997 /* ImageTransition.swift */, + D1160B39AE013E090625A8ED69438550 /* ImageView+Kingfisher.swift */, + FA0355AB3BC139259660241D81207E46 /* Indicator.swift */, + 3A959D62A4E9FEF5388D9BFD56339B21 /* Kingfisher.h */, + 63D453B9D697B3E58A4B054AA8B5F925 /* Kingfisher.swift */, + 071546085B39C5EBDCC89FC3DBACE514 /* KingfisherManager.swift */, + 6BC07248A46CC125113CE2C30CEA3C5F /* KingfisherOptionsInfo.swift */, + 31276D9479F7A8A96A23AFC48D338CAA /* Placeholder.swift */, + C0C17725F6B1B0D98A634B5B391B504F /* RequestModifier.swift */, + E9A712BEA8EEE22DEF0C1E2394AB5188 /* Resource.swift */, + 2A7F57C3FE0F83A32AB42C9F50ADE083 /* String+MD5.swift */, + AFC3965899E4FB0B43D0F41897BAEAC5 /* ThreadHelper.swift */, + 758471292657321B219103490AE38DA7 /* UIButton+Kingfisher.swift */, + F4C9268E0759AD3F341D4F94F894D6A8 /* Support Files */, ); name = Kingfisher; path = Kingfisher; sourceTree = ""; }; - DBE1E21018A344D246C19B749EAB6B89 /* AlamofireObjectMapper */ = { + CBF506C0A897891D519B53970B5D418C /* Products */ = { isa = PBXGroup; children = ( - A64AA90C724E10B7A4AE18CB07F84BEF /* AlamofireObjectMapper.swift */, - DEA576CEA9254FAC8821B1F219982F3D /* Support Files */, + 0F37485DB577398A7FDCCE0F8F05162A /* Alamofire.framework */, + BD8AA3FE5AA67B9768E8D23A3C6CDE62 /* AlamofireObjectMapper.framework */, + B21C86A5C4255093D77A2862F46BAB9B /* Kingfisher.framework */, + 28F2E4DBF9A55E142D00BE46122AD5FF /* ObjectMapper.framework */, + D4723F3CDBFBA8FA855765FD42332A7D /* Pods_GetRestIOS.framework */, + 3BBDAF3AA0D8858E27887AEB968514D2 /* ScrollableGraphView.framework */, + BD15204CDC32C3C1384C9D149C6D0900 /* XLPagerTabStrip.bundle */, + C6E9FE7124AF14AAA4EA28B0910B370F /* XLPagerTabStrip.framework */, ); - name = AlamofireObjectMapper; - path = AlamofireObjectMapper; + name = Products; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + 0A9280645A8D49562038882F04B40922 /* Frameworks */, + 409CD76EB56818E48EF9A3F0AA0E2714 /* Pods */, + CBF506C0A897891D519B53970B5D418C /* Products */, + 3D5C68A8C0201CFBF1679597F74EC727 /* Targets Support Files */, + ); + sourceTree = ""; + }; + D9BEC53E8994EC082758024A845F54C3 /* iOS */ = { + isa = PBXGroup; + children = ( + DC69BB97A9D32BEE90E92E203F897EAE /* CFNetwork.framework */, + 9DA1E0BD8C69135FB4B74C79D159BDA0 /* Foundation.framework */, + B535AB9324C02900D60997DE28D2D730 /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + E9698890C750DAA3FB6F962C09591465 /* ScrollableGraphView */ = { + isa = PBXGroup; + children = ( + A8EE119C76C786A623216BDE69E20A62 /* BarDrawingLayer.swift */, + ED30501CC6CA178CD9564DE65D63CEE0 /* BarPlot.swift */, + 28AD2D3D2517B66DC39EF018A8877D2A /* DotDrawingLayer.swift */, + AB21AF578F5EF0E2AA714BE7A6A3F783 /* DotPlot.swift */, + CCAE054B0D98D013C8306CF8F2D8C460 /* FillDrawingLayer.swift */, + C25EBF4D4FB8DA84A1893353EB8891D5 /* GradientDrawingLayer.swift */, + D186D786A94E470E1857506D33C478D4 /* GraphPoint.swift */, + 478B759C865EE900E018EB4D35DE9CFC /* GraphPointAnimation.swift */, + 8A1E27C84AE0F02149E1E7AF0B45DA02 /* LabelPool.swift */, + 681C5140E52BEDE25DAFEFABF4584E3E /* LineDrawingLayer.swift */, + 388606EE6EFA76148FB2D79573DBB3A6 /* LinePlot.swift */, + E0F7CBAC4B35DC776B09272F91613DE8 /* Plot.swift */, + F8B1B71428493C07C5CFB396270D3A64 /* ReferenceLineDrawingView.swift */, + 9A4B2CA663A801F43C2B89A19F97FF4D /* ReferenceLines.swift */, + 1A26AF103240EA161625F296CE997E88 /* ScrollableGraphView.swift */, + CA01BA715C06D5D0B8036CFAC2EAE2FF /* ScrollableGraphViewDataSource.swift */, + 6B8DAFEAA10C5233BF36F2B1BF361033 /* ScrollableGraphViewDrawingDelegate.swift */, + 4D3F2435C6DF2E715450D0EDA95A182F /* ScrollableGraphViewDrawingLayer.swift */, + 3FB990D09288CA9C240D475A4B2D43E4 /* Support Files */, + ); + name = ScrollableGraphView; + path = ScrollableGraphView; sourceTree = ""; }; - DEA576CEA9254FAC8821B1F219982F3D /* Support Files */ = { + F4C9268E0759AD3F341D4F94F894D6A8 /* Support Files */ = { isa = PBXGroup; children = ( - 1E5F17FA4415992DFA715D85411DB63C /* AlamofireObjectMapper.modulemap */, - 513E6D4F332D1EE4C1E8D047DBEBC13C /* AlamofireObjectMapper.xcconfig */, - 32676DA2198AB81AC5B1778F61F5F1CD /* AlamofireObjectMapper-dummy.m */, - 1B5B72BFED64BB60C4E621C7C60060D7 /* AlamofireObjectMapper-Info.plist */, - 6F9E1BC587627058C17DFC27655974D3 /* AlamofireObjectMapper-prefix.pch */, - 265ADD9480EBB2BA8B942FF7009CB94C /* AlamofireObjectMapper-umbrella.h */, + 39014AD8BA68AEB595685FA742E5564B /* Kingfisher.modulemap */, + EC8BB4FD4527268EC4A39FAF8B79532A /* Kingfisher.xcconfig */, + 1A211583F182A0B6249248BB91FA3196 /* Kingfisher-dummy.m */, + 79DB06FCF2E92865E9B6785B1C8D7C80 /* Kingfisher-Info.plist */, + 47C943CCF0D864EA766432033124C0AB /* Kingfisher-prefix.pch */, + B02E60A2228663BA06071EC4C9CBF9B1 /* Kingfisher-umbrella.h */, ); name = "Support Files"; - path = "../Target Support Files/AlamofireObjectMapper"; + path = "../Target Support Files/Kingfisher"; sourceTree = ""; }; /* End PBXGroup section */ @@ -544,19 +777,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 69D5C17A42F0DEBA97F93493F069DBB8 /* Headers */ = { + 609113437B6B4784EBE923F2E1C85326 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 7F424C046646FE578B5BAA8AE3D30B37 /* ObjectMapper-umbrella.h in Headers */, + 07942666EC70498FC0CE360ACDC04D3A /* FXPageControl.h in Headers */, + 5B8E9B2484D4F4367D0244BD8FF8E948 /* XLPagerTabStrip-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64EFA1386FC08062E66735514B36CE91 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 14A69231E9B356F73BF669FE8A0A98BF /* Pods-GetRestIOS-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 8352EA4288E29E72B398E370230C9331 /* Headers */ = { + 69D5C17A42F0DEBA97F93493F069DBB8 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - CCD2951D6F2996525953F148B99568AD /* Pods-GetRestIOS-umbrella.h in Headers */, + 7F424C046646FE578B5BAA8AE3D30B37 /* ObjectMapper-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -577,6 +819,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C5EC9E0CDFD89A9ED00A04281F05840B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 68EAE4F9EBA06D7D834206C4FAEBE36C /* ScrollableGraphView-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -595,9 +845,26 @@ ); name = ObjectMapper; productName = ObjectMapper; - productReference = 813BE20269FDB8E362958A033991622E /* ObjectMapper.framework */; + productReference = 28F2E4DBF9A55E142D00BE46122AD5FF /* ObjectMapper.framework */; productType = "com.apple.product-type.framework"; }; + 2AFE7E73274862DFD5D580BF0BA03CE2 /* XLPagerTabStrip-XLPagerTabStrip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7FF1C63F04F401C9C7A22BC551CB912D /* Build configuration list for PBXNativeTarget "XLPagerTabStrip-XLPagerTabStrip" */; + buildPhases = ( + 6CCA1ECCDF865AF7580645160831D70C /* Sources */, + 5A81103CEFC1A3F5FF22BD544B640EEB /* Frameworks */, + 955D50AC8CA8DFF36B4E4D0467CC27BC /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "XLPagerTabStrip-XLPagerTabStrip"; + productName = "XLPagerTabStrip-XLPagerTabStrip"; + productReference = BD15204CDC32C3C1384C9D149C6D0900 /* XLPagerTabStrip.bundle */; + productType = "com.apple.product-type.bundle"; + }; 3383968E74B5371B20BB519B170DC7FD /* Alamofire */ = { isa = PBXNativeTarget; buildConfigurationList = E87124444A44B7DB55208E7FEC21D331 /* Build configuration list for PBXNativeTarget "Alamofire" */; @@ -613,7 +880,7 @@ ); name = Alamofire; productName = Alamofire; - productReference = 9E384806E109B4030E4D837E95D5B81B /* Alamofire.framework */; + productReference = 0F37485DB577398A7FDCCE0F8F05162A /* Alamofire.framework */; productType = "com.apple.product-type.framework"; }; 4A0A22DC77365EB37D44E9B9E0F3ABD4 /* Kingfisher */ = { @@ -631,7 +898,25 @@ ); name = Kingfisher; productName = Kingfisher; - productReference = 608F27D594B4FC0692990626061228AF /* Kingfisher.framework */; + productReference = B21C86A5C4255093D77A2862F46BAB9B /* Kingfisher.framework */; + productType = "com.apple.product-type.framework"; + }; + 5EDBAC25970E4256AFA87C97F6E6C6E5 /* ScrollableGraphView */ = { + isa = PBXNativeTarget; + buildConfigurationList = DEF223990A0760728F3C750B4CFB9B22 /* Build configuration list for PBXNativeTarget "ScrollableGraphView" */; + buildPhases = ( + C5EC9E0CDFD89A9ED00A04281F05840B /* Headers */, + 79135C871690C347C9992C34059B6C25 /* Sources */, + 5972F23ED21812D1422AC71C934A6979 /* Frameworks */, + 99D1BD2C059F6D4F8A4344152DEDD713 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ScrollableGraphView; + productName = ScrollableGraphView; + productReference = 3BBDAF3AA0D8858E27887AEB968514D2 /* ScrollableGraphView.framework */; productType = "com.apple.product-type.framework"; }; 743E4A349913BA26BF7AEE81D0D0DC34 /* AlamofireObjectMapper */ = { @@ -651,29 +936,50 @@ ); name = AlamofireObjectMapper; productName = AlamofireObjectMapper; - productReference = B974C5C308E0C2A5EB9BE13E11CC1852 /* AlamofireObjectMapper.framework */; + productReference = BD8AA3FE5AA67B9768E8D23A3C6CDE62 /* AlamofireObjectMapper.framework */; productType = "com.apple.product-type.framework"; }; - BE5AA0378929F17CE7B5C5B52DEDBAB2 /* Pods-GetRestIOS */ = { + BC8911E7CB00F6759DE6DE6DC45570D4 /* XLPagerTabStrip */ = { isa = PBXNativeTarget; - buildConfigurationList = 572216C437CFC5C90F96BAC980A662C1 /* Build configuration list for PBXNativeTarget "Pods-GetRestIOS" */; + buildConfigurationList = 4A76FEC8B753D238E484F54A319CFAE6 /* Build configuration list for PBXNativeTarget "XLPagerTabStrip" */; buildPhases = ( - 8352EA4288E29E72B398E370230C9331 /* Headers */, - 35ED607741A177010DCE8229A87C8B09 /* Sources */, - 2DE5D5012496E0ECD9EFE637BD212BF1 /* Frameworks */, - 9985791AF7F3635C169188730D59CAF3 /* Resources */, + 609113437B6B4784EBE923F2E1C85326 /* Headers */, + 69A3D0F5F490674EDB527ADC909AA10B /* Sources */, + 8CAA4CAA81A34D92ECEBBFF8C11E1599 /* Frameworks */, + 80BCE4B56B4C3410E0AAC4BC5F8C90DA /* Resources */, ); buildRules = ( ); dependencies = ( - 629AB95D5B7B7EB87879299D54BF6371 /* PBXTargetDependency */, - 02B16F66BEBF8AB3142E80EFE56B82C0 /* PBXTargetDependency */, - 642ED9E469C068393B2D0DBDCF33689E /* PBXTargetDependency */, - 34CD6D14315769882ACBF8E4B63B556B /* PBXTargetDependency */, + 8BAA6B3E682F67ECAD25268063F2A9BB /* PBXTargetDependency */, + ); + name = XLPagerTabStrip; + productName = XLPagerTabStrip; + productReference = C6E9FE7124AF14AAA4EA28B0910B370F /* XLPagerTabStrip.framework */; + productType = "com.apple.product-type.framework"; + }; + E697E5BFC005C672BD7AAD5A0D7C8769 /* Pods-GetRestIOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2743022549D660AB8FB3FCF5CC12A78B /* Build configuration list for PBXNativeTarget "Pods-GetRestIOS" */; + buildPhases = ( + 64EFA1386FC08062E66735514B36CE91 /* Headers */, + 6C3EC46B7F8AC8D48C073D3571A67E9B /* Sources */, + 8035A55A140FCC40B751668FF7DCD1CD /* Frameworks */, + 42CD58DFDC2A57DBF0FEF4A1D68EDABA /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 0C3DB9C0BC96056295D8FEDE5593BC67 /* PBXTargetDependency */, + C5B20DE7A1F63E884CC85B846CE035DF /* PBXTargetDependency */, + 565A69D0096FC4C08B253EE1407BED3F /* PBXTargetDependency */, + C6867FCC05D4005EC0D7295AD441A0F3 /* PBXTargetDependency */, + 1734B74EBFA964CC99F93C52691504F1 /* PBXTargetDependency */, + B8D3E9948432DD0275A03633B13C04BB /* PBXTargetDependency */, ); name = "Pods-GetRestIOS"; productName = "Pods-GetRestIOS"; - productReference = F62AEB5A7D0463195B6DE26564927E6A /* Pods_GetRestIOS.framework */; + productReference = D4723F3CDBFBA8FA855765FD42332A7D /* Pods_GetRestIOS.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -686,14 +992,14 @@ LastUpgradeCheck = 1020; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; - compatibilityVersion = "Xcode 9.3"; + compatibilityVersion = "Xcode 10.0"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = CF1408CF629C7361332E53B88F7BD30C; - productRefGroup = 2E423AA63AA1EC2281C71B98C3A75E5B /* Products */; + productRefGroup = CBF506C0A897891D519B53970B5D418C /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( @@ -701,7 +1007,10 @@ 743E4A349913BA26BF7AEE81D0D0DC34 /* AlamofireObjectMapper */, 4A0A22DC77365EB37D44E9B9E0F3ABD4 /* Kingfisher */, 0882708950626A3ECBCB6A065347330B /* ObjectMapper */, - BE5AA0378929F17CE7B5C5B52DEDBAB2 /* Pods-GetRestIOS */, + E697E5BFC005C672BD7AAD5A0D7C8769 /* Pods-GetRestIOS */, + 5EDBAC25970E4256AFA87C97F6E6C6E5 /* ScrollableGraphView */, + BC8911E7CB00F6759DE6DE6DC45570D4 /* XLPagerTabStrip */, + 2AFE7E73274862DFD5D580BF0BA03CE2 /* XLPagerTabStrip-XLPagerTabStrip */, ); }; /* End PBXProject section */ @@ -721,7 +1030,30 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9985791AF7F3635C169188730D59CAF3 /* Resources */ = { + 42CD58DFDC2A57DBF0FEF4A1D68EDABA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 80BCE4B56B4C3410E0AAC4BC5F8C90DA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C0CCAF0F0FCCA68395A8E3285B9EB2C8 /* XLPagerTabStrip.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 955D50AC8CA8DFF36B4E4D0467CC27BC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 849F6F5ED2DCFA725F0DA892F7020E73 /* ButtonCell.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 99D1BD2C059F6D4F8A4344152DEDD713 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -754,11 +1086,66 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 35ED607741A177010DCE8229A87C8B09 /* Sources */ = { + 69A3D0F5F490674EDB527ADC909AA10B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E66567F8C1A941AC2B74B649A01918BF /* Pods-GetRestIOS-dummy.m in Sources */, + 4D5B30B36079E7CF6788A9404A1A1B94 /* BarPagerTabStripViewController.swift in Sources */, + A0520FC66695256426D743FA2D42D8FF /* BarView.swift in Sources */, + 023AE5E73991D565BF5C879492D85D87 /* BaseButtonBarPagerTabStripViewController.swift in Sources */, + 8EA6D69F71B0FB44A169563C491B43F3 /* ButtonBarPagerTabStripViewController.swift in Sources */, + E7BB386A78DE89D8CD138D09A0173F8C /* ButtonBarView.swift in Sources */, + 456B9D594F9E045823CC03B1A692F7CB /* ButtonBarViewCell.swift in Sources */, + 0A2F1AEDDCF1CE5E556D9092B9FB4A54 /* FXPageControl.m in Sources */, + 52CBFC5C47D4072474CD951AD373D5BC /* IndicatorInfo.swift in Sources */, + 815A942158A2A9033C8CF892C0E9D42C /* PagerTabStripBehaviour.swift in Sources */, + B0091594D9D26432A7AB3F212D7C4933 /* PagerTabStripError.swift in Sources */, + C4B4950DCDE41CA8BA2D64DE05234C2A /* PagerTabStripViewController.swift in Sources */, + 65E87B29E22B78A63FC86023BF0264B7 /* SegmentedPagerTabStripViewController.swift in Sources */, + BFCAA4B4BD33CB5C396C8121585B3E3C /* SwipeDirection.swift in Sources */, + 29B1A621E9EF143374D3D1705060F31E /* TwitterPagerTabStripViewController.swift in Sources */, + 9CE49D8096A1CB52CDA2DFEE70D0AD35 /* XLPagerTabStrip-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C3EC46B7F8AC8D48C073D3571A67E9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 025A3E121CFC95A918072DCC749B9820 /* Pods-GetRestIOS-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CCA1ECCDF865AF7580645160831D70C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79135C871690C347C9992C34059B6C25 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5CD00709C49E904F708725B90316CBC6 /* BarDrawingLayer.swift in Sources */, + E9D7DEC99FDBFB0E2E7BC01B388BB7D0 /* BarPlot.swift in Sources */, + F681AACAD4F67208C9C4D934EE911596 /* DotDrawingLayer.swift in Sources */, + 8992EB524FA3B181B2A5B0931B7AB835 /* DotPlot.swift in Sources */, + 95644C8A14F1F77F1D0D77592C2D6B5A /* FillDrawingLayer.swift in Sources */, + FB84E320678BF2FC15BD7DC165E46438 /* GradientDrawingLayer.swift in Sources */, + 50E7AC236E46DA2903C80227393CB8AE /* GraphPoint.swift in Sources */, + 9D98A81426C3604FB3084DEA56EEB0BA /* GraphPointAnimation.swift in Sources */, + 9D0B00EAA4282312840787D9A4CEE4AB /* LabelPool.swift in Sources */, + 567B0E636EEDC38CA73441BC2284A4E9 /* LineDrawingLayer.swift in Sources */, + 79EA9C787417F6CEB3E1666F3234F7BC /* LinePlot.swift in Sources */, + 7029EDDF782D6A4D7065ADB970065D57 /* Plot.swift in Sources */, + A615C52520DE484B41D7CBBC67E0FDB4 /* ReferenceLineDrawingView.swift in Sources */, + F339C07FB4C8DC00884EBD80E38E7FB0 /* ReferenceLines.swift in Sources */, + CF5DCB055E7C52404F277F98DCDEB28B /* ScrollableGraphView-dummy.m in Sources */, + EE137952E4142821A09FC27DFBE108F1 /* ScrollableGraphView.swift in Sources */, + CBE2D21662DBEDC43071D7C2DC406103 /* ScrollableGraphViewDataSource.swift in Sources */, + 5F4B7A4C9FFE0D3DB9AFD57EBC182E30 /* ScrollableGraphViewDrawingDelegate.swift in Sources */, + E1FCC9513457B776C59AED1FD86917F5 /* ScrollableGraphViewDrawingLayer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -853,35 +1240,53 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 02B16F66BEBF8AB3142E80EFE56B82C0 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = AlamofireObjectMapper; - target = 743E4A349913BA26BF7AEE81D0D0DC34 /* AlamofireObjectMapper */; - targetProxy = 7E48B9BBB9301A913A419E63ED7EE9F5 /* PBXContainerItemProxy */; - }; - 3155D3CEB59D4A6B616692A447046BAF /* PBXTargetDependency */ = { + 0C3DB9C0BC96056295D8FEDE5593BC67 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Alamofire; target = 3383968E74B5371B20BB519B170DC7FD /* Alamofire */; - targetProxy = 9F95E621710F4B7EBD56B83C134F6AD5 /* PBXContainerItemProxy */; + targetProxy = 016B2062743B2143F41291F7AFD705C4 /* PBXContainerItemProxy */; }; - 34CD6D14315769882ACBF8E4B63B556B /* PBXTargetDependency */ = { + 1734B74EBFA964CC99F93C52691504F1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = ObjectMapper; - target = 0882708950626A3ECBCB6A065347330B /* ObjectMapper */; - targetProxy = B979B35D2514B358C0175B8BB71C5599 /* PBXContainerItemProxy */; + name = ScrollableGraphView; + target = 5EDBAC25970E4256AFA87C97F6E6C6E5 /* ScrollableGraphView */; + targetProxy = 9F060D2E07F4C24B36819659E02C161A /* PBXContainerItemProxy */; }; - 629AB95D5B7B7EB87879299D54BF6371 /* PBXTargetDependency */ = { + 3155D3CEB59D4A6B616692A447046BAF /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Alamofire; target = 3383968E74B5371B20BB519B170DC7FD /* Alamofire */; - targetProxy = B0A0000AACCAE782312410793228CA71 /* PBXContainerItemProxy */; + targetProxy = 9F95E621710F4B7EBD56B83C134F6AD5 /* PBXContainerItemProxy */; }; - 642ED9E469C068393B2D0DBDCF33689E /* PBXTargetDependency */ = { + 565A69D0096FC4C08B253EE1407BED3F /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Kingfisher; target = 4A0A22DC77365EB37D44E9B9E0F3ABD4 /* Kingfisher */; - targetProxy = 5438FAD39C104426A0D9199DB1F44873 /* PBXContainerItemProxy */; + targetProxy = 78FFFE21F72F86AECBFBF2C33ABD9354 /* PBXContainerItemProxy */; + }; + 8BAA6B3E682F67ECAD25268063F2A9BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "XLPagerTabStrip-XLPagerTabStrip"; + target = 2AFE7E73274862DFD5D580BF0BA03CE2 /* XLPagerTabStrip-XLPagerTabStrip */; + targetProxy = 2199626C60CA466ABC00BA6842138A5E /* PBXContainerItemProxy */; + }; + B8D3E9948432DD0275A03633B13C04BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = XLPagerTabStrip; + target = BC8911E7CB00F6759DE6DE6DC45570D4 /* XLPagerTabStrip */; + targetProxy = 40E92A3CE60424D36E29455A40BF40EE /* PBXContainerItemProxy */; + }; + C5B20DE7A1F63E884CC85B846CE035DF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = AlamofireObjectMapper; + target = 743E4A349913BA26BF7AEE81D0D0DC34 /* AlamofireObjectMapper */; + targetProxy = 1B98A957FC26CEA42F28018C0B0C840C /* PBXContainerItemProxy */; + }; + C6867FCC05D4005EC0D7295AD441A0F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = ObjectMapper; + target = 0882708950626A3ECBCB6A065347330B /* ObjectMapper */; + targetProxy = C3BAD0237695BD05AE76DDF201393FDE /* PBXContainerItemProxy */; }; DA9C863ED9905AD7ACD4A26C10D28515 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -894,7 +1299,7 @@ /* Begin XCBuildConfiguration section */ 03DAC121EB2BC6A02FC6CD0C1761262F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2343C987478E4125F9DB74A8E36BE80E /* Kingfisher.xcconfig */; + baseConfigurationReference = EC8BB4FD4527268EC4A39FAF8B79532A /* Kingfisher.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -929,7 +1334,7 @@ }; 0661ADF27034244673BC9D454193698F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 513E6D4F332D1EE4C1E8D047DBEBC13C /* AlamofireObjectMapper.xcconfig */; + baseConfigurationReference = 28EC2FDC1CF0CA23AAC33148B9339D98 /* AlamofireObjectMapper.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -965,7 +1370,7 @@ }; 1828B2CFA60046054C21FB9606384D45 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 513E6D4F332D1EE4C1E8D047DBEBC13C /* AlamofireObjectMapper.xcconfig */; + baseConfigurationReference = 28EC2FDC1CF0CA23AAC33148B9339D98 /* AlamofireObjectMapper.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1000,7 +1405,7 @@ }; 1D256AFAD8F18BF1F1E48B504377A4B7 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E0274FBA440263A9D15DCCC6F51D75F0 /* ObjectMapper.xcconfig */; + baseConfigurationReference = AC2721B68FAD211CC3D6249E5D5750C1 /* ObjectMapper.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1098,12 +1503,10 @@ }; name = Debug; }; - 27716B87468B3E0D4F18249DAC9E740B /* Debug */ = { + 2AFB2FBDC8BE81E73EB336E4038881BA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0B2CDB4FA13BD80A2CBD5F64B735936B /* Pods-GetRestIOS.debug.xcconfig */; + baseConfigurationReference = BD15D7F477CC17474FA3E412A01AF1F8 /* ScrollableGraphView.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; - CLANG_ENABLE_OBJC_WEAK = NO; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -1113,28 +1516,64 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/ScrollableGraphView/ScrollableGraphView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/ScrollableGraphView/ScrollableGraphView-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 12.2; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.modulemap"; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + MODULEMAP_FILE = "Target Support Files/ScrollableGraphView/ScrollableGraphView.modulemap"; + PRODUCT_MODULE_NAME = ScrollableGraphView; + PRODUCT_NAME = ScrollableGraphView; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; + }; + 3506770F229F6D4F28F4831B7381A679 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap"; + PRODUCT_MODULE_NAME = XLPagerTabStrip; + PRODUCT_NAME = XLPagerTabStrip; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; }; 3CCC6195EDBEE5DA2A49DF962113BE16 /* Release */ = { isa = XCBuildConfiguration; @@ -1198,7 +1637,7 @@ }; 53F579EB33F69E2357E748B5E9CF12D5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E0274FBA440263A9D15DCCC6F51D75F0 /* ObjectMapper.xcconfig */; + baseConfigurationReference = AC2721B68FAD211CC3D6249E5D5750C1 /* ObjectMapper.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1233,7 +1672,7 @@ }; 5EA5B16470125F51417FD02CB6401D1D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2343C987478E4125F9DB74A8E36BE80E /* Kingfisher.xcconfig */; + baseConfigurationReference = EC8BB4FD4527268EC4A39FAF8B79532A /* Kingfisher.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1267,9 +1706,25 @@ }; name = Release; }; + 73AD8FF42FC1C9CA6D325C6C6EEE7772 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/XLPagerTabStrip"; + INFOPLIST_FILE = "Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + PRODUCT_NAME = XLPagerTabStrip; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; 9CF36E6AA46D597086D835E1724A4D87 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 74344AAA3AB486A0F108AF009AB853D3 /* Alamofire.xcconfig */; + baseConfigurationReference = 0681AA5487811D0965B4B01D0CD5714F /* Alamofire.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1303,9 +1758,63 @@ }; name = Release; }; + A66F6882BDE77012936BF835592DD991 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0B2CDB4FA13BD80A2CBD5F64B735936B /* Pods-GetRestIOS.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A846A2A47FE3D8CA83BE15ED09A11097 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/XLPagerTabStrip"; + INFOPLIST_FILE = "Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + PRODUCT_NAME = XLPagerTabStrip; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; B914025A518B53556696F19D8D477057 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 74344AAA3AB486A0F108AF009AB853D3 /* Alamofire.xcconfig */; + baseConfigurationReference = 0681AA5487811D0965B4B01D0CD5714F /* Alamofire.xcconfig */; buildSettings = { CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; @@ -1338,7 +1847,77 @@ }; name = Debug; }; - D7311215EC034769D81A8388E0056CCF /* Release */ = { + C6498AB64519793916E5BC90D940F86C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 685FB3926C6030A5606606457EBD1C29 /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap"; + PRODUCT_MODULE_NAME = XLPagerTabStrip; + PRODUCT_NAME = XLPagerTabStrip; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E6894AFAF3A78BE44CC165FDAFE35F44 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BD15D7F477CC17474FA3E412A01AF1F8 /* ScrollableGraphView.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/ScrollableGraphView/ScrollableGraphView-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/ScrollableGraphView/ScrollableGraphView-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MODULEMAP_FILE = "Target Support Files/ScrollableGraphView/ScrollableGraphView.modulemap"; + PRODUCT_MODULE_NAME = ScrollableGraphView; + PRODUCT_NAME = ScrollableGraphView; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + ECE8ECB156B9172A8D5D0CAA3437F6BA /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7017A9A681D7F3FD97550F06C789B8DF /* Pods-GetRestIOS.release.xcconfig */; buildSettings = { @@ -1380,6 +1959,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 2743022549D660AB8FB3FCF5CC12A78B /* Build configuration list for PBXNativeTarget "Pods-GetRestIOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A66F6882BDE77012936BF835592DD991 /* Debug */, + ECE8ECB156B9172A8D5D0CAA3437F6BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1389,11 +1977,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 572216C437CFC5C90F96BAC980A662C1 /* Build configuration list for PBXNativeTarget "Pods-GetRestIOS" */ = { + 4A76FEC8B753D238E484F54A319CFAE6 /* Build configuration list for PBXNativeTarget "XLPagerTabStrip" */ = { isa = XCConfigurationList; buildConfigurations = ( - 27716B87468B3E0D4F18249DAC9E740B /* Debug */, - D7311215EC034769D81A8388E0056CCF /* Release */, + C6498AB64519793916E5BC90D940F86C /* Debug */, + 3506770F229F6D4F28F4831B7381A679 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7FF1C63F04F401C9C7A22BC551CB912D /* Build configuration list for PBXNativeTarget "XLPagerTabStrip-XLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A846A2A47FE3D8CA83BE15ED09A11097 /* Debug */, + 73AD8FF42FC1C9CA6D325C6C6EEE7772 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1425,6 +2022,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DEF223990A0760728F3C750B4CFB9B22 /* Build configuration list for PBXNativeTarget "ScrollableGraphView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E6894AFAF3A78BE44CC165FDAFE35F44 /* Debug */, + 2AFB2FBDC8BE81E73EB336E4038881BA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; E87124444A44B7DB55208E7FEC21D331 /* Build configuration list for PBXNativeTarget "Alamofire" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Pods/Pods.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist index 53bedfc..bec895a 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pods/Pods.xcodeproj/xcuserdata/gyeongseon.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,31 +4,50 @@ SchemeUserState - Alamofire.xcscheme_^#shared#^_ + Alamofire.xcscheme + isShown + orderHint 0 - AlamofireObjectMapper.xcscheme_^#shared#^_ + AlamofireObjectMapper.xcscheme + isShown + + orderHint + 1 + + Kingfisher.xcscheme + + isShown + orderHint 2 - Kingfisher.xcscheme_^#shared#^_ + ObjectMapper.xcscheme + isShown + orderHint 3 - ObjectMapper.xcscheme_^#shared#^_ + Pods-GetRestIOS.xcscheme + isShown + orderHint 4 - Pods-GetRestIOS.xcscheme_^#shared#^_ + ScrollableGraphView.xcscheme + isShown + orderHint 5 + SuppressBuildableAutocreation + diff --git a/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/Pods-GetRestIOS.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/Pods-GetRestIOS.xcscheme index c4d1d45..a6abb0b 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/Pods-GetRestIOS.xcscheme +++ b/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/Pods-GetRestIOS.xcscheme @@ -14,7 +14,7 @@ buildForAnalyzing = "YES"> @@ -45,7 +45,7 @@ diff --git a/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist index b5d21bb..b78a1c6 100644 --- a/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Pods/Pods.xcodeproj/xcuserdata/leean.xcuserdatad/xcschemes/xcschememanagement.plist @@ -39,6 +39,21 @@ orderHint 4 + ScrollableGraphView.xcscheme + + orderHint + 5 + + XLPagerTabStrip-XLPagerTabStrip.xcscheme + + orderHint + 7 + + XLPagerTabStrip.xcscheme + + orderHint + 6 + SuppressBuildableAutocreation diff --git a/Pods/ScrollableGraphView/Classes/Drawing/BarDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/BarDrawingLayer.swift new file mode 100644 index 0000000..8b9b74d --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/BarDrawingLayer.swift @@ -0,0 +1,77 @@ + +import UIKit + +// MARK: Drawing the bars +internal class BarDrawingLayer: ScrollableGraphViewDrawingLayer { + + private var barPath = UIBezierPath() + private var barWidth: CGFloat = 4 + private var shouldRoundCorners = false + + init(frame: CGRect, barWidth: CGFloat, barColor: UIColor, barLineWidth: CGFloat, barLineColor: UIColor, shouldRoundCorners: Bool) { + super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height) + + self.barWidth = barWidth + self.lineWidth = barLineWidth + self.strokeColor = barLineColor.cgColor + self.fillColor = barColor.cgColor + self.shouldRoundCorners = shouldRoundCorners + + self.lineJoin = lineJoin + self.lineCap = lineCap + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func createBarPath(centre: CGPoint) -> UIBezierPath { + + let barWidthOffset: CGFloat = self.barWidth / 2 + + let origin = CGPoint(x: centre.x - barWidthOffset, y: centre.y) + let size = CGSize(width: barWidth, height: zeroYPosition - centre.y) + let rect = CGRect(origin: origin, size: size) + + let barPath: UIBezierPath = { + if shouldRoundCorners { + return UIBezierPath(roundedRect: rect, cornerRadius: barWidthOffset) + } else { + return UIBezierPath(rect: rect) + } + }() + + return barPath + } + + private func createPath () -> UIBezierPath { + + barPath.removeAllPoints() + + // We can only move forward if we can get the data we need from the delegate. + guard let + activePointsInterval = self.owner?.graphViewDrawingDelegate?.intervalForActivePoints() + else { + return barPath + } + + for i in activePointsInterval { + + var location = CGPoint.zero + + if let pointLocation = owner?.graphPoint(forIndex: i).location { + location = pointLocation + } + + let pointPath = createBarPath(centre: location) + barPath.append(pointPath) + } + + return barPath + } + + override func updatePath() { + + self.path = createPath ().cgPath + } +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/DotDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/DotDrawingLayer.swift new file mode 100644 index 0000000..9f2f4a0 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/DotDrawingLayer.swift @@ -0,0 +1,101 @@ + +import UIKit + +internal class DotDrawingLayer: ScrollableGraphViewDrawingLayer { + + private var dataPointPath = UIBezierPath() + private var dataPointSize: CGFloat = 5 + private var dataPointType: ScrollableGraphViewDataPointType = .circle + + private var customDataPointPath: ((_ centre: CGPoint) -> UIBezierPath)? + + init(frame: CGRect, fillColor: UIColor, dataPointType: ScrollableGraphViewDataPointType, dataPointSize: CGFloat, customDataPointPath: ((_ centre: CGPoint) -> UIBezierPath)? = nil) { + + self.dataPointType = dataPointType + self.dataPointSize = dataPointSize + self.customDataPointPath = customDataPointPath + + super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height) + + self.fillColor = fillColor.cgColor + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func createDataPointPath() -> UIBezierPath { + + dataPointPath.removeAllPoints() + + // We can only move forward if we can get the data we need from the delegate. + guard let + activePointsInterval = self.owner?.graphViewDrawingDelegate?.intervalForActivePoints() + else { + return dataPointPath + } + + let pointPathCreator = getPointPathCreator() + + for i in activePointsInterval { + + var location = CGPoint.zero + + if let pointLocation = owner?.graphPoint(forIndex: i).location { + location = pointLocation + } + + let pointPath = pointPathCreator(location) + dataPointPath.append(pointPath) + } + + return dataPointPath + } + + private func createCircleDataPoint(centre: CGPoint) -> UIBezierPath { + return UIBezierPath(arcCenter: centre, radius: dataPointSize, startAngle: 0, endAngle: CGFloat(2.0 * Double.pi), clockwise: true) + } + + private func createSquareDataPoint(centre: CGPoint) -> UIBezierPath { + + let squarePath = UIBezierPath() + + squarePath.move(to: centre) + + let topLeft = CGPoint(x: centre.x - dataPointSize, y: centre.y - dataPointSize) + let topRight = CGPoint(x: centre.x + dataPointSize, y: centre.y - dataPointSize) + let bottomLeft = CGPoint(x: centre.x - dataPointSize, y: centre.y + dataPointSize) + let bottomRight = CGPoint(x: centre.x + dataPointSize, y: centre.y + dataPointSize) + + squarePath.move(to: topLeft) + squarePath.addLine(to: topRight) + squarePath.addLine(to: bottomRight) + squarePath.addLine(to: bottomLeft) + squarePath.addLine(to: topLeft) + + return squarePath + } + + private func getPointPathCreator() -> (_ centre: CGPoint) -> UIBezierPath { + switch(self.dataPointType) { + case .circle: + return createCircleDataPoint + case .square: + return createSquareDataPoint + case .custom: + if let customCreator = self.customDataPointPath { + return customCreator + } + else { + // We don't have a custom path, so just return the default. + fallthrough + } + default: + return createCircleDataPoint + } + } + + override func updatePath() { + self.path = createDataPointPath().cgPath + } +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/FillDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/FillDrawingLayer.swift new file mode 100644 index 0000000..97b3c29 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/FillDrawingLayer.swift @@ -0,0 +1,24 @@ + +import UIKit + +internal class FillDrawingLayer : ScrollableGraphViewDrawingLayer { + + // Fills are only used with lineplots and we need + // to know what the line looks like. + private var lineDrawingLayer: LineDrawingLayer + + init(frame: CGRect, fillColor: UIColor, lineDrawingLayer: LineDrawingLayer) { + + self.lineDrawingLayer = lineDrawingLayer + super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height) + self.fillColor = fillColor.cgColor + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func updatePath() { + self.path = lineDrawingLayer.createLinePath().cgPath + } +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/GradientDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/GradientDrawingLayer.swift new file mode 100644 index 0000000..319fa5c --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/GradientDrawingLayer.swift @@ -0,0 +1,75 @@ + +import UIKit + +internal class GradientDrawingLayer : ScrollableGraphViewDrawingLayer { + + private var startColor: UIColor + private var endColor: UIColor + private var gradientType: ScrollableGraphViewGradientType + + // Gradient fills are only used with lineplots and we need + // to know what the line looks like. + private var lineDrawingLayer: LineDrawingLayer + + lazy private var gradientMask: CAShapeLayer = ({ + let mask = CAShapeLayer() + + mask.frame = CGRect(x: 0, y: 0, width: self.viewportWidth, height: self.viewportHeight) + mask.fillRule = CAShapeLayerFillRule.evenOdd + mask.lineJoin = self.lineJoin + + return mask + })() + + init(frame: CGRect, startColor: UIColor, endColor: UIColor, gradientType: ScrollableGraphViewGradientType, lineJoin: String = convertFromCAShapeLayerLineJoin(CAShapeLayerLineJoin.round), lineDrawingLayer: LineDrawingLayer) { + self.startColor = startColor + self.endColor = endColor + self.gradientType = gradientType + //self.lineJoin = lineJoin + + self.lineDrawingLayer = lineDrawingLayer + + super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height) + + addMaskLayer() + self.setNeedsDisplay() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func addMaskLayer() { + self.mask = gradientMask + } + + override func updatePath() { + gradientMask.path = lineDrawingLayer.createLinePath().cgPath + } + + override func draw(in ctx: CGContext) { + + let colors = [startColor.cgColor, endColor.cgColor] + let colorSpace = CGColorSpaceCreateDeviceRGB() + let locations: [CGFloat] = [0.0, 1.0] + let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations) + + let displacement = ((viewportWidth / viewportHeight) / 2.5) * self.bounds.height + let topCentre = CGPoint(x: offset + self.bounds.width / 2, y: -displacement) + let bottomCentre = CGPoint(x: offset + self.bounds.width / 2, y: self.bounds.height) + let startRadius: CGFloat = 0 + let endRadius: CGFloat = self.bounds.width + + switch(gradientType) { + case .linear: + ctx.drawLinearGradient(gradient!, start: topCentre, end: bottomCentre, options: .drawsAfterEndLocation) + case .radial: + ctx.drawRadialGradient(gradient!, startCenter: topCentre, startRadius: startRadius, endCenter: topCentre, endRadius: endRadius, options: .drawsAfterEndLocation) + } + } +} + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertFromCAShapeLayerLineJoin(_ input: CAShapeLayerLineJoin) -> String { + return input.rawValue +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/LineDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/LineDrawingLayer.swift new file mode 100644 index 0000000..373a3cb --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/LineDrawingLayer.swift @@ -0,0 +1,138 @@ + +import UIKit + +internal class LineDrawingLayer : ScrollableGraphViewDrawingLayer { + + private var currentLinePath = UIBezierPath() + + private var lineStyle: ScrollableGraphViewLineStyle + private var shouldFill: Bool + private var lineCurviness: CGFloat + + init(frame: CGRect, lineWidth: CGFloat, lineColor: UIColor, lineStyle: ScrollableGraphViewLineStyle, lineJoin: String, lineCap: String, shouldFill: Bool, lineCurviness: CGFloat) { + + self.lineStyle = lineStyle + self.shouldFill = shouldFill + self.lineCurviness = lineCurviness + + super.init(viewportWidth: frame.size.width, viewportHeight: frame.size.height) + + self.lineWidth = lineWidth + self.strokeColor = lineColor.cgColor + + self.lineJoin = convertToCAShapeLayerLineJoin(lineJoin) + self.lineCap = convertToCAShapeLayerLineCap(lineCap) + + // Setup + self.fillColor = UIColor.clear.cgColor // This is handled by the fill drawing layer. + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + internal func createLinePath() -> UIBezierPath { + + guard let owner = owner else { + return UIBezierPath() + } + + // Can't really do anything without the delegate. + guard let delegate = self.owner?.graphViewDrawingDelegate else { + return currentLinePath + } + + currentLinePath.removeAllPoints() + + let pathSegmentAdder = lineStyle == .straight ? addStraightLineSegment : addCurvedLineSegment + + let activePointsInterval = delegate.intervalForActivePoints() + + let pointPadding = delegate.paddingForPoints() + + let min = delegate.rangeForActivePoints().min + zeroYPosition = delegate.calculatePosition(atIndex: 0, value: min).y + + let viewport = delegate.currentViewport() + let viewportWidth = viewport.width + let viewportHeight = viewport.height + + // Connect the line to the starting edge if we are filling it. + if(shouldFill) { + // Add a line from the base of the graph to the first data point. + let firstDataPoint = owner.graphPoint(forIndex: activePointsInterval.lowerBound) + + let viewportLeftZero = CGPoint(x: firstDataPoint.location.x - (pointPadding.leftmostPointPadding), y: zeroYPosition) + let leftFarEdgeTop = CGPoint(x: firstDataPoint.location.x - (pointPadding.leftmostPointPadding + viewportWidth), y: zeroYPosition) + let leftFarEdgeBottom = CGPoint(x: firstDataPoint.location.x - (pointPadding.leftmostPointPadding + viewportWidth), y: viewportHeight) + + currentLinePath.move(to: leftFarEdgeBottom) + pathSegmentAdder(leftFarEdgeBottom, leftFarEdgeTop, currentLinePath) + pathSegmentAdder(leftFarEdgeTop, viewportLeftZero, currentLinePath) + pathSegmentAdder(viewportLeftZero, CGPoint(x: firstDataPoint.location.x, y: firstDataPoint.location.y), currentLinePath) + } + else { + let firstDataPoint = owner.graphPoint(forIndex: activePointsInterval.lowerBound) + currentLinePath.move(to: firstDataPoint.location) + } + + // Connect each point on the graph with a segment. + for i in activePointsInterval.lowerBound ..< activePointsInterval.upperBound - 1 { + + let startPoint = owner.graphPoint(forIndex: i).location + let endPoint = owner.graphPoint(forIndex: i+1).location + + pathSegmentAdder(startPoint, endPoint, currentLinePath) + } + + // Connect the line to the ending edge if we are filling it. + if(shouldFill) { + // Add a line from the last data point to the base of the graph. + let lastDataPoint = owner.graphPoint(forIndex: activePointsInterval.upperBound - 1).location + + let viewportRightZero = CGPoint(x: lastDataPoint.x + (pointPadding.rightmostPointPadding), y: zeroYPosition) + let rightFarEdgeTop = CGPoint(x: lastDataPoint.x + (pointPadding.rightmostPointPadding + viewportWidth), y: zeroYPosition) + let rightFarEdgeBottom = CGPoint(x: lastDataPoint.x + (pointPadding.rightmostPointPadding + viewportWidth), y: viewportHeight) + + pathSegmentAdder(lastDataPoint, viewportRightZero, currentLinePath) + pathSegmentAdder(viewportRightZero, rightFarEdgeTop, currentLinePath) + pathSegmentAdder(rightFarEdgeTop, rightFarEdgeBottom, currentLinePath) + } + + return currentLinePath + } + + private func addStraightLineSegment(startPoint: CGPoint, endPoint: CGPoint, inPath path: UIBezierPath) { + path.addLine(to: endPoint) + } + + private func addCurvedLineSegment(startPoint: CGPoint, endPoint: CGPoint, inPath path: UIBezierPath) { + // calculate control points + let difference = endPoint.x - startPoint.x + + var x = startPoint.x + (difference * lineCurviness) + var y = startPoint.y + let controlPointOne = CGPoint(x: x, y: y) + + x = endPoint.x - (difference * lineCurviness) + y = endPoint.y + let controlPointTwo = CGPoint(x: x, y: y) + + // add curve from start to end + currentLinePath.addCurve(to: endPoint, controlPoint1: controlPointOne, controlPoint2: controlPointTwo) + } + + override func updatePath() { + self.path = createLinePath().cgPath + } +} + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertToCAShapeLayerLineJoin(_ input: String) -> CAShapeLayerLineJoin { + return CAShapeLayerLineJoin(rawValue: input) +} + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertToCAShapeLayerLineCap(_ input: String) -> CAShapeLayerLineCap { + return CAShapeLayerLineCap(rawValue: input) +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/ReferenceLineDrawingView.swift b/Pods/ScrollableGraphView/Classes/Drawing/ReferenceLineDrawingView.swift new file mode 100644 index 0000000..827ebad --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/ReferenceLineDrawingView.swift @@ -0,0 +1,329 @@ + +import UIKit + +internal class ReferenceLineDrawingView : UIView { + + var settings: ReferenceLines = ReferenceLines() + + // PRIVATE PROPERTIES + // ################## + + private var labelMargin: CGFloat = 4 + private var leftLabelInset: CGFloat = 10 + private var rightLabelInset: CGFloat = 10 + + // Store information about the ScrollableGraphView + private var currentRange: (min: Double, max: Double) = (0,100) + private var topMargin: CGFloat = 10 + private var bottomMargin: CGFloat = 10 + + private var lineWidth: CGFloat { + get { + return self.bounds.width + } + } + + private var units: String { + get { + if let units = self.settings.referenceLineUnits { + return " \(units)" + } else { + return "" + } + } + } + + // Layers + private var labels = [UILabel]() + private let referenceLineLayer = CAShapeLayer() + private let referenceLinePath = UIBezierPath() + + init(frame: CGRect, topMargin: CGFloat, bottomMargin: CGFloat, referenceLineColor: UIColor, referenceLineThickness: CGFloat, referenceLineSettings: ReferenceLines) { + super.init(frame: frame) + + self.topMargin = topMargin + self.bottomMargin = bottomMargin + + // The reference line layer draws the reference lines and we handle the labels elsewhere. + self.referenceLineLayer.frame = self.frame + self.referenceLineLayer.strokeColor = referenceLineColor.cgColor + self.referenceLineLayer.lineWidth = referenceLineThickness + + self.settings = referenceLineSettings + + self.layer.addSublayer(referenceLineLayer) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func createLabel(at position: CGPoint, withText text: String) -> UILabel { + let frame = CGRect(x: position.x, y: position.y, width: 0, height: 0) + let label = UILabel(frame: frame) + + return label + } + + private func createReferenceLinesPath() -> UIBezierPath { + + referenceLinePath.removeAllPoints() + for label in labels { + label.removeFromSuperview() + } + labels.removeAll() + + if(self.settings.includeMinMax) { + let maxLineStart = CGPoint(x: 0, y: topMargin) + let maxLineEnd = CGPoint(x: lineWidth, y: topMargin) + + let minLineStart = CGPoint(x: 0, y: self.bounds.height - bottomMargin) + let minLineEnd = CGPoint(x: lineWidth, y: self.bounds.height - bottomMargin) + + let numberFormatter = referenceNumberFormatter() + + let maxString = numberFormatter.string(from: self.currentRange.max as NSNumber)! + units + let minString = numberFormatter.string(from: self.currentRange.min as NSNumber)! + units + + addLine(withTag: maxString, from: maxLineStart, to: maxLineEnd, in: referenceLinePath) + addLine(withTag: minString, from: minLineStart, to: minLineEnd, in: referenceLinePath) + } + + let initialRect = CGRect(x: self.bounds.origin.x, y: self.bounds.origin.y + topMargin, width: self.bounds.size.width, height: self.bounds.size.height - (topMargin + bottomMargin)) + + switch(settings.positionType) { + case .relative: + createReferenceLines(in: initialRect, atRelativePositions: self.settings.relativePositions, forPath: referenceLinePath) + case .absolute: + createReferenceLines(in: initialRect, atAbsolutePositions: self.settings.absolutePositions, forPath: referenceLinePath) + } + + return referenceLinePath + } + + private func referenceNumberFormatter() -> NumberFormatter { + let numberFormatter = NumberFormatter() + numberFormatter.numberStyle = self.settings.referenceLineNumberStyle + numberFormatter.minimumFractionDigits = self.settings.referenceLineNumberOfDecimalPlaces + numberFormatter.maximumFractionDigits = self.settings.referenceLineNumberOfDecimalPlaces + + return numberFormatter + } + + private func createReferenceLines(in rect: CGRect, atRelativePositions relativePositions: [Double], forPath path: UIBezierPath) { + + let height = rect.size.height + var relativePositions = relativePositions + + // If we are including the min and max already need to make sure we don't redraw them. + if(self.settings.includeMinMax) { + relativePositions = relativePositions.filter({ (x:Double) -> Bool in + return (x != 0 && x != 1) + }) + } + + for relativePosition in relativePositions { + + let yPosition = height * CGFloat(1 - relativePosition) + + let lineStart = CGPoint(x: 0, y: rect.origin.y + yPosition) + let lineEnd = CGPoint(x: lineStart.x + lineWidth, y: lineStart.y) + + createReferenceLineFrom(from: lineStart, to: lineEnd, in: path) + } + } + + private func createReferenceLines(in rect: CGRect, atAbsolutePositions absolutePositions: [Double], forPath path: UIBezierPath) { + + for absolutePosition in absolutePositions { + + let yPosition = calculateYPositionForYAxisValue(value: absolutePosition) + + // don't need to add rect.origin.y to yPosition like we do for relativePositions, + // as we calculate the position for the y axis value in the previous line, + // this already takes into account margins, etc. + let lineStart = CGPoint(x: 0, y: yPosition) + let lineEnd = CGPoint(x: lineStart.x + lineWidth, y: lineStart.y) + + createReferenceLineFrom(from: lineStart, to: lineEnd, in: path) + } + } + + private func createReferenceLineFrom(from lineStart: CGPoint, to lineEnd: CGPoint, in path: UIBezierPath) { + if(self.settings.shouldAddLabelsToIntermediateReferenceLines) { + + let value = calculateYAxisValue(for: lineStart) + let numberFormatter = referenceNumberFormatter() + var valueString = numberFormatter.string(from: value as NSNumber)! + + if(self.settings.shouldAddUnitsToIntermediateReferenceLineLabels) { + valueString += " \(units)" + } + + addLine(withTag: valueString, from: lineStart, to: lineEnd, in: path) + + } else { + addLine(from: lineStart, to: lineEnd, in: path) + } + } + + private func addLine(withTag tag: String, from: CGPoint, to: CGPoint, in path: UIBezierPath) { + + let boundingSize = self.boundingSize(forText: tag) + let leftLabel = createLabel(withText: tag) + let rightLabel = createLabel(withText: tag) + + // Left label gap. + leftLabel.frame = CGRect( + origin: CGPoint(x: from.x + leftLabelInset, y: from.y - (boundingSize.height / 2)), + size: boundingSize) + + let leftLabelStart = CGPoint(x: leftLabel.frame.origin.x - labelMargin, y: to.y) + let leftLabelEnd = CGPoint(x: (leftLabel.frame.origin.x + leftLabel.frame.size.width) + labelMargin, y: to.y) + + // Right label gap. + rightLabel.frame = CGRect( + origin: CGPoint(x: (from.x + self.frame.width) - rightLabelInset - boundingSize.width, y: from.y - (boundingSize.height / 2)), + size: boundingSize) + + let rightLabelStart = CGPoint(x: rightLabel.frame.origin.x - labelMargin, y: to.y) + let rightLabelEnd = CGPoint(x: (rightLabel.frame.origin.x + rightLabel.frame.size.width) + labelMargin, y: to.y) + + // Add the lines and tags depending on the settings for where we want them. + var gaps = [(start: CGFloat, end: CGFloat)]() + + switch(self.settings.referenceLinePosition) { + + case .left: + gaps.append((start: leftLabelStart.x, end: leftLabelEnd.x)) + self.addSubview(leftLabel) + self.labels.append(leftLabel) + + case .right: + gaps.append((start: rightLabelStart.x, end: rightLabelEnd.x)) + self.addSubview(rightLabel) + self.labels.append(rightLabel) + + case .both: + gaps.append((start: leftLabelStart.x, end: leftLabelEnd.x)) + gaps.append((start: rightLabelStart.x, end: rightLabelEnd.x)) + self.addSubview(leftLabel) + self.addSubview(rightLabel) + self.labels.append(leftLabel) + self.labels.append(rightLabel) + } + + addLine(from: from, to: to, withGaps: gaps, in: path) + } + + private func addLine(from: CGPoint, to: CGPoint, withGaps gaps: [(start: CGFloat, end: CGFloat)], in path: UIBezierPath) { + + // If there are no gaps, just add a single line. + if(gaps.count <= 0) { + addLine(from: from, to: to, in: path) + } + // If there is only 1 gap, it's just two lines. + else if (gaps.count == 1) { + + let gapLeft = CGPoint(x: gaps.first!.start, y: from.y) + let gapRight = CGPoint(x: gaps.first!.end, y: from.y) + + addLine(from: from, to: gapLeft, in: path) + addLine(from: gapRight, to: to, in: path) + } + // If there are many gaps, we have a series of intermediate lines. + else { + + let firstGap = gaps.first! + let lastGap = gaps.last! + + let firstGapLeft = CGPoint(x: firstGap.start, y: from.y) + let lastGapRight = CGPoint(x: lastGap.end, y: to.y) + + // Add the first line to the start of the first gap + addLine(from: from, to: firstGapLeft, in: path) + + // Add lines between all intermediate gaps + for i in 0 ..< gaps.count - 1 { + + let startGapEnd = gaps[i].end + let endGapStart = gaps[i + 1].start + + let lineStart = CGPoint(x: startGapEnd, y: from.y) + let lineEnd = CGPoint(x: endGapStart, y: from.y) + + addLine(from: lineStart, to: lineEnd, in: path) + } + + // Add the final line to the end + addLine(from: lastGapRight, to: to, in: path) + } + } + + private func addLine(from: CGPoint, to: CGPoint, in path: UIBezierPath) { + path.move(to: from) + path.addLine(to: to) + } + + private func boundingSize(forText text: String) -> CGSize { + return (text as NSString).size(withAttributes: + [NSAttributedString.Key.font:self.settings.referenceLineLabelFont]) + } + + private func calculateYAxisValue(for point: CGPoint) -> Double { + + let graphHeight = self.frame.size.height - (topMargin + bottomMargin) + + // value = the corresponding value on the graph for any y co-ordinate in the view + // y - t y = the y co-ordinate in the view for which we want to know the corresponding value on the graph + // value = --------- * (min - max) + max t = the top margin + // h h = the height of the graph space without margins + // min = the range's current mininum + // max = the range's current maximum + + var value = (((point.y - topMargin) / (graphHeight)) * CGFloat((self.currentRange.min - self.currentRange.max))) + CGFloat(self.currentRange.max) + + // Sometimes results in "negative zero" + if(value == 0) { + value = 0 + } + + return Double(value) + } + + private func calculateYPositionForYAxisValue(value: Double) -> CGFloat { + + // Just an algebraic re-arrangement of calculateYAxisValue + let graphHeight = self.frame.size.height - (topMargin + bottomMargin) + var y = ((CGFloat(value - self.currentRange.max) / CGFloat(self.currentRange.min - self.currentRange.max)) * graphHeight) + topMargin + + if (y == 0) { + y = 0 + } + + return y + } + + private func createLabel(withText text: String) -> UILabel { + let label = UILabel() + + label.text = text + label.textColor = self.settings.referenceLineLabelColor + label.font = self.settings.referenceLineLabelFont + + return label + } + + // Public functions to update the reference lines with any changes to the range and viewport (phone rotation, etc). + // When the range changes, need to update the max for the new range, then update all the labels that are showing for the axis and redraw the reference lines. + func set(range: (min: Double, max: Double)) { + self.currentRange = range + self.referenceLineLayer.path = createReferenceLinesPath().cgPath + } + + func set(viewportWidth: CGFloat, viewportHeight: CGFloat) { + self.frame.size.width = viewportWidth + self.frame.size.height = viewportHeight + self.referenceLineLayer.path = createReferenceLinesPath().cgPath + } +} diff --git a/Pods/ScrollableGraphView/Classes/Drawing/ScrollableGraphViewDrawingLayer.swift b/Pods/ScrollableGraphView/Classes/Drawing/ScrollableGraphViewDrawingLayer.swift new file mode 100644 index 0000000..864e346 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Drawing/ScrollableGraphViewDrawingLayer.swift @@ -0,0 +1,49 @@ + +import UIKit + +internal class ScrollableGraphViewDrawingLayer : CAShapeLayer { + + var offset: CGFloat = 0 { + didSet { + offsetDidChange() + } + } + + var viewportWidth: CGFloat = 0 + var viewportHeight: CGFloat = 0 + var zeroYPosition: CGFloat = 0 + + weak var owner: Plot? + + var active = true + + init(viewportWidth: CGFloat, viewportHeight: CGFloat, offset: CGFloat = 0) { + super.init() + + self.viewportWidth = viewportWidth + self.viewportHeight = viewportHeight + + self.frame = CGRect(origin: CGPoint(x: offset, y: 0), size: CGSize(width: self.viewportWidth, height: self.viewportHeight)) + + setup() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setup() { + // Get rid of any animations. + self.actions = ["position" : NSNull(), "bounds" : NSNull()] + } + + private func offsetDidChange() { + self.frame.origin.x = offset + self.bounds.origin.x = offset + } + + func updatePath() { + fatalError("updatePath needs to be implemented by the subclass") + } +} + diff --git a/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPoint.swift b/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPoint.swift new file mode 100644 index 0000000..88812dd --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPoint.swift @@ -0,0 +1,30 @@ +import UIKit + +internal class GraphPoint { + + var location = CGPoint(x: 0, y: 0) + var currentlyAnimatingToPosition = false + + var x: CGFloat { + get { + return location.x + } + set { + location.x = newValue + } + } + + var y: CGFloat { + get { + return location.y + } + set { + location.y = newValue + } + } + + init(position: CGPoint = CGPoint.zero) { + x = position.x + y = position.y + } +} diff --git a/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPointAnimation.swift b/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPointAnimation.swift new file mode 100644 index 0000000..40dd7a5 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/Animation/GraphPointAnimation.swift @@ -0,0 +1,86 @@ +import UIKit + +internal class GraphPointAnimation : Equatable { + + // Public Properties + var animationEasing = Easings.easeOutQuad + var duration: Double = 1 + var delay: Double = 0 + private(set) var finished = false + private(set) var animationKey: String + + // Private State + private var startingPoint: CGPoint + private var endingPoint: CGPoint + + private var elapsedTime: Double = 0 + private var graphPoint: GraphPoint? + private var multiplier: Double = 1 + + static private var animationsCreated = 0 + + init(fromPoint: CGPoint, toPoint: CGPoint, forGraphPoint graphPoint: GraphPoint, forKey key: String = "animation\(animationsCreated)") { + self.startingPoint = fromPoint + self.endingPoint = toPoint + self.animationKey = key + self.graphPoint = graphPoint + self.graphPoint?.currentlyAnimatingToPosition = true + + GraphPointAnimation.animationsCreated += 1 + } + + func update(withTimestamp dt: Double) { + + if(!finished) { + + if elapsedTime > delay { + + let animationElapsedTime = elapsedTime - delay + + let changeInX = endingPoint.x - startingPoint.x + let changeInY = endingPoint.y - startingPoint.y + + // t is in the range of 0 to 1, indicates how far through the animation it is. + let t = animationElapsedTime / duration + let interpolation = animationEasing(t) + + let x = startingPoint.x + changeInX * CGFloat(interpolation) + let y = startingPoint.y + changeInY * CGFloat(interpolation) + + if(animationElapsedTime >= duration) { + animationDidFinish() + } + + graphPoint?.x = CGFloat(x) + graphPoint?.y = CGFloat(y) + + elapsedTime += dt * multiplier + } + // Keep going until we are passed the delay + else { + elapsedTime += dt * multiplier + } + } + } + + func animationDidFinish() { + self.graphPoint?.currentlyAnimatingToPosition = false + self.finished = true + } + + static func ==(lhs: GraphPointAnimation, rhs: GraphPointAnimation) -> Bool { + return lhs.animationKey == rhs.animationKey + } +} + +// Simplified easing functions from: http://www.joshondesign.com/2013/03/01/improvedEasingEquations +internal struct Easings { + + static let easeInQuad = { (t:Double) -> Double in return t*t; } + static let easeOutQuad = { (t:Double) -> Double in return 1 - Easings.easeInQuad(1-t); } + + static let easeOutElastic = { (t: Double) -> Double in + var p = 0.3; + return pow(2,-10*t) * sin((t-p/4)*(2*Double.pi)/p) + 1; + } +} diff --git a/Pods/ScrollableGraphView/Classes/Plots/BarPlot.swift b/Pods/ScrollableGraphView/Classes/Plots/BarPlot.swift new file mode 100644 index 0000000..708cf61 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/BarPlot.swift @@ -0,0 +1,46 @@ + +import UIKit + +open class BarPlot : Plot { + + // Customisation + // ############# + + /// The width of an individual bar on the graph. + open var barWidth: CGFloat = 25; + /// The actual colour of the bar. + open var barColor: UIColor = UIColor.gray + /// The width of the outline of the bar + open var barLineWidth: CGFloat = 1 + /// The colour of the bar outline + open var barLineColor: UIColor = UIColor.darkGray + /// Whether the bars should be drawn with rounded corners + open var shouldRoundBarCorners: Bool = false + + // Private State + // ############# + + private var barLayer: BarDrawingLayer? + + public init(identifier: String) { + super.init() + self.identifier = identifier + } + + override func layers(forViewport viewport: CGRect) -> [ScrollableGraphViewDrawingLayer?] { + createLayers(viewport: viewport) + return [barLayer] + } + + private func createLayers(viewport: CGRect) { + barLayer = BarDrawingLayer( + frame: viewport, + barWidth: barWidth, + barColor: barColor, + barLineWidth: barLineWidth, + barLineColor: barLineColor, + shouldRoundCorners: shouldRoundBarCorners) + + barLayer?.owner = self + } +} diff --git a/Pods/ScrollableGraphView/Classes/Plots/DotPlot.swift b/Pods/ScrollableGraphView/Classes/Plots/DotPlot.swift new file mode 100644 index 0000000..b781c10 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/DotPlot.swift @@ -0,0 +1,49 @@ + +import UIKit + +open class DotPlot : Plot { + + // Customisation + // ############# + + /// The shape to draw for each data point. + open var dataPointType = ScrollableGraphViewDataPointType.circle + /// The size of the shape to draw for each data point. + open var dataPointSize: CGFloat = 5 + /// The colour with which to fill the shape. + open var dataPointFillColor: UIColor = UIColor.black + /// If dataPointType is set to .Custom then you,can provide a closure to create any kind of shape you would like to be displayed instead of just a circle or square. The closure takes a CGPoint which is the centre of the shape and it should return a complete UIBezierPath. + open var customDataPointPath: ((_ centre: CGPoint) -> UIBezierPath)? + + // Private State + // ############# + + private var dataPointLayer: DotDrawingLayer? + + public init(identifier: String) { + super.init() + self.identifier = identifier + } + + override func layers(forViewport viewport: CGRect) -> [ScrollableGraphViewDrawingLayer?] { + createLayers(viewport: viewport) + return [dataPointLayer] + } + + private func createLayers(viewport: CGRect) { + dataPointLayer = DotDrawingLayer( + frame: viewport, + fillColor: dataPointFillColor, + dataPointType: dataPointType, + dataPointSize: dataPointSize, + customDataPointPath: customDataPointPath) + + dataPointLayer?.owner = self + } +} + +@objc public enum ScrollableGraphViewDataPointType : Int { + case circle + case square + case custom +} diff --git a/Pods/ScrollableGraphView/Classes/Plots/LinePlot.swift b/Pods/ScrollableGraphView/Classes/Plots/LinePlot.swift new file mode 100644 index 0000000..6a2cd30 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/LinePlot.swift @@ -0,0 +1,143 @@ + +import UIKit + +open class LinePlot : Plot { + + // Public settings for the LinePlot + // ################################ + + /// Specifies how thick the graph of the line is. In points. + open var lineWidth: CGFloat = 2 + + /// The color of the graph line. UIColor. + open var lineColor: UIColor = UIColor.black + + /// Whether the line is straight or curved. + open var lineStyle_: Int { + get { return lineStyle.rawValue } + set { + if let enumValue = ScrollableGraphViewLineStyle(rawValue: newValue) { + lineStyle = enumValue + } + } + } + + /// Whether or not the line should be rendered using bezier curves are straight lines. + open var lineStyle = ScrollableGraphViewLineStyle.straight + + /// How each segment in the line should connect. Takes any of the Core Animation LineJoin values. + open var lineJoin: String = convertFromCAShapeLayerLineJoin(CAShapeLayerLineJoin.round) + + /// The line caps. Takes any of the Core Animation LineCap values. + open var lineCap: String = convertFromCAShapeLayerLineCap(CAShapeLayerLineCap.round) + open var lineCurviness: CGFloat = 0.5 + + + // Fill Settings + // ############# + + /// Specifies whether or not the plotted graph should be filled with a colour or gradient. + open var shouldFill: Bool = false + + var fillType_: Int { + get { return fillType.rawValue } + set { + if let enumValue = ScrollableGraphViewFillType(rawValue: newValue) { + fillType = enumValue + } + } + } + + /// Specifies whether to fill the graph with a solid colour or gradient. + open var fillType = ScrollableGraphViewFillType.solid + + /// If fillType is set to .Solid then this colour will be used to fill the graph. + open var fillColor: UIColor = UIColor.black + + /// If fillType is set to .Gradient then this will be the starting colour for the gradient. + open var fillGradientStartColor: UIColor = UIColor.white + + /// If fillType is set to .Gradient, then this will be the ending colour for the gradient. + open var fillGradientEndColor: UIColor = UIColor.black + + open var fillGradientType_: Int { + get { return fillGradientType.rawValue } + set { + if let enumValue = ScrollableGraphViewGradientType(rawValue: newValue) { + fillGradientType = enumValue + } + } + } + + /// If fillType is set to .Gradient, then this defines whether the gradient is rendered as a linear gradient or radial gradient. + open var fillGradientType = ScrollableGraphViewGradientType.linear + + // Private State + // ############# + + private var lineLayer: LineDrawingLayer? + private var fillLayer: FillDrawingLayer? + private var gradientLayer: GradientDrawingLayer? + + public init(identifier: String) { + super.init() + self.identifier = identifier + } + + override func layers(forViewport viewport: CGRect) -> [ScrollableGraphViewDrawingLayer?] { + createLayers(viewport: viewport) + return [lineLayer, fillLayer, gradientLayer] + } + + private func createLayers(viewport: CGRect) { + + // Create the line drawing layer. + lineLayer = LineDrawingLayer(frame: viewport, lineWidth: lineWidth, lineColor: lineColor, lineStyle: lineStyle, lineJoin: lineJoin, lineCap: lineCap, shouldFill: shouldFill, lineCurviness: lineCurviness) + + // Depending on whether we want to fill with solid or gradient, create the layer accordingly. + + // Gradient and Fills + switch (self.fillType) { + + case .solid: + if(shouldFill) { + // Setup fill + fillLayer = FillDrawingLayer(frame: viewport, fillColor: fillColor, lineDrawingLayer: lineLayer!) + } + + case .gradient: + if(shouldFill) { + gradientLayer = GradientDrawingLayer(frame: viewport, startColor: fillGradientStartColor, endColor: fillGradientEndColor, gradientType: fillGradientType, lineDrawingLayer: lineLayer!) + } + } + + lineLayer?.owner = self + fillLayer?.owner = self + gradientLayer?.owner = self + } +} + +@objc public enum ScrollableGraphViewLineStyle : Int { + case straight + case smooth +} + +@objc public enum ScrollableGraphViewFillType : Int { + case solid + case gradient +} + +@objc public enum ScrollableGraphViewGradientType : Int { + case linear + case radial +} + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertFromCAShapeLayerLineJoin(_ input: CAShapeLayerLineJoin) -> String { + return input.rawValue +} + +// Helper function inserted by Swift 4.2 migrator. +fileprivate func convertFromCAShapeLayerLineCap(_ input: CAShapeLayerLineCap) -> String { + return input.rawValue +} diff --git a/Pods/ScrollableGraphView/Classes/Plots/Plot.swift b/Pods/ScrollableGraphView/Classes/Plots/Plot.swift new file mode 100644 index 0000000..580bbe8 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Plots/Plot.swift @@ -0,0 +1,247 @@ + +import UIKit + +open class Plot { + + // The id for this plot. Used when determining which data to give it in the dataSource + open var identifier: String! + + weak var graphViewDrawingDelegate: ScrollableGraphViewDrawingDelegate! = nil + + // Animation Settings + // ################## + + /// How long the animation should take. Affects both the startup animation and the animation when the range of the y-axis adapts to onscreen points. + open var animationDuration: Double = 1.5 + + open var adaptAnimationType_: Int { + get { return adaptAnimationType.rawValue } + set { + if let enumValue = ScrollableGraphViewAnimationType(rawValue: newValue) { + adaptAnimationType = enumValue + } + } + } + /// The animation style. + open var adaptAnimationType = ScrollableGraphViewAnimationType.easeOut + /// If adaptAnimationType is set to .Custom, then this is the easing function you would like applied for the animation. + open var customAnimationEasingFunction: ((_ t: Double) -> Double)? + + // Private Animation State + // ####################### + + private var currentAnimations = [GraphPointAnimation]() + private var displayLink: CADisplayLink! + private var previousTimestamp: CFTimeInterval = 0 + private var currentTimestamp: CFTimeInterval = 0 + + private var graphPoints = [GraphPoint]() + + deinit { + displayLink?.invalidate() + } + + // MARK: Different plot types should implement: + // ############################################ + + func layers(forViewport viewport: CGRect) -> [ScrollableGraphViewDrawingLayer?] { + return [] + } + + // MARK: Plot Animation + // #################### + + // Animation update loop for co-domain changes. + @objc private func animationUpdate() { + let dt = timeSinceLastFrame() + + for animation in currentAnimations { + + animation.update(withTimestamp: dt) + + if animation.finished { + dequeue(animation: animation) + } + } + + graphViewDrawingDelegate.updatePaths() + } + + private func animate(point: GraphPoint, to position: CGPoint, withDelay delay: Double = 0) { + let currentPoint = CGPoint(x: point.x, y: point.y) + let animation = GraphPointAnimation(fromPoint: currentPoint, toPoint: position, forGraphPoint: point) + animation.animationEasing = getAnimationEasing() + animation.duration = animationDuration + animation.delay = delay + enqueue(animation: animation) + } + + private func getAnimationEasing() -> (Double) -> Double { + switch(self.adaptAnimationType) { + case .elastic: + return Easings.easeOutElastic + case .easeOut: + return Easings.easeOutQuad + case .custom: + if let customEasing = customAnimationEasingFunction { + return customEasing + } + else { + fallthrough + } + default: + return Easings.easeOutQuad + } + } + + private func enqueue(animation: GraphPointAnimation) { + if (currentAnimations.count == 0) { + // Need to kick off the loop. + displayLink.isPaused = false + } + currentAnimations.append(animation) + } + + private func dequeue(animation: GraphPointAnimation) { + if let index = currentAnimations.index(of: animation) { + currentAnimations.remove(at: index) + } + + if(currentAnimations.count == 0) { + // Stop animation loop. + displayLink.isPaused = true + } + } + + internal func dequeueAllAnimations() { + + for animation in currentAnimations { + animation.animationDidFinish() + } + + currentAnimations.removeAll() + displayLink.isPaused = true + } + + private func timeSinceLastFrame() -> Double { + if previousTimestamp == 0 { + previousTimestamp = displayLink.timestamp + } else { + previousTimestamp = currentTimestamp + } + + currentTimestamp = displayLink.timestamp + + var dt = currentTimestamp - previousTimestamp + + if dt > 0.032 { + dt = 0.032 + } + + return dt + } + + internal func startAnimations(forPoints pointsToAnimate: CountableRange, withData data: [Double], withStaggerValue stagger: Double) { + + animatePlotPointPositions(forPoints: pointsToAnimate, withData: data, withDelay: stagger) + } + + internal func createPlotPoints(numberOfPoints: Int, range: (min: Double, max: Double)) { + for i in 0 ..< numberOfPoints { + + let value = range.min + + let position = graphViewDrawingDelegate.calculatePosition(atIndex: i, value: value) + let point = GraphPoint(position: position) + graphPoints.append(point) + } + } + + // When active interval changes, need to set the position for any NEWLY ACTIVATED points, otherwise + // they will come on screen at the incorrect position. + // Needs to be called when the active interval has changed and during initial setup. + internal func setPlotPointPositions(forNewlyActivatedPoints newPoints: CountableRange, withData data: [Double]) { + + for i in newPoints.startIndex ..< newPoints.endIndex { + // e.g. + // indices: 10...20 + // data positions: 0...10 = // 0 to (end - start) + let dataPosition = i - newPoints.startIndex + + let value = data[dataPosition] + + let newPosition = graphViewDrawingDelegate.calculatePosition(atIndex: i, value: value) + graphPoints[i].x = newPosition.x + graphPoints[i].y = newPosition.y + } + } + + // Same as a above, but can take an array with the indicies of the activated points rather than a range. + internal func setPlotPointPositions(forNewlyActivatedPoints activatedPoints: [Int], withData data: [Double]) { + + var index = 0 + for activatedPointIndex in activatedPoints { + + let dataPosition = index + let value = data[dataPosition] + + let newPosition = graphViewDrawingDelegate.calculatePosition(atIndex: activatedPointIndex, value: value) + graphPoints[activatedPointIndex].x = newPosition.x + graphPoints[activatedPointIndex].y = newPosition.y + + index += 1 + } + } + + // When the range changes, we need to set the position for any VISIBLE points, either animating or setting directly + // depending on the settings. + // Needs to be called when the range has changed. + internal func animatePlotPointPositions(forPoints pointsToAnimate: CountableRange, withData data: [Double], withDelay delay: Double) { + // For any visible points, kickoff the animation to their new position after the axis' min/max has changed. + var dataIndex = 0 + for pointIndex in pointsToAnimate { + let newPosition = graphViewDrawingDelegate.calculatePosition(atIndex: pointIndex, value: data[dataIndex]) + let point = graphPoints[pointIndex] + animate(point: point, to: newPosition, withDelay: Double(dataIndex) * delay) + dataIndex += 1 + } + } + + internal func setup() { + displayLink = CADisplayLink(target: self, selector: #selector(animationUpdate)) + displayLink.add(to: RunLoop.main, forMode: RunLoop.Mode.common) + displayLink.isPaused = true + } + + internal func reset() { + currentAnimations.removeAll() + graphPoints.removeAll() + displayLink?.invalidate() + previousTimestamp = 0 + currentTimestamp = 0 + } + + internal func invalidate() { + currentAnimations.removeAll() + graphPoints.removeAll() + displayLink?.invalidate() + } + + internal func graphPoint(forIndex index: Int) -> GraphPoint { + return graphPoints[index] + } +} + +@objc public enum ScrollableGraphViewAnimationType : Int { + case easeOut + case elastic + case custom +} + + + + + + + + diff --git a/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDataSource.swift b/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDataSource.swift new file mode 100644 index 0000000..3c778e1 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDataSource.swift @@ -0,0 +1,8 @@ + +import UIKit + +public protocol ScrollableGraphViewDataSource : class { + func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double + func label(atIndex pointIndex: Int) -> String + func numberOfPoints() -> Int // This now forces the same number of points in each plot. +} diff --git a/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDrawingDelegate.swift b/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDrawingDelegate.swift new file mode 100644 index 0000000..91d8584 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Protocols/ScrollableGraphViewDrawingDelegate.swift @@ -0,0 +1,12 @@ + +import UIKit + +// Delegate definition that provides the data required by the drawing layers. +internal protocol ScrollableGraphViewDrawingDelegate : class { + func intervalForActivePoints() -> CountableRange + func rangeForActivePoints() -> (min: Double, max: Double) + func paddingForPoints() -> (leftmostPointPadding: CGFloat, rightmostPointPadding: CGFloat) + func calculatePosition(atIndex index: Int, value: Double) -> CGPoint + func currentViewport() -> CGRect + func updatePaths() +} diff --git a/Pods/ScrollableGraphView/Classes/Reference/LabelPool.swift b/Pods/ScrollableGraphView/Classes/Reference/LabelPool.swift new file mode 100644 index 0000000..9dde79c --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Reference/LabelPool.swift @@ -0,0 +1,53 @@ + +import UIKit + +internal class LabelPool { + + var labels = [UILabel]() + var relations = [Int : Int]() + var unused = [Int]() + + func deactivateLabel(forPointIndex pointIndex: Int){ + + if let unusedLabelIndex = relations[pointIndex] { + unused.append(unusedLabelIndex) + } + relations[pointIndex] = nil + } + + @discardableResult + func activateLabel(forPointIndex pointIndex: Int) -> UILabel { + var label: UILabel + + if(unused.count >= 1) { + let unusedLabelIndex = unused.first! + unused.removeFirst() + + label = labels[unusedLabelIndex] + relations[pointIndex] = unusedLabelIndex + } + else { + label = UILabel() + labels.append(label) + let newLabelIndex = labels.index(of: label)! + relations[pointIndex] = newLabelIndex + } + + return label + } + + var activeLabels: [UILabel] { + get { + + var currentlyActive = [UILabel]() + let numberOfLabels = labels.count + + for i in 0 ..< numberOfLabels { + if(!unused.contains(i)) { + currentlyActive.append(labels[i]) + } + } + return currentlyActive + } + } +} diff --git a/Pods/ScrollableGraphView/Classes/Reference/ReferenceLines.swift b/Pods/ScrollableGraphView/Classes/Reference/ReferenceLines.swift new file mode 100644 index 0000000..38f12aa --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/Reference/ReferenceLines.swift @@ -0,0 +1,90 @@ + +import UIKit + +// Currently just a simple data structure to hold the settings for the reference lines. +open class ReferenceLines { + + // Reference Lines + // ############### + + /// Whether or not to show the y-axis reference lines and labels. + @IBInspectable open var shouldShowReferenceLines: Bool = true + /// The colour for the reference lines. + @IBInspectable open var referenceLineColor: UIColor = UIColor.black + /// The thickness of the reference lines. + @IBInspectable open var referenceLineThickness: CGFloat = 0.5 + + @IBInspectable var referenceLinePosition_: Int { + get { return referenceLinePosition.rawValue } + set { + if let enumValue = ScrollableGraphViewReferenceLinePosition(rawValue: newValue) { + referenceLinePosition = enumValue + } + } + } + /// Where the labels should be displayed on the reference lines. + open var referenceLinePosition = ScrollableGraphViewReferenceLinePosition.left + + @IBInspectable open var positionType = ReferenceLinePositioningType.relative + @IBInspectable open var relativePositions: [Double] = [0.25, 0.5, 0.75] + @IBInspectable open var absolutePositions: [Double] = [25, 50, 75] + @IBInspectable open var includeMinMax: Bool = true + + /// Whether or not to add labels to the intermediate reference lines. + @IBInspectable open var shouldAddLabelsToIntermediateReferenceLines: Bool = true + /// Whether or not to add units specified by the referenceLineUnits variable to the labels on the intermediate reference lines. + @IBInspectable open var shouldAddUnitsToIntermediateReferenceLineLabels: Bool = false + + // Reference Line Labels + // ##################### + + /// The font to be used for the reference line labels. + open var referenceLineLabelFont = UIFont.systemFont(ofSize: 8) + /// The colour of the reference line labels. + @IBInspectable open var referenceLineLabelColor: UIColor = UIColor.black + + /// Whether or not to show the units on the reference lines. + @IBInspectable open var shouldShowReferenceLineUnits: Bool = true + /// The units that the y-axis is in. This string is used for labels on the reference lines. + @IBInspectable open var referenceLineUnits: String? + /// The number of decimal places that should be shown on the reference line labels. + @IBInspectable open var referenceLineNumberOfDecimalPlaces: Int = 0 + /// The NSNumberFormatterStyle that reference lines should use to display + @IBInspectable open var referenceLineNumberStyle: NumberFormatter.Style = .none + + // Data Point Labels // TODO: Refactor these into their own settings and allow for more label options (positioning) + // ################################################################################################################ + + /// Whether or not to show the labels on the x-axis for each point. + @IBInspectable open var shouldShowLabels: Bool = true + /// How far from the "minimum" reference line the data point labels should be rendered. + @IBInspectable open var dataPointLabelTopMargin: CGFloat = 10 + /// How far from the bottom of the view the data point labels should be rendered. + @IBInspectable open var dataPointLabelBottomMargin: CGFloat = 0 + /// The font for the data point labels. + @IBInspectable open var dataPointLabelColor: UIColor = UIColor.black + /// The colour for the data point labels. + open var dataPointLabelFont: UIFont? = UIFont.systemFont(ofSize: 10) + /// Used to force the graph to show every n-th dataPoint label + @IBInspectable open var dataPointLabelsSparsity: Int = 1 + + public init() { + // Need this for external frameworks. + } +} + + +@objc public enum ScrollableGraphViewReferenceLinePosition : Int { + case left + case right + case both +} + +@objc public enum ReferenceLinePositioningType : Int { + case relative + case absolute +} + +@objc public enum ScrollableGraphViewReferenceLineType : Int { + case cover +} diff --git a/Pods/ScrollableGraphView/Classes/ScrollableGraphView.swift b/Pods/ScrollableGraphView/Classes/ScrollableGraphView.swift new file mode 100644 index 0000000..9dc5d18 --- /dev/null +++ b/Pods/ScrollableGraphView/Classes/ScrollableGraphView.swift @@ -0,0 +1,1027 @@ +import UIKit + +// MARK: - ScrollableGraphView +@IBDesignable +@objc open class ScrollableGraphView: UIScrollView, UIScrollViewDelegate, ScrollableGraphViewDrawingDelegate { + + // MARK: - Public Properties + // Use these to customise the graph. + // ################################# + + // Fill Styles + // ########### + + /// The background colour for the entire graph view, not just the plotted graph. + @IBInspectable open var backgroundFillColor: UIColor = UIColor.white + + // Spacing + // ####### + + /// How far the "maximum" reference line is from the top of the view's frame. In points. + @IBInspectable open var topMargin: CGFloat = 10 + /// How far the "minimum" reference line is from the bottom of the view's frame. In points. + @IBInspectable open var bottomMargin: CGFloat = 10 + /// How far the first point on the graph should be placed from the left hand side of the view. + @IBInspectable open var leftmostPointPadding: CGFloat = 50 + /// How far the final point on the graph should be placed from the right hand side of the view. + @IBInspectable open var rightmostPointPadding: CGFloat = 50 + /// How much space should be between each data point. + @IBInspectable open var dataPointSpacing: CGFloat = 40 + + @IBInspectable var direction_: Int { + get { return direction.rawValue } + set { + if let enumValue = ScrollableGraphViewDirection(rawValue: newValue) { + direction = enumValue + } + } + } + /// Which side of the graph the user is expected to scroll from. + open var direction = ScrollableGraphViewDirection.leftToRight + + // Graph Range + // ########### + + /// Forces the graph's minimum to always be zero. Used in conjunction with shouldAutomaticallyDetectRange or shouldAdaptRange, if you want to force the minimum to stay at 0 rather than the detected minimum. + @IBInspectable open var shouldRangeAlwaysStartAtZero: Bool = false + /// The minimum value for the y-axis. This is ignored when shouldAutomaticallyDetectRange or shouldAdaptRange = true + @IBInspectable open var rangeMin: Double = 0 + /// The maximum value for the y-axis. This is ignored when shouldAutomaticallyDetectRange or shouldAdaptRange = true + @IBInspectable open var rangeMax: Double = 100 + + // Adapting & Animations + // ##################### + + /// Whether or not the y-axis' range should adapt to the points that are visible on screen. This means if there are only 5 points visible on screen at any given time, the maximum on the y-axis will be the maximum of those 5 points. This is updated automatically as the user scrolls along the graph. + @IBInspectable open var shouldAdaptRange: Bool = false + /// If shouldAdaptRange is set to true then this specifies whether or not the points on the graph should animate to their new positions. Default is set to true. + @IBInspectable open var shouldAnimateOnAdapt: Bool = true + + /// Whether or not the graph should animate to their positions when the graph is first displayed. + @IBInspectable open var shouldAnimateOnStartup: Bool = true + + // Reference Line Settings + // ####################### + + var referenceLines: ReferenceLines? = nil + + // MARK: - Private State + // ##################### + + private var isInitialSetup = true + private var isCurrentlySettingUp = false + + private var viewportWidth: CGFloat = 0 { + didSet { if(oldValue != viewportWidth) { viewportDidChange() }} + } + private var viewportHeight: CGFloat = 0 { + didSet { if(oldValue != viewportHeight) { viewportDidChange() }} + } + + private var totalGraphWidth: CGFloat = 0 + private var offsetWidth: CGFloat = 0 + + // Graph Line + private var zeroYPosition: CGFloat = 0 + + // Graph Drawing + private var drawingView = UIView() + private var plots: [Plot] = [Plot]() + + // Reference Lines + private var referenceLineView: ReferenceLineDrawingView? + + // Labels + private var labelsView = UIView() + private var labelPool = LabelPool() + + // Data Source + weak open var dataSource: ScrollableGraphViewDataSource? { + didSet { + if(plots.count > 0) { + reload() + } + } + } + + // Active Points & Range Calculation + private var previousActivePointsInterval: CountableRange = -1 ..< -1 + private var activePointsInterval: CountableRange = -1 ..< -1 { + didSet { + if(oldValue.lowerBound != activePointsInterval.lowerBound || oldValue.upperBound != activePointsInterval.upperBound) { + if !isCurrentlySettingUp { activePointsDidChange() } + } + } + } + + private var range: (min: Double, max: Double) = (0, 100) { + didSet { + if(oldValue.min != range.min || oldValue.max != range.max) { + if !isCurrentlySettingUp { rangeDidChange() } + } + } + } + + // MARK: - INIT, SETUP & VIEWPORT RESIZING + // ####################################### + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + public init(frame: CGRect, dataSource: ScrollableGraphViewDataSource) { + self.dataSource = dataSource + super.init(frame: frame) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + deinit { + for plot in plots { + plot.invalidate() + } + } + + // You can change how you want the graph to appear in interface builder here. + // This ONLY changes how it appears in interface builder, you will still need + // to setup the graph properly in your view controller for it to change in the + // actual application. + open override func prepareForInterfaceBuilder() { + super.prepareForInterfaceBuilder() + + self.dataSource = self as? ScrollableGraphViewDataSource + self.shouldAnimateOnStartup = false + + // Customise how the reference lines look in IB + let referenceLines = ReferenceLines() + self.addReferenceLines(referenceLines: referenceLines) + } + + private func setup() { + + clipsToBounds = true + isCurrentlySettingUp = true + + // 0. + // Save the viewport, that is, the size of the rectangle through which we view the graph. + + self.viewportWidth = self.frame.width + self.viewportHeight = self.frame.height + + let viewport = CGRect(x: 0, y: 0, width: viewportWidth, height: viewportHeight) + + // 1. + // Add the subviews we will use to draw everything. + + // Add the drawing view in which we draw all the plots. + drawingView = UIView(frame: viewport) + drawingView.backgroundColor = backgroundFillColor + self.addSubview(drawingView) + + // Add the x-axis labels view. + self.insertSubview(labelsView, aboveSubview: drawingView) + + // 2. + // Calculate the total size of the graph, need to know this for the scrollview. + + // Calculate the drawing frames + let numberOfDataPoints = dataSource?.numberOfPoints() ?? 0 + totalGraphWidth = graphWidth(forNumberOfDataPoints: numberOfDataPoints) + self.contentSize = CGSize(width: totalGraphWidth, height: viewportHeight) + + // Scrolling direction. + + #if TARGET_INTERFACE_BUILDER + self.offsetWidth = 0 + #else + if (direction == .rightToLeft) { + self.offsetWidth = self.contentSize.width - viewportWidth + } + // Otherwise start of all the way to the left. + else { + self.offsetWidth = 0 + } + #endif + + // Set the scrollview offset. + self.contentOffset.x = self.offsetWidth + + // 3. + // Calculate the points that we will be able to see when the view loads. + + let initialActivePointsInterval = calculateActivePointsInterval() + + // 4. + // Add the plots to the graph, we need these to calculate the range. + + while(queuedPlots.count > 0) { + if let plot = queuedPlots.dequeue() { + addPlotToGraph(plot: plot, activePointsInterval: initialActivePointsInterval) + } + } + + // 5. + // Calculate the range for the points we can actually see. + + #if TARGET_INTERFACE_BUILDER + self.range = (min: rangeMin, max: rangeMax) + #else + // Need to calculate the range across all plots to get the min and max for all plots. + if (shouldAdaptRange) { // This overwrites anything specified by rangeMin and rangeMax + let range = calculateRange(forActivePointsInterval: initialActivePointsInterval) + self.range = range + } + else { + self.range = (min: rangeMin, max: rangeMax) // just use what the user specified instead. + } + #endif + + // If the graph was given all 0s as data, we can't use a range of 0->0, so make sure we have a sensible range at all times. + if (self.range.min == 0 && self.range.max == 0) { + self.range = (min: 0, max: rangeMax) + } + + // 6. + // Add the reference lines, can only add this once we know the range. + + if(referenceLines != nil) { + addReferenceViewDrawingView() + } + + // 7. + // We're now done setting up, update the offsets and change the flag. + + updateOffsetWidths() + isCurrentlySettingUp = false + + // Set the first active points interval. These are the points that are visible when the view loads. + self.activePointsInterval = initialActivePointsInterval + } + + // TODO in 4.1: Plot layer ordering. + // TODO in 4.1: Plot removal. + private func addDrawingLayersForPlots(inViewport viewport: CGRect) { + for plot in plots { + addSubLayers(layers: plot.layers(forViewport: viewport)) + } + } + + private func addSubLayers(layers: [ScrollableGraphViewDrawingLayer?]) { + for layer in layers { + if let layer = layer { + drawingView.layer.addSublayer(layer) + } + } + } + + private func addReferenceViewDrawingView() { + + guard let referenceLines = self.referenceLines else { + // We can want to add this if the settings arent nil. + return + } + + if(referenceLines.shouldShowReferenceLines) { + let viewport = CGRect(x: 0, y: 0, width: viewportWidth, height: viewportHeight) + var referenceLineBottomMargin = bottomMargin + + // Have to adjust the bottom line if we are showing data point labels (x-axis). + if(referenceLines.shouldShowLabels && referenceLines.dataPointLabelFont != nil) { + referenceLineBottomMargin += (referenceLines.dataPointLabelFont!.pointSize + referenceLines.dataPointLabelTopMargin + referenceLines.dataPointLabelBottomMargin) + } + + referenceLineView?.removeFromSuperview() + referenceLineView = ReferenceLineDrawingView( + frame: viewport, + topMargin: topMargin, + bottomMargin: referenceLineBottomMargin, + referenceLineColor: referenceLines.referenceLineColor, + referenceLineThickness: referenceLines.referenceLineThickness, + referenceLineSettings: referenceLines) + + referenceLineView?.set(range: self.range) + + self.addSubview(referenceLineView!) + } + } + + // If the view has changed we have to make sure we're still displaying the right data. + override open func layoutSubviews() { + super.layoutSubviews() + + // while putting the view on the IB, we may get calls with frame too small + // if frame height is too small we won't be able to calculate zeroYPosition + // so make sure to proceed only if there is enough space + var availableGraphHeight = frame.height + availableGraphHeight = availableGraphHeight - topMargin - bottomMargin + + if let referenceLines = referenceLines { + if(referenceLines.shouldShowLabels && referenceLines.dataPointLabelFont != nil) { + availableGraphHeight -= (referenceLines.dataPointLabelFont!.pointSize + referenceLines.dataPointLabelTopMargin + referenceLines.dataPointLabelBottomMargin) + } + } + + if availableGraphHeight > 0 { + updateUI() + } + } + + private func updateUI() { + + // Make sure we have data, if don't, just get out. We can't do anything without any data. + guard let dataSource = dataSource else { + return + } + + guard dataSource.numberOfPoints() > 0 else { + return + } + + if (isInitialSetup) { + setup() + + if(shouldAnimateOnStartup) { + startAnimations(withStaggerValue: 0.15) + } + + // We're done setting up. + isInitialSetup = false + } + // Otherwise, the user is just scrolling and we just need to update everything. + else { + // Needs to update the viewportWidth and viewportHeight which is used to calculate which + // points we can actually see. + viewportWidth = self.frame.width + viewportHeight = self.frame.height + + // If the scrollview has scrolled anywhere, we need to update the offset + // and move around our drawing views. + offsetWidth = self.contentOffset.x + updateOffsetWidths() + + // Recalculate active points for this size. + // Recalculate range for active points. + let newActivePointsInterval = calculateActivePointsInterval() + self.previousActivePointsInterval = self.activePointsInterval + self.activePointsInterval = newActivePointsInterval + + // If adaption is enabled we want to + if(shouldAdaptRange) { + // TODO: This is currently called every single frame... + // We need to only calculate the range if the active points interval has changed! + #if !TARGET_INTERFACE_BUILDER + let newRange = calculateRange(forActivePointsInterval: newActivePointsInterval) + self.range = newRange + #endif + } + } + } + + private func updateOffsetWidths() { + drawingView.frame.origin.x = offsetWidth + drawingView.bounds.origin.x = offsetWidth + + updateOffsetsForGradients(offsetWidth: offsetWidth) + + referenceLineView?.frame.origin.x = offsetWidth + } + + private func updateOffsetsForGradients(offsetWidth: CGFloat) { + guard let sublayers = drawingView.layer.sublayers else { + return + } + + for layer in sublayers { + switch(layer) { + case let layer as GradientDrawingLayer: + layer.offset = offsetWidth + default: break + } + } + } + + private func updateFrames() { + // Drawing view needs to always be the same size as the scrollview. + drawingView.frame.size.width = viewportWidth + drawingView.frame.size.height = viewportHeight + + // Gradient should extend over the entire viewport + updateFramesForGradientLayers(viewportWidth: viewportWidth, viewportHeight: viewportHeight) + + // Reference lines should extend over the entire viewport + referenceLineView?.set(viewportWidth: viewportWidth, viewportHeight: viewportHeight) + + self.contentSize.height = viewportHeight + } + + private func updateFramesForGradientLayers(viewportWidth: CGFloat, viewportHeight: CGFloat) { + + guard let sublayers = drawingView.layer.sublayers else { + return + } + + for layer in sublayers { + switch(layer) { + case let layer as GradientDrawingLayer: + layer.frame.size.width = viewportWidth + layer.frame.size.height = viewportHeight + default: break + } + } + } + + // MARK: - Public Methods + // ###################### + + public func addPlot(plot: Plot) { + // If we aren't setup yet, save the plot to be added during setup. + if(isInitialSetup) { + enqueuePlot(plot) + } + // Otherwise, just add the plot directly. + else { + addPlotToGraph(plot: plot, activePointsInterval: self.activePointsInterval) + } + } + + public func addReferenceLines(referenceLines: ReferenceLines) { + + // If we aren't setup yet, just save the reference lines and the setup will take care of it. + if(isInitialSetup) { + self.referenceLines = referenceLines + } + // Otherwise, add the reference lines, reload everything. + else { + addReferenceLinesToGraph(referenceLines: referenceLines) + } + } + + // Limitation: Can only be used when reloading the same number of data points! + public func reload() { + stopAnimations() + rangeDidChange() + updateUI() + updatePaths() + updateLabelsForCurrentInterval() + } + + // The functions for adding plots and reference lines need to be able to add plots + // both before and after the graph knows its viewport/size. + // This needs to be the case so we can use it in interface builder as well as + // just adding it programatically. + // These functions add the plots and reference lines to the graph. + // The public functions will either save the plots and reference lines (in the case + // don't have the required viewport information) or add it directly to the graph + // (the case where we already know the viewport information). + private func addPlotToGraph(plot: Plot, activePointsInterval: CountableRange) { + plot.graphViewDrawingDelegate = self + self.plots.append(plot) + initPlot(plot: plot, activePointsInterval: activePointsInterval) + startAnimations(withStaggerValue: 0.15) + } + + private func addReferenceLinesToGraph(referenceLines: ReferenceLines) { + self.referenceLines = referenceLines + addReferenceViewDrawingView() + + updateLabelsForCurrentInterval() + } + + private func initPlot(plot: Plot, activePointsInterval: CountableRange) { + + #if !TARGET_INTERFACE_BUILDER + plot.setup() // Only init the animations for plots if we are not in IB + #endif + + plot.createPlotPoints(numberOfPoints: dataSource!.numberOfPoints(), range: range) // TODO: removed forced unwrap + + // If we are not animating on startup then just set all the plot positions to their respective values + if(!shouldAnimateOnStartup) { + let dataForInitialPoints = getData(forPlot: plot, andActiveInterval: activePointsInterval) + plot.setPlotPointPositions(forNewlyActivatedPoints: activePointsInterval, withData: dataForInitialPoints) + } + + addSubLayers(layers: plot.layers(forViewport: currentViewport())) + } + + private var queuedPlots: SGVQueue = SGVQueue() + + private func enqueuePlot(_ plot: Plot) { + queuedPlots.enqueue(element: plot) + } + + + // MARK: - Private Methods + // ####################### + + // MARK: Layout Calculations + // ######################### + + private func calculateActivePointsInterval() -> CountableRange { + + // Calculate the "active points" + let min = Int((offsetWidth) / dataPointSpacing) + let max = Int(((offsetWidth + viewportWidth)) / dataPointSpacing) + + // Add and minus two so the path goes "off the screen" so we can't see where it ends. + let minPossible = 0 + var maxPossible = 0 + + if let numberOfPoints = dataSource?.numberOfPoints() { + maxPossible = numberOfPoints - 1 + } + + let numberOfPointsOffscreen = 2 + + let actualMin = clamp(value: min - numberOfPointsOffscreen, min: minPossible, max: maxPossible) + let actualMax = clamp(value: max + numberOfPointsOffscreen, min: minPossible, max: maxPossible) + + return actualMin..) -> (min: Double, max: Double) { + + // This calculates the range across all plots for the active points. + // So the maximum will be the max of all plots, same goes for min. + var ranges = [(min: Double, max: Double)]() + + for plot in plots { + let rangeForPlot = calculateRange(forPlot: plot, forActivePointsInterval: interval) + ranges.append(rangeForPlot) + } + + let minOfRanges = min(ofAllRanges: ranges) + let maxOfRanges = max(ofAllRanges: ranges) + + return (min: minOfRanges, max: maxOfRanges) + } + + private func max(ofAllRanges ranges: [(min: Double, max: Double)]) -> Double { + + var max: Double = ranges[0].max + + for range in ranges { + if(range.max > max) { + max = range.max + } + } + + return max + } + + private func min(ofAllRanges ranges: [(min: Double, max: Double)]) -> Double { + var min: Double = ranges[0].min + + for range in ranges { + if(range.min < min) { + min = range.min + } + } + + return min + } + + // Calculate the range for a single plot. + private func calculateRange(forPlot plot: Plot, forActivePointsInterval interval: CountableRange) -> (min: Double, max: Double) { + + let dataForActivePoints = getData(forPlot: plot, andActiveInterval: interval) + + // We don't have any active points, return defaults. + if(dataForActivePoints.count == 0) { + return (min: self.rangeMin, max: self.rangeMax) + } + else { + + let range = calculateRange(for: dataForActivePoints) + return clean(range: range) + } + } + + private func calculateRange(for data: T) -> (min: Double, max: Double) where T.Iterator.Element == Double { + + var rangeMin: Double = Double(Int.max) + var rangeMax: Double = Double(Int.min) + + for dataPoint in data { + if (dataPoint > rangeMax) { + rangeMax = dataPoint + } + + if (dataPoint < rangeMin) { + rangeMin = dataPoint + } + } + return (min: rangeMin, max: rangeMax) + } + + private func clean(range: (min: Double, max: Double)) -> (min: Double, max: Double){ + if(range.min == range.max) { + + let min = shouldRangeAlwaysStartAtZero ? 0 : range.min + let max = range.max + 1 + + return (min: min, max: max) + } + else if (shouldRangeAlwaysStartAtZero) { + + let min: Double = 0 + var max: Double = range.max + + // If we have all negative numbers and the max happens to be 0, there will cause a division by 0. Return the default height. + if(range.max == 0) { + max = rangeMax + } + + return (min: min, max: max) + } + else { + return range + } + } + + private func graphWidth(forNumberOfDataPoints numberOfPoints: Int) -> CGFloat { + let width: CGFloat = (CGFloat(numberOfPoints - 1) * dataPointSpacing) + (leftmostPointPadding + rightmostPointPadding) + return width + } + + private func clamp(value:T, min:T, max:T) -> T { + if (value < min) { + return min + } + else if (value > max) { + return max + } + else { + return value + } + } + + private func getData(forPlot plot: Plot, andActiveInterval activeInterval: CountableRange) -> [Double] { + + var dataForInterval = [Double]() + + for i in activeInterval.startIndex ..< activeInterval.endIndex { + let dataForIndexI = dataSource?.value(forPlot: plot, atIndex: i) ?? 0 + dataForInterval.append(dataForIndexI) + } + + return dataForInterval + } + + private func getData(forPlot plot: Plot, andNewlyActivatedPoints activatedPoints: [Int]) -> [Double] { + + var dataForActivatedPoints = [Double]() + + for activatedPoint in activatedPoints { + let dataForActivatedPoint = dataSource?.value(forPlot: plot, atIndex: activatedPoint) ?? 0 + dataForActivatedPoints.append(dataForActivatedPoint) + } + + return dataForActivatedPoints + } + + // MARK: Events + // ############ + + // If the active points (the points we can actually see) change, then we need to update the path. + private func activePointsDidChange() { + + let deactivatedPoints = determineDeactivatedPoints() + let activatedPoints = determineActivatedPoints() + + // The plots need to know which points became active and what their values + // are so the plots can display them properly. + if(!isInitialSetup) { + for plot in plots { + let newData = getData(forPlot: plot, andNewlyActivatedPoints: activatedPoints) + plot.setPlotPointPositions(forNewlyActivatedPoints: activatedPoints, withData: newData) + } + } + + updatePaths() + + if let ref = self.referenceLines { + if(ref.shouldShowLabels) { + let deactivatedLabelPoints = filterPointsForLabels(fromPoints: deactivatedPoints) + let activatedLabelPoints = filterPointsForLabels(fromPoints: activatedPoints) + updateLabels(deactivatedPoints: deactivatedLabelPoints, activatedPoints: activatedLabelPoints) + } + } + } + + private func rangeDidChange() { + + // If shouldAnimateOnAdapt is enabled it will kickoff any animations that need to occur. + if(shouldAnimateOnAdapt) { + startAnimations() + } + else { + // Otherwise we should simple just move the data to their positions. + for plot in plots { + let newData = getData(forPlot: plot, andActiveInterval: activePointsInterval) + plot.setPlotPointPositions(forNewlyActivatedPoints: intervalForActivePoints(), withData: newData) + } + } + + referenceLineView?.set(range: range) + } + + private func viewportDidChange() { + + // We need to make sure all the drawing views are the same size as the viewport. + updateFrames() + + // Basically this recreates the paths with the new viewport size so things are in sync, but only + // if the viewport has changed after the initial setup. Because the initial setup will use the latest + // viewport anyway. + if(!isInitialSetup) { + updatePaths() + + // Need to update the graph points so they are in their right positions for the new viewport. + // Animate them into position if animation is enabled, but make sure to stop any current animations first. + #if !TARGET_INTERFACE_BUILDER + stopAnimations() + #endif + startAnimations() + + // The labels will also need to be repositioned if the viewport has changed. + repositionActiveLabels() + } + } + + // Returns the indices of any points that became inactive (that is, "off screen"). (No order) + private func determineDeactivatedPoints() -> [Int] { + let prevSet = Set(previousActivePointsInterval) + let currSet = Set(activePointsInterval) + + let deactivatedPoints = prevSet.subtracting(currSet) + + return Array(deactivatedPoints) + } + + // Returns the indices of any points that became active (on screen). (No order) + private func determineActivatedPoints() -> [Int] { + let prevSet = Set(previousActivePointsInterval) + let currSet = Set(activePointsInterval) + + let activatedPoints = currSet.subtracting(prevSet) + + return Array(activatedPoints) + } + + // Animations + + private func startAnimations(withStaggerValue stagger: Double = 0) { + var pointsToAnimate = 0 ..< 0 + + #if !TARGET_INTERFACE_BUILDER + if (shouldAnimateOnAdapt || (isInitialSetup && shouldAnimateOnStartup)) { + pointsToAnimate = activePointsInterval + } + #endif + + for plot in plots { + let dataForPointsToAnimate = getData(forPlot: plot, andActiveInterval: pointsToAnimate) + plot.startAnimations(forPoints: pointsToAnimate, withData: dataForPointsToAnimate, withStaggerValue: stagger) + } + } + + private func stopAnimations() { + for plot in plots { + plot.dequeueAllAnimations() + } + } + + // Labels + // TODO in 4.1: refactor all label adding & positioning code. + + // Update any labels for any new points that have been activated and deactivated. + private func updateLabels(deactivatedPoints: [Int], activatedPoints: [Int]) { + + guard let ref = self.referenceLines else { + return + } + + // Disable any labels for the deactivated points. + for point in deactivatedPoints { + labelPool.deactivateLabel(forPointIndex: point) + } + + // Grab an unused label and update it to the right position for the newly activated poitns + for point in activatedPoints { + let label = labelPool.activateLabel(forPointIndex: point) + + label.text = (dataSource?.label(atIndex: point) ?? "") + label.textColor = ref.dataPointLabelColor + label.font = ref.dataPointLabelFont + + label.sizeToFit() + + // self.range.min is the current ranges minimum that has been detected + // self.rangeMin is the minimum that should be used as specified by the user + let rangeMin = (shouldAdaptRange) ? self.range.min : self.rangeMin + let position = calculatePosition(atIndex: point, value: rangeMin) + + label.frame = CGRect(origin: CGPoint(x: position.x - label.frame.width / 2, y: position.y + ref.dataPointLabelTopMargin), size: label.frame.size) + + let _ = labelsView.subviews.filter { $0.frame == label.frame }.map { $0.removeFromSuperview() } + + labelsView.addSubview(label) + } + } + + private func updateLabelsForCurrentInterval() { + // Have to ensure that the labels are added if we are supposed to be showing them. + if let ref = self.referenceLines { + if(ref.shouldShowLabels) { + + var activatedPoints: [Int] = [] + for i in activePointsInterval { + activatedPoints.append(i) + } + + let filteredPoints = filterPointsForLabels(fromPoints: activatedPoints) + updateLabels(deactivatedPoints: filteredPoints, activatedPoints: filteredPoints) + } + } + } + + private func repositionActiveLabels() { + + guard let ref = self.referenceLines else { + return + } + + for label in labelPool.activeLabels { + + let rangeMin = (shouldAdaptRange) ? self.range.min : self.rangeMin + let position = calculatePosition(atIndex: 0, value: rangeMin) + + label.frame.origin.y = position.y + ref.dataPointLabelTopMargin + } + } + + private func filterPointsForLabels(fromPoints points:[Int]) -> [Int] { + + guard let ref = self.referenceLines else { + return points + } + + if(ref.dataPointLabelsSparsity == 1) { + return points + } + return points.filter({ $0 % ref.dataPointLabelsSparsity == 0 }) + } + + // MARK: - Drawing Delegate + // ######################## + + internal func calculatePosition(atIndex index: Int, value: Double) -> CGPoint { + + // Set range defaults based on settings: + + // self.range.min/max is the current ranges min/max that has been detected + // self.rangeMin/Max is the min/max that should be used as specified by the user + let rangeMax = (shouldAdaptRange) ? self.range.max : self.rangeMax + let rangeMin = (shouldAdaptRange) ? self.range.min : self.rangeMin + + // y = the y co-ordinate in the view for the value in the graph + // value = the value on the graph for which we want to know its + // ( ( value - max ) ) corresponding location on the y axis in the view + // y = ( ( ----------- ) * graphHeight ) + topMargin t = the top margin + // ( ( min - max ) ) h = the height of the graph space without margins + // min = the range's current mininum + // max = the range's current maximum + + // Calculate the position on in the view for the value specified. + var graphHeight = viewportHeight - topMargin - bottomMargin + + if let ref = self.referenceLines { + if(ref.shouldShowLabels && ref.dataPointLabelFont != nil) { + graphHeight -= (ref.dataPointLabelFont!.pointSize + ref.dataPointLabelTopMargin + ref.dataPointLabelBottomMargin) + } + } + + let x = (CGFloat(index) * dataPointSpacing) + leftmostPointPadding + let y = (CGFloat((value - rangeMax) / (rangeMin - rangeMax)) * graphHeight) + topMargin + + return CGPoint(x: x, y: y) + } + + internal func intervalForActivePoints() -> CountableRange { + return activePointsInterval + } + + internal func rangeForActivePoints() -> (min: Double, max: Double) { + return range + } + + internal func paddingForPoints() -> (leftmostPointPadding: CGFloat, rightmostPointPadding: CGFloat) { + return (leftmostPointPadding: leftmostPointPadding, rightmostPointPadding: rightmostPointPadding) + } + + internal func currentViewport() -> CGRect { + return CGRect(x: 0, y: 0, width: viewportWidth, height: viewportHeight) + } + + // Update any paths with the new path based on visible data points. + internal func updatePaths() { + + zeroYPosition = calculatePosition(atIndex: 0, value: self.range.min).y + + if let drawingLayers = drawingView.layer.sublayers { + for layer in drawingLayers { + if let layer = layer as? ScrollableGraphViewDrawingLayer { + // The bar layer needs the zero Y position to set the bottom of the bar + layer.zeroYPosition = zeroYPosition + // Need to make sure this is set in createLinePath + assert (layer.zeroYPosition > 0); + layer.updatePath() + } + } + } + } +} + +// MARK: - ScrollableGraphView Settings Enums +// ########################################## + +@objc public enum ScrollableGraphViewDirection : Int { + case leftToRight + case rightToLeft +} + +// Simple queue data structure for keeping track of which +// plots have been added. +fileprivate class SGVQueue { + + var storage: [T] + + public var count: Int { + get { + return storage.count + } + } + + init() { + storage = [T]() + } + + public func enqueue(element: T) { + storage.insert(element, at: 0) + } + + public func dequeue() -> T? { + return storage.popLast() + } +} + +// We have to be our own data source for interface builder. +#if TARGET_INTERFACE_BUILDER +public extension ScrollableGraphView : ScrollableGraphViewDataSource { + + var numberOfDisplayItems: Int { + get { + return 30 + } + } + + var linePlotData: [Double] { + get { + return self.generateRandomData(numberOfDisplayItems, max: 100, shouldIncludeOutliers: false) + } + } + + public func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double { + return linePlotData[pointIndex] + } + + public func label(atIndex pointIndex: Int) -> String { + return "\(pointIndex)" + } + + public func numberOfPoints() -> Int { + return numberOfDisplayItems + } + + private func generateRandomData(_ numberOfItems: Int, max: Double, shouldIncludeOutliers: Bool = true) -> [Double] { + var data = [Double]() + for _ in 0 ..< numberOfItems { + var randomNumber = Double(arc4random()).truncatingRemainder(dividingBy: max) + + if(shouldIncludeOutliers) { + if(arc4random() % 100 < 10) { + randomNumber *= 3 + } + } + + data.append(randomNumber) + } + return data + } +} +#endif + diff --git a/Pods/ScrollableGraphView/LICENSE b/Pods/ScrollableGraphView/LICENSE new file mode 100644 index 0000000..40d2b86 --- /dev/null +++ b/Pods/ScrollableGraphView/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Phillip + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/ScrollableGraphView/README.md b/Pods/ScrollableGraphView/README.md new file mode 100644 index 0000000..4f0ed96 --- /dev/null +++ b/Pods/ScrollableGraphView/README.md @@ -0,0 +1,592 @@ +# ScrollableGraphView + +## Announcements + +### 9-7-2017 - Looking for Examples: + +If your application uses this component and you would like to show it off, please let me know as I would like to create a gallery. Please create a pull request and update the [examples.md](examples.md) with the app name and URL. I will add screenshots of the applications to a gallery for everyone to see. + +### 9-7-2017 - Version 4: + +Version 4 was released which adds multiple plots, dynamic reloading of values, more reference line customisation options and various bug fixes. + +You can see the major changes in the API [here](APIv4.md). + +The public interface is incompatible with previous versions. If you prefer to keep using the older version, make sure to specify version 3 in your podfile or downloaded the classes from a pre-v4 release. + +## About + +![Example Application Usage](readme_images/IMG_5814_small.jpg) + +An adaptive scrollable graph view for iOS to visualise simple discrete datasets. Written in Swift. Originally written for a small personal project. + +The main goal of the this graph component is to visualise simple discrete datasets and allow the the user to scroll through the graph. + +![Init Animation](readme_images/init_anim_high_fps.gif) + +### Contribution + +All pull requests are welcome. There is a list of features people would like on the issues page, ranging from simple changes to quite complex. Feel free to jump on in. + +## Sponsors + +Development of this component has been sponsored by **Anomaly**. Check them out [here](https://www.anomaly.net.au/). + +## Contents + +- [Features](#features) +- [Basic Usage](#usage) +- [Customisation](#customisation) +- [Customisation Examples](#customisation-examples) +- [Improvements](#improvements) +- [Other](#other) + +## Features + +| Feature List | +|--------| +| Initialisation animations and range adaption animations.

![Animating](readme_images/animating.gif)| +| Multiple plots and dynamic reloading of the values.

![dynamic-reload](readme_images/dynamic-reload.gif)| +| Range adaption when scrolling through the graph. The range of the y-axis will automatically adapt to to the min and max of the visible points.

![Adapting](readme_images/adapting.gif)| +| Smooth scrolling around the graph.

![Scrolling](readme_images/scrolling.gif)| +| Handles as many points as you can throw at it.

![More_Scrolling](readme_images/more_scrolling.gif)| +| Many customisation options. (Check the customisation section)

![Customising](readme_images/customising.gif)| + +## Usage + +### Adding the ScrollableGraphView to your project: + +Add the ```ScrollableGraphView``` class to your project. There are two ways to add the ScrollableGraphView to your project. + +#### Manually +Add all of the files in the [Classes](Classes/) directory to your project in Xcode to your project in Xcode. + +#### CocoaPods +Add ```pod 'ScrollableGraphView'``` to your Podfile and then make sure to ```import ScrollableGraphView``` in your code. + +#### Carthage +Add `github "philackm/ScrollableGraphView" ~> 4.0.2` to your Cartfile and then make sure to link the frameworks and `import ScrollableGraphView` in your code. + +### Creating a graph and providing it with data. + +1. Create a ScrollableGraphView instance. The graph requires a data source, which is an object that conforms to the `ScrollableGraphViewDataSource` protocol. + + ```swift + // Compose the graph view by creating a graph, then adding any plots + // and reference lines before adding the graph to the view hierarchy. + let graphView = ScrollableGraphView(frame: frame, dataSource: self) + + let linePlot = LinePlot(identifier: "line") // Identifier should be unique for each plot. + let referenceLines = ReferenceLines() + + graphView.addPlot(plot: linePlot) + graphView.addReferenceLines(referenceLines: referenceLines) + ``` + +2. Ensure the dataSource object conforms to the `ScrollableGraphViewDataSource` protocol and implements the following three methods like so: + + ```swift + func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double { + // Return the data for each plot. + switch(plot.identifier) { + case "line": + return linePlotData[pointIndex] + default: + return 0 + } + } + + func label(atIndex pointIndex: Int) -> String { + return "FEB \(pointIndex)" + } + + func numberOfPoints() -> Int { + return numberOfDataPointsInGraph + } + ``` + +3. Finally, add the ScrollableGraphView to the view hierarchy. + + ```swift + someViewController.view.addSubview(graphView) + ``` + +This will create a graph that looks something like: + +![SimpleGraph](readme_images/simple.png) + +### Interface Builder support + +There is now support for Interface Builder (from CocoaPod version 2.0.0). See the example project in the folder: [graphview_example_ib](graphview_example_ib/) + +### Things you *could* use it for: + +- ✔ Study applications to show time studied/etc +- ✔ Weather applications +- ✔ Prototyping +- ✔ *Simple* data visualisation + +### Things you **shouldn't/cannot** use it for: + +- ✘ Rigorous statistical software +- ✘ Important & complex data visualisation +- ✘ Graphing continuous mathematical functions + +## Customisation + +The entire graph is composed by initially creating an empty `ScrollableGraphView` object and progressively adding whatever plots and reference lines you require. + +Create a plot using the any of the `LinePlot`, `DotPlot`, `BarPlot` constructors. Create reference lines using the `ReferenceLines()` constructor. Before adding the `ScrollableGraphView` object to the view hierarchy, add the plots and reference lines to the graph using the `addPlot` and `addReferenceLines` methods. You can add multiple plots (examples are shown below). Each plot _must_ have the same number of data points. + +In the case of interface builder, graph customisation is performed via the properties pane, whilst plots and reference lines customisation is done in the corresponding view controller. See the example project in the folder: [graphview_example_ib](graphview_example_ib/) + +## Graph Customisation + +These settings can be set directly on the `ScrollableGraphView` object before adding it to the view hierarchy. + +#### Adapting & Animations +| Property | Description | +|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **shouldAdaptRange**: Bool | Whether or not the y-axis' range should adapt to the points that are visible on screen. This means if there are only 5 points visible on screen at any given time, the maximum on the y-axis will be the maximum of those 5 points. This is updated automatically as the user scrolls along the graph. ![Adapting](readme_images/adapting.gif)| +| **shouldAnimateOnAdapt**: Bool | If `shouldAdaptRange` is set to true then this specifies whether or not the points on the graph should animate to their new positions. Default is set to `true`. Looks very janky if set to `false`. | +| **shouldAnimateOnStartup**: Bool | Whether or not the graph should animate to their positions when the graph is first displayed. | + +#### Spacing +![spacing](readme_images/spacing.png) + +| Property | Description | +|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **topMargin**: CGFloat | How far the "maximum" reference line is from the top of the view's frame. In points. | +| **bottomMargin**: CGFloat | How far the "minimum" reference line is from the bottom of the view's frame. In points. | +| **leftmostPointPadding**: CGFloat | How far the first point on the graph should be placed from the left hand side of the view. | +| **rightmostPointPadding**: CGFloat | How far the final point on the graph should be placed from the right hand side of the view. | +| **dataPointSpacing**: CGFloat | How much space should be between each data point. | +| **direction**: ScrollableGraphViewDirection | Which way the user is expected to scroll from. Possible values:
  • `ScrollableGraphViewDirection.leftToRight`
  • `ScrollableGraphViewDirection.rightToLeft`
For example, if it is set to `.rightToLeft`, the graph will start on the "right hand side" of the graph and the user will have to scroll towards the left. | + +#### Graph Range +| Property | Description | +|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **rangeMin**: Double | The minimum value for the y-axis. This is ignored when `shouldAdaptRange` = `true` | +| **rangeMax**: Double | The maximum value for the y-axis. This is ignored when `shouldAdaptRange` = `true` | +| **shouldRangeAlwaysStartAtZero**: Bool | Forces the graph's minimum to always be zero. Used in conjunction with `shouldAdaptRange`, if you want to force the minimum to stay at 0 rather than the detected minimum. | + + +## Plot Customisation + + +For all plots you can specify animation related information for when the plot first appears and during adaptions. + +#### Animation +| Property | Description | +|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **animationDuration**: Double | How long the animation should take. Affects both the startup animation and the animation when the range of the y-axis adapts to onscreen points. | +| **adaptAnimationType**: ScrollableGraphViewAnimationType | The animation style. Possible values:
  • `ScrollableGraphViewAnimationType.easeOut`
  • `ScrollableGraphViewAnimationType.elastic`
  • `ScrollableGraphViewAnimationType.custom`
| +| **customAnimationEasingFunction**: ((t: Double) -> Double)? | If `adaptAnimationType` is set to `.custom`, then this is the easing function you would like applied for the animation. | + +### LinePlot + +Line plot specific customisation options. These options are available on any `LinePlot` object. + +#### Line Styles +| Property | Description | +|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **lineWidth**: CGFloat | Specifies how thick the graph of the line is. In points. | +| **lineColor**: UIColor | The color of the graph line. UIColor. | +| **lineStyle**: ScrollableGraphViewLineStyle | Whether or not the line should be rendered using bezier curves are straight lines. Possible values:
  • `ScrollableGraphViewLineStyle.straight`
  • `ScrollableGraphViewLineStyle.smooth`
| +| **lineJoin** | How each segment in the line should connect. Takes any of the Core Animation LineJoin values. | +| **lineCap** | The line caps. Takes any of the Core Animation LineCap values. | + +#### Fill Styles +| Property | Description | +|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **shouldFill**: Bool | Specifies whether or not the plotted graph should be filled with a colour or gradient. | +| **fillType**: ScrollableGraphViewFillType | Specifies whether to fill the graph with a solid colour or gradient. Possible values:
  • `ScrollableGraphViewFillType.solid`
  • `ScrollableGraphViewFillType.gradient`
| +| **fillColor**: UIColor | If `fillType` is set to `.solid` then this colour will be used to fill the graph. | +| **fillGradientStartColor**: UIColor | If `fillType` is set to `.gradient` then this will be the starting colour for the gradient. | +| **fillGradientEndColor**: UIColor | If `fillType` is set to `.gradient`, then this will be the ending colour for the gradient. | +| **fillGradientType**:ScrollableGraphViewGradientType | If `fillType` is set to `.gradient`, then this defines whether the gradient is rendered as a linear gradient or radial gradient. Possible values:
  • `ScrollableGraphViewGradientType.linear`
  • `ScrollableGraphViewGradientType.radial`
| + +### DotPlot + +Dot plot specific customisation options. These options are available on any `DotPlot` object. + +| Property | Description | +|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **dataPointType**: ScrollableGraphViewDataPointType | The shape to draw for each data point. Possible values:
  • `ScrollableGraphViewDataPointType.circle`
  • `ScrollableGraphViewDataPointType.square`
  • `ScrollableGraphViewDataPointType.custom`
| +| **dataPointSize**: CGFloat | The size of the shape to draw for each data point. | +| **dataPointFillColor**: UIColor | The colour with which to fill the shape. | +| **customDataPointPath**: ((centre: CGPoint) -> UIBezierPath)? | If `dataPointType` is set to `.custom` then you,can provide a closure to create any kind of shape you would like to be displayed instead of just a circle or square. The closure takes a `CGPoint` which is the centre of the shape and it should return a complete `UIBezierPath`. | + +### BarPlot + +Bar plot specific customisation options. These options are available on any `BarPlot` object. + +| Property | Description| +|---------------------------------------|------------| +| **barWidth**: CGFloat | The width of an individual bar on the graph.| +| **barColor**: UIColor | The actual colour of the bar.| +| **barLineWidth**: CGFloat | The width of the outline of the bar.| +| **barLineColor**: UIColor | The colour of the bar outline.| +| **shouldRoundBarCorners**: Bool | Whether or not to use rounded corners for the bars.| + + +## Reference Line Customisation + + +These options are set on the `ReferenceLines` object before adding it to the graph view. + +### Reference Lines + +| Property | Description| +|-----------------------------------------------------------------|------------| +| **shouldShowReferenceLines**: Bool | Whether or not to show the y-axis reference lines and labels.| +| **positionType**: ReferenceLinePositioningType | Whether the reference lines should be placed relatively, (for example at 0%, 20%, 40%, 60%, 80% and 100% of the max y-axis value), or absolutely at specific values on the y-axis. Possible values:
  • `ReferenceLinePositioningType.relative`
  • `ReferenceLinePositioningType.absolute`
| +| **relativePositions**: [Double] | An array of positions where the reference lines should be placed. Used if `positionType == .relative`. For example, assigning a value of [0, 0.5, 1] will add 3 reference lines to the graph, one at the bottom of the y-axis (0%), one in the middle of the y-axis (50%) and one at the top (100%). All values in the array should be between 0 and 1. | +| **absolutePositions**: [Double] | An array of absolute positions where the reference lines should be placed. Used if `positionType == .absolute`. For example, assigning a value of [10, 35] will add 2 reference lines to the graph, one at the value of 10 on the y-axis, one at the value of 35 on the y-axis. | +| **includeMinMax**: Bool | Whether or not you want to render the minimum and maximum reference line. If this is true, the min and max reference lines are always rendered. Set this to false if you want to specify only one, or neither, with `relativePositions` or `absolutePositions`. | +| **referenceLineColor**: UIColor | The colour for the reference lines.| +| **referenceLineThickness**: CGFloat | The thickness of the reference lines.| +| **referenceLinePosition**: ScrollableGraphViewReferenceLinePosition | Where the labels should be displayed on the reference lines. Possible values:
  • `ScrollableGraphViewReferenceLinePosition.left`
  • `ScrollableGraphViewReferenceLinePosition.right`
  • `ScrollableGraphViewReferenceLinePosition.both`
| +| **shouldAddLabelsToIntermediateReferenceLines**: Bool | Whether or not to add labels to the intermediate (between min and max) reference lines.| +| **shouldAddUnitsToIntermediateReferenceLineLabels**: Bool | Whether or not to add units specified by the `referenceLineUnits` variable to the labels on the intermediate reference lines.| + +### Reference Line Labels (y-axis) + +| Property | Description | +|-------------------------------------------------------|-----------------------------------------------------------------------------------------| +| **referenceLineLabelFont**: UIFont | The font to be used for the reference line labels. | +| **referenceLineLabelColor**: UIColor | The colour of the reference line labels. | +| **shouldShowReferenceLineUnits**: Bool | Whether or not to show the units on the reference lines. | +| **referenceLineUnits**: String? | The units that the y-axis is in. This string is used for labels on the reference lines. | +| **referenceLineNumberOfDecimalPlaces**: Int | The number of decimal places that should be shown on the reference line labels. | +| **referenceLineNumberStyle**: NSNumberFormatterStyle | The number style that should be shown on the reference line labels. | + +### Data Point Labels (x-axis) + +| Property | Description | +|-----------------------------------------|-------------------------------------------------------------------------------------| +| **shouldShowLabels**: Bool | Whether or not to show the labels on the x-axis for each point. | +| **dataPointLabelTopMargin**: CGFloat | How far from the "minimum" reference line the data point labels should be rendered. | +| **dataPointLabelBottomMargin**: CGFloat | How far from the bottom of the view the data point labels should be rendered. | +| **dataPointLabelFont**: UIFont? | The font for the data point labels. | +| **dataPointLabelColor**: UIColor | The colour for the data point labels. | +| **dataPointLabelsSparsity**: Int | Used to force the graph to show every n-th dataPoint label | + + + +## Customisation Examples + +All of these examples can be seen in action in the example project: [graphview_example_code](graphview_example_code/) + +Open the project in Xcode and hit run. + +_Note: Examples here use a "colorFromHex" extension for UIColor._ + +### Default +![simple](readme_images/gallery-v4/simple.png) +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +let linePlot = LinePlot(identifier: "simple") // Identifier should be unique for each plot. +let referenceLines = ReferenceLines() + +graphView.addPlot(plot: linePlot) +graphView.addReferenceLines(referenceLines: referenceLines) +``` + +### Bar Dark (Bar layer thanks to [@RedBlueThing](https://twitter.com/RedBlueThing)) +![bar-dark](readme_images/gallery-v4/bar-dark.png) +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +// Setup the plot +let barPlot = BarPlot(identifier: "bar") + +barPlot.barWidth = 25 +barPlot.barLineWidth = 1 +barPlot.barLineColor = UIColor.colorFromHex(hexString: "#777777") +barPlot.barColor = UIColor.colorFromHex(hexString: "#555555") + +barPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic +barPlot.animationDuration = 1.5 + +// Setup the reference lines +let referenceLines = ReferenceLines() + +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2) +referenceLines.referenceLineLabelColor = UIColor.white + +referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5) + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333") + +graphView.shouldAnimateOnStartup = true + +graphView.rangeMax = 100 +graphView.rangeMin = 0 + +// Add everything +graphView.addPlot(plot: barPlot) +graphView.addReferenceLines(referenceLines: referenceLines) +return graphView +``` + +### Smooth Dark +![line-dark-smooth](readme_images/gallery-v4/line-dark-smooth.png) +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +// Setup the line plot. +let linePlot = LinePlot(identifier: "darkLine") + +linePlot.lineWidth = 1 +linePlot.lineColor = UIColor.colorFromHex(hexString: "#777777") +linePlot.lineStyle = ScrollableGraphViewLineStyle.smooth + +linePlot.shouldFill = true +linePlot.fillType = ScrollableGraphViewFillType.gradient +linePlot.fillGradientType = ScrollableGraphViewGradientType.linear +linePlot.fillGradientStartColor = UIColor.colorFromHex(hexString: "#555555") +linePlot.fillGradientEndColor = UIColor.colorFromHex(hexString: "#444444") + +linePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +let dotPlot = DotPlot(identifier: "darkLineDot") // Add dots as well. +dotPlot.dataPointSize = 2 +dotPlot.dataPointFillColor = UIColor.white + +dotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// Setup the reference lines. +let referenceLines = ReferenceLines() + +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2) +referenceLines.referenceLineLabelColor = UIColor.white + +referenceLines.positionType = .absolute +// Reference lines will be shown at these values on the y-axis. +referenceLines.absolutePositions = [10, 20, 25, 30] +referenceLines.includeMinMax = false + +referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5) + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333") +graphView.dataPointSpacing = 80 + +graphView.shouldAnimateOnStartup = true +graphView.shouldAdaptRange = true +graphView.shouldRangeAlwaysStartAtZero = true + +graphView.rangeMax = 50 + +// Add everything to the graph. +graphView.addReferenceLines(referenceLines: referenceLines) +graphView.addPlot(plot: linePlot) +graphView.addPlot(plot: dotPlot) +``` + + + +### Dot +![dot](readme_images/gallery-v4/dot.png) +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +// Setup the plot +let plot = DotPlot(identifier: "dot") + +plot.dataPointSize = 5 +plot.dataPointFillColor = UIColor.white + +// Setup the reference lines +let referenceLines = ReferenceLines() +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5) +referenceLines.referenceLineLabelColor = UIColor.white +referenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both + +referenceLines.shouldShowLabels = false + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#00BFFF") +graphView.shouldAdaptRange = false +graphView.shouldAnimateOnAdapt = false +graphView.shouldAnimateOnStartup = false + +graphView.dataPointSpacing = 25 +graphView.rangeMax = 50 +graphView.rangeMin = 0 + +// Add everything +graphView.addPlot(plot: plot) +graphView.addReferenceLines(referenceLines: referenceLines) +``` + +### Pink +![line-pink-straight](readme_images/gallery-v4/line-pink-straight.png) +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +// Setup the plot +let linePlot = LinePlot(identifier: "pinkLine") + +linePlot.lineColor = UIColor.clear +linePlot.shouldFill = true +linePlot.fillColor = UIColor.colorFromHex(hexString: "#FF0080") + +// Setup the reference lines +let referenceLines = ReferenceLines() + +referenceLines.referenceLineThickness = 1 +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5) +referenceLines.referenceLineLabelColor = UIColor.white +referenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both + +referenceLines.dataPointLabelFont = UIFont.boldSystemFont(ofSize: 10) +referenceLines.dataPointLabelColor = UIColor.white +referenceLines.dataPointLabelsSparsity = 3 + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#222222") + +graphView.dataPointSpacing = 60 +graphView.shouldAdaptRange = true + +// Add everything +graphView.addPlot(plot: linePlot) +graphView.addReferenceLines(referenceLines: referenceLines) +``` + +### Multiple Plots v1 +![multi-v1](readme_images/gallery-v4/multi1.png) +```swift +// Setup the line plot. +let blueLinePlot = LinePlot(identifier: "multiBlue") + +blueLinePlot.lineWidth = 1 +blueLinePlot.lineColor = UIColor.colorFromHex(hexString: "#16aafc") +blueLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth + +blueLinePlot.shouldFill = true +blueLinePlot.fillType = ScrollableGraphViewFillType.solid +blueLinePlot.fillColor = UIColor.colorFromHex(hexString: "#16aafc").withAlphaComponent(0.5) + +blueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// Setup the second line plot. +let orangeLinePlot = LinePlot(identifier: "multiOrange") + +orangeLinePlot.lineWidth = 1 +orangeLinePlot.lineColor = UIColor.colorFromHex(hexString: "#ff7d78") +orangeLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth + +orangeLinePlot.shouldFill = true +orangeLinePlot.fillType = ScrollableGraphViewFillType.solid +orangeLinePlot.fillColor = UIColor.colorFromHex(hexString: "#ff7d78").withAlphaComponent(0.5) + +orangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// Setup the reference lines. +let referenceLines = ReferenceLines() + +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2) +referenceLines.referenceLineLabelColor = UIColor.white + +referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1) + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333") + +graphView.dataPointSpacing = 80 +graphView.shouldAnimateOnStartup = true +graphView.shouldAdaptRange = true + +graphView.shouldRangeAlwaysStartAtZero = true + +// Add everything to the graph. +graphView.addReferenceLines(referenceLines: referenceLines) +graphView.addPlot(plot: blueLinePlot) +graphView.addPlot(plot: orangeLinePlot) +``` + +### Multiple Plots v2 + +It is possible to combine multiple plots to get different looks. We use the the dot plot to add markers to the line plot in this case: + +![multi-v2](readme_images/gallery-v4/multi2.png) + +```swift +let graphView = ScrollableGraphView(frame: frame, dataSource: self) + +// Setup the first plot. +let blueLinePlot = LinePlot(identifier: "multiBlue") + +blueLinePlot.lineColor = UIColor.colorFromHex(hexString: "#16aafc") +blueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// dots on the line +let blueDotPlot = DotPlot(identifier: "multiBlueDot") +blueDotPlot.dataPointType = ScrollableGraphViewDataPointType.circle +blueDotPlot.dataPointSize = 5 +blueDotPlot.dataPointFillColor = UIColor.colorFromHex(hexString: "#16aafc") + +blueDotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// Setup the second plot. +let orangeLinePlot = LinePlot(identifier: "multiOrange") + +orangeLinePlot.lineColor = UIColor.colorFromHex(hexString: "#ff7d78") +orangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// squares on the line +let orangeSquarePlot = DotPlot(identifier: "multiOrangeSquare") +orangeSquarePlot.dataPointType = ScrollableGraphViewDataPointType.square +orangeSquarePlot.dataPointSize = 5 +orangeSquarePlot.dataPointFillColor = UIColor.colorFromHex(hexString: "#ff7d78") + +orangeSquarePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic + +// Setup the reference lines. +let referenceLines = ReferenceLines() + +referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8) +referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2) +referenceLines.referenceLineLabelColor = UIColor.white +referenceLines.relativePositions = [0, 0.2, 0.4, 0.6, 0.8, 1] + +referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1) + +// Setup the graph +graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333") + +graphView.dataPointSpacing = 80 + +graphView.shouldAnimateOnStartup = true +graphView.shouldAdaptRange = true +graphView.shouldRangeAlwaysStartAtZero = true + +// Add everything to the graph. +graphView.addReferenceLines(referenceLines: referenceLines) +graphView.addPlot(plot: blueLinePlot) +graphView.addPlot(plot: blueDotPlot) +graphView.addPlot(plot: orangeLinePlot) +graphView.addPlot(plot: orangeSquarePlot) +``` + +## Known Issues + +- Some aspects of the graph cannot be customised _after_ it has been added to the view hierarchy. +- Reloading the graph with a different number of data items is currently not supported. +- Performance in the simulator is not great. + +If you find any bugs please create an issue on Github. + +## Other + +[Follow me on twitter](https://twitter.com/philackm) for interesting updates (read: gifs) about other things that I make. diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.markdown b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.markdown index 66d450f..f3a8ad5 100644 --- a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.markdown +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.markdown @@ -87,4 +87,54 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## ScrollableGraphView + +The MIT License (MIT) + +Copyright (c) 2016 Phillip + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +## XLPagerTabStrip + +The MIT License (MIT) + +Copyright (c) 2019 Xmartlabs SRL + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.plist b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.plist index 73c951d..ffeef2a 100644 --- a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.plist +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-acknowledgements.plist @@ -123,6 +123,68 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI Type PSGroupSpecifier
+ + FooterText + The MIT License (MIT) + +Copyright (c) 2016 Phillip + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + ScrollableGraphView + Type + PSGroupSpecifier + + + FooterText + The MIT License (MIT) + +Copyright (c) 2019 Xmartlabs SRL + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + XLPagerTabStrip + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-input-files.xcfilelist b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..a408c42 --- /dev/null +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,6 @@ +${PODS_ROOT}/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh +${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework +${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework +${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework +${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework +${BUILT_PRODUCTS_DIR}/ScrollableGraphView/ScrollableGraphView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-output-files.xcfilelist b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..74765c8 --- /dev/null +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1,5 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireObjectMapper.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ScrollableGraphView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-input-files.xcfilelist b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..a408c42 --- /dev/null +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,6 @@ +${PODS_ROOT}/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh +${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework +${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework +${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework +${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework +${BUILT_PRODUCTS_DIR}/ScrollableGraphView/ScrollableGraphView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-output-files.xcfilelist b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..74765c8 --- /dev/null +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks-Release-output-files.xcfilelist @@ -0,0 +1,5 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AlamofireObjectMapper.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ObjectMapper.framework +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ScrollableGraphView.framework \ No newline at end of file diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh index ac46bcb..0dfee72 100755 --- a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS-frameworks.sh @@ -157,12 +157,16 @@ if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework" install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework" install_framework "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework" + install_framework "${BUILT_PRODUCTS_DIR}/ScrollableGraphView/ScrollableGraphView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework" install_framework "${BUILT_PRODUCTS_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework" install_framework "${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework" install_framework "${BUILT_PRODUCTS_DIR}/ObjectMapper/ObjectMapper.framework" + install_framework "${BUILT_PRODUCTS_DIR}/ScrollableGraphView/ScrollableGraphView.framework" + install_framework "${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework" fi if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then wait diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.debug.xcconfig b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.debug.xcconfig index bac76ef..bc62f98 100644 --- a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.debug.xcconfig +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.debug.xcconfig @@ -1,9 +1,9 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/ScrollableGraphView" "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ScrollableGraphView/ScrollableGraphView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "AlamofireObjectMapper" -framework "CFNetwork" -framework "Kingfisher" -framework "ObjectMapper" +OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "AlamofireObjectMapper" -framework "CFNetwork" -framework "Foundation" -framework "Kingfisher" -framework "ObjectMapper" -framework "ScrollableGraphView" -framework "UIKit" -framework "XLPagerTabStrip" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.release.xcconfig b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.release.xcconfig index bac76ef..bc62f98 100644 --- a/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.release.xcconfig +++ b/Pods/Target Support Files/Pods-GetRestIOS/Pods-GetRestIOS.release.xcconfig @@ -1,9 +1,9 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper" "${PODS_CONFIGURATION_BUILD_DIR}/ScrollableGraphView" "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Alamofire/Alamofire.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/AlamofireObjectMapper/AlamofireObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ObjectMapper/ObjectMapper.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/ScrollableGraphView/ScrollableGraphView.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' -OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "AlamofireObjectMapper" -framework "CFNetwork" -framework "Kingfisher" -framework "ObjectMapper" +OTHER_LDFLAGS = $(inherited) -framework "Alamofire" -framework "AlamofireObjectMapper" -framework "CFNetwork" -framework "Foundation" -framework "Kingfisher" -framework "ObjectMapper" -framework "ScrollableGraphView" -framework "UIKit" -framework "XLPagerTabStrip" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-Info.plist b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-Info.plist new file mode 100644 index 0000000..ba03103 --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 4.0.6 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-dummy.m b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-dummy.m new file mode 100644 index 0000000..2c24358 --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_ScrollableGraphView : NSObject +@end +@implementation PodsDummy_ScrollableGraphView +@end diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-prefix.pch b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-umbrella.h b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-umbrella.h new file mode 100644 index 0000000..062e334 --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double ScrollableGraphViewVersionNumber; +FOUNDATION_EXPORT const unsigned char ScrollableGraphViewVersionString[]; + diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.modulemap b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.modulemap new file mode 100644 index 0000000..434060b --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.modulemap @@ -0,0 +1,6 @@ +framework module ScrollableGraphView { + umbrella header "ScrollableGraphView-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.xcconfig b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.xcconfig new file mode 100644 index 0000000..c8e7560 --- /dev/null +++ b/Pods/Target Support Files/ScrollableGraphView/ScrollableGraphView.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ScrollableGraphView +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/ScrollableGraphView +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist b/Pods/Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist new file mode 100644 index 0000000..885dc7a --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 9.0.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist new file mode 100644 index 0000000..ee83e4d --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 9.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-dummy.m b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-dummy.m new file mode 100644 index 0000000..a2a5f5d --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_XLPagerTabStrip : NSObject +@end +@implementation PodsDummy_XLPagerTabStrip +@end diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-umbrella.h b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-umbrella.h new file mode 100644 index 0000000..f2d3ecc --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-umbrella.h @@ -0,0 +1,17 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FXPageControl.h" + +FOUNDATION_EXPORT double XLPagerTabStripVersionNumber; +FOUNDATION_EXPORT const unsigned char XLPagerTabStripVersionString[]; + diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap new file mode 100644 index 0000000..999fe0e --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap @@ -0,0 +1,6 @@ +framework module XLPagerTabStrip { + umbrella header "XLPagerTabStrip-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig new file mode 100644 index 0000000..e20b2c3 --- /dev/null +++ b/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/XLPagerTabStrip +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Pods/XLPagerTabStrip/LICENSE b/Pods/XLPagerTabStrip/LICENSE new file mode 100644 index 0000000..fb6581a --- /dev/null +++ b/Pods/XLPagerTabStrip/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019 Xmartlabs SRL + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/XLPagerTabStrip/README.md b/Pods/XLPagerTabStrip/README.md new file mode 100644 index 0000000..d9d5e2b --- /dev/null +++ b/Pods/XLPagerTabStrip/README.md @@ -0,0 +1,345 @@ +# XLPagerTabStrip + +

+Build status +Platform iOS +Swift 5 compatible +Carthage compatible +CocoaPods compatible +License: MIT + + + +

+ +Made with ❤️ by [XMARTLABS](http://xmartlabs.com). + +Android [PagerTabStrip](http://developer.android.com/reference/android/support/v4/view/PagerTabStrip.html) for iOS! + +**XLPagerTabStrip** is a *Container View Controller* that allows us to switch easily among a collection of view controllers. Pan gesture can be used to move on to next or previous view controller. It shows a interactive indicator of the current, previous, next child view controllers. + + + + + + + + +
+ +## Getting involved + +* If you **want to contribute** please feel free to **submit pull requests**. +* If you **have a feature request** please **open an issue**. +* If you **found a bug** or **need help** please **check older issues, [FAQ](#faq) and threads on [StackOverflow](http://stackoverflow.com/questions/tagged/XLPagerTabStrip) (Tag 'XLPagerTabStrip') before submitting an issue**. + +**Before contribute check the [CONTRIBUTING](CONTRIBUTING.md) file for more info.** + +If you use **XLPagerTabStrip** in your app we would love to hear about it! Drop us a line on [twitter](https://twitter.com/xmartlabs). + +## Pager Types + +The library provides 4 different ways to show the view controllers. + +### Button Bar + +This is likely the most common pager type. It's used by many well-known apps such as instagram, youtube, skype, and many others. + + + +### Bar + +This mode doesn't show a title neither an image. It only shows a bar that indicates the current view controller. + + + +### Twitter + +A long time ago, the twitter app made use of this type of pager in the app main screen. + + + +### Segmented + +This mode uses a `UISegmentedControl` to indicate which view controller is being displayed. + + + +## Usage + +Basically, we just need to provide the list of child view controllers to show, and these view controllers should provide the information (title or image) that will be shown in the associated indicator. + +Let's see the steps to do this: + +##### Choose which type of pager we want to create + +First, we must choose the type of pager we want to create. Depending on our choice, we will have to create a view controller that extends from one of the following controllers: `TwitterPagerTabStripViewController`, `ButtonBarPagerTabStripViewController`, `SegmentedPagerTabStripViewController`, `BarPagerTabStripViewController`. + +> All these built-in pager controllers extend from the base class `PagerTabStripViewController`. +> You can also make your custom pager controller by extending directly from `PagerTabStripViewController` in the event that no pager menu type fits your needs. + +```swift +import XLPagerTabStrip + +class MyPagerTabStripName: ButtonBarPagerTabStripViewController { + .. +} +``` + +##### Connect outlets and add layout constraints + +We strongly recommend using IB to set up our page controller views. + +Drag a `UIViewController` into the storyboard and set up its class with your pager controller (`MyPagerTabStripName`). +Drag a `UIScrollView` into your view controller view and connect `PagerTabStripViewController` `containerView` outlet with the scroll view. + +Depending on which type of paging view controller you are working with you may have to connect more outlets. + +For `BarPagerTabStripViewController`, we should connect `barView` outlet. barView type is UIView. `ButtonBarPagerTabStripViewController` requires us to connect `buttonBarView` outlet. `buttonBarView` type is `ButtonBarView` which extends from `UICollectionView`. `SegmentedPagerTabStripViewController` has a `segmentedControl` outlet; if the outlet is not connected the library try to set up the navigationItem `titleView` property using a `UISegmentedControl`. `TwitterPagerTabStripViewController` doesn't require us to connect any additional outlet. + +> The example project contains a example for each pager controller type and we can look into it to see how views were added and how outlets were connected. + +##### Provide the view controllers that will appear embedded into the PagerTabStrip view controller + +You can provide the view controllers by overriding `func viewControllers(for: pagerTabStripController: PagerTabStripViewController) -> [UIViewController]` method. + +```swift +override public func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { + return [MyEmbeddedViewController(), MySecondEmbeddedViewController()] +} +``` + +> The method above is the only method declared in `PagerTabStripDataSource` protocol. We don't need to explicitly conform to it since base pager class already does it. + + +##### Provide information to show in each indicator + +Every UIViewController that will appear within the PagerTabStrip needs to provide either a title or an image. +In order to do so they should conform to `IndicatorInfoProvider` by implementing `func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo` + which provides the information required to show the PagerTabStrip menu (indicator) associated with the view controller. + +```swift +class MyEmbeddedViewController: UITableViewController, IndicatorInfoProvider { + + func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { + return IndicatorInfo(title: "My Child title") + } +} +``` + +**For a detailed step-by-step guide about how to use the library, please check out this community [blog post](https://medium.com/michaeladeyeri/how-to-implement-android-like-tab-layouts-in-ios-using-swift-3-578516c3aa9).** + +That's it! We're done! 🍻🍻 + + +## Customization + +##### Pager Behaviour + +The pager indicator can be updated progressive as we swipe or at once in the middle of the transition between the view controllers. +By setting up `pagerBehaviour` property we can choose how the indicator should be updated. + +```swift +public var pagerBehaviour: PagerTabStripBehaviour +``` + +```swift +public enum PagerTabStripBehaviour { + case common(skipIntermediteViewControllers: Bool) + case progressive(skipIntermediteViewControllers: Bool, elasticIndicatorLimit: Bool) +} +``` + +Default Values: +```swift +// Twitter Type +PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) +// Segmented Type +PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) +// Bar Type +PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) +// ButtonBar Type +PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) +``` + +As you might have noticed, `common` and `progressive` enumeration cases have `skipIntermediateViewControllers` and `elasticIndicatorLimit` associated values. + +`skipIntermediateViewControllers` allows us to skip intermediate view controllers when a tab indicator is tapped. + +`elasticIndicatorLimit` allows us to tension the indicator when we reach a limit, I mean when we try to move forward from last indicator or move back from first indicator. + +##### PagerTabStripDelegate & PagerTabStripIsProgressiveDelegate + +Normally we don't need to implement these protocols because each pager type already conforms to it in order to properly update its indicator. However, there may be some scenarios when overriding a method may come in handy. + +```swift +public protocol PagerTabStripDelegate: class { + + func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) +} + +public protocol PagerTabStripIsProgressiveDelegate : PagerTabStripDelegate { + + func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) +} +``` + +> Again, the method invoked by the library depends on the `pagerBehaviour` value. + + + + +### ButtonBar Customization + +```swift + +settings.style.buttonBarBackgroundColor: UIColor? +// buttonBar minimumInteritemSpacing value, note that button bar extends from UICollectionView +settings.style.buttonBarMinimumInteritemSpacing: CGFloat? +// buttonBar minimumLineSpacing value +settings.style.buttonBarMinimumLineSpacing: CGFloat? +// buttonBar flow layout left content inset value +settings.style.buttonBarLeftContentInset: CGFloat? +// buttonBar flow layout right content inset value +settings.style.buttonBarRightContentInset: CGFloat? + +// selected bar view is created programmatically so it's important to set up the following 2 properties properly +settings.style.selectedBarBackgroundColor = UIColor.black +settings.style.selectedBarHeight: CGFloat = 5 + +// each buttonBar item is a UICollectionView cell of type ButtonBarViewCell +settings.style.buttonBarItemBackgroundColor: UIColor? +settings.style.buttonBarItemFont = UIFont.systemFont(ofSize: 18) +// helps to determine the cell width, it represent the space before and after the title label +settings.style.buttonBarItemLeftRightMargin: CGFloat = 8 +settings.style.buttonBarItemTitleColor: UIColor? +// in case the barView items do not fill the screen width this property stretch the cells to fill the screen +settings.style.buttonBarItemsShouldFillAvailiableWidth = true +// only used if button bar is created programmatically and not using storyboards or nib files as recommended. +public var buttonBarHeight: CGFloat? +``` + +**Important:** Settings should be called before `viewDidLoad` is called. +```swift +override func viewDidLoad() { + self.settings.style.selectedBarHeight = 2 + self.settings.style.selectedBarBackgroundColor = UIColor.white + + super.viewDidLoad() +} +``` + +##### Update cells when selected indicator changes + +We may need to update the indicator cell when the displayed view controller changes. The following function properties help to accomplish that. Depending on our pager `pagerBehaviour` value we will have to set up `changeCurrentIndex` or `changeCurrentIndexProgressive`. + +```swift +public var changeCurrentIndex: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, animated: Bool) -> Void)? +public var changeCurrentIndexProgressive: ((oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void)? +``` + +Let's see an example: + +```swift +changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in + guard changeCurrentIndex == true else { return } + + oldCell?.label.textColor = UIColor(white: 1, alpha: 0.6) + newCell?.label.textColor = UIColor.white + + if animated { + UIView.animate(withDuration: 0.1, animations: { () -> Void in + newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) + oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) + }) + } + else { + newCell?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) + oldCell?.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) + } +} +``` + +### Bar Type Customization + +```swift +settings.style.barBackgroundColor: UIColor? +settings.style.selectedBarBackgroundColor: UIColor? +// barHeight is only set up when the bar is created programmatically and not using storyboards or xib files as recommended. +settings.style.barHeight: CGFloat = 5 +``` + +### Twitter Type Customization + +```swift +settings.style.dotColor = UIColor(white: 1, alpha: 0.4) +settings.style.selectedDotColor = UIColor.white +settings.style.portraitTitleFont = UIFont.systemFont(ofSize: 18) +settings.style.landscapeTitleFont = UIFont.systemFont(ofSize: 15) +settings.style.titleColor = UIColor.white +``` + +### Segmented Type Customization + +```swift +settings.style.segmentedControlColor: UIColor? +``` + + + +## Requirements + +* iOS 9.3+ +* Xcode 10.2+ + +## Examples + +Follow these 3 steps to run Example project: Clone XLPagerTabStrip repository, open XLPagerTabStrip workspace and run the *Example* project. + +## Installation + +### CocoaPods + +[CocoaPods](https://cocoapods.org/) is a dependency manager for Cocoa projects. + +To install XLPagerTabStrip, simply add the following line to your Podfile: + +```ruby +pod 'XLPagerTabStrip', '~> 9.0' +``` + +### Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a simple, decentralized dependency manager for Cocoa. + +To install XLPagerTabStrip, simply add the following line to your Cartfile: + +```ogdl +github "xmartlabs/XLPagerTabStrip" ~> 9.0 +``` + +## FAQ + +#### How to change the visible child view controller programmatically + +`PagerTabStripViewController` provides the following methods to programmatically change the visible child view controller: + +```swift +func moveToViewController(at index: Int) +func moveToViewController(at index: Int, animated: Bool) +func moveTo(viewController: UIViewController) +func moveTo(viewController: UIViewController, animated: Bool) +``` + + +#### How to migrate from Swift 2 to Swift 3 + +Check out [our migration guide](https://github.com/xmartlabs/XLPagerTabStrip/blob/master/Migration.md) + +## Author + +* [Martin Barreto](https://github.com/mtnBarreto) ([@mtnBarreto](https://twitter.com/mtnBarreto)) + +## Change Log + +This can be found in the [CHANGELOG.md](CHANGELOG.md) file. diff --git a/Pods/XLPagerTabStrip/Sources/BarPagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/BarPagerTabStripViewController.swift new file mode 100644 index 0000000..e231268 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/BarPagerTabStripViewController.swift @@ -0,0 +1,98 @@ +// BarPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import UIKit + +public struct BarPagerTabStripSettings { + + public struct Style { + public var barBackgroundColor: UIColor? + public var selectedBarBackgroundColor: UIColor? + public var barHeight: CGFloat = 5 // barHeight is ony set up when the bar is created programatically and not using storyboards or xib files. + } + + public var style = Style() +} + +open class BarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate { + + public var settings = BarPagerTabStripSettings() + + @IBOutlet weak public var barView: BarView! + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + open override func viewDidLoad() { + super.viewDidLoad() + barView = barView ?? { + let barView = BarView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: settings.style.barHeight)) + barView.autoresizingMask = .flexibleWidth + barView.backgroundColor = .black + barView.selectedBar.backgroundColor = .white + return barView + }() + + barView.backgroundColor = settings.style.barBackgroundColor ?? barView.backgroundColor + barView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor ?? barView.selectedBar.backgroundColor + } + + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if barView.superview == nil { + view.addSubview(barView) + } + barView.optionsCount = viewControllers.count + barView.moveTo(index: currentIndex, animated: false) + } + + open override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + barView.optionsCount = viewControllers.count + if isViewLoaded { + barView.moveTo(index: currentIndex, animated: false) + } + } + + // MARK: - PagerTabStripDelegate + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { + + barView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage) + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { + barView.moveTo(index: toIndex, animated: true) + } +} diff --git a/Pods/XLPagerTabStrip/Sources/BarView.swift b/Pods/XLPagerTabStrip/Sources/BarView.swift new file mode 100644 index 0000000..1183524 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/BarView.swift @@ -0,0 +1,91 @@ +// BarView.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class BarView: UIView { + + open lazy var selectedBar: UIView = { [unowned self] in + let selectedBar = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)) + return selectedBar + }() + + var optionsCount = 1 { + willSet(newOptionsCount) { + if newOptionsCount <= selectedIndex { + selectedIndex = optionsCount - 1 + } + } + } + var selectedIndex = 0 + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + addSubview(selectedBar) + } + + override init(frame: CGRect) { + super.init(frame: frame) + addSubview(selectedBar) + } + + // MARK: - Helpers + + private func updateSelectedBarPosition(with animation: Bool) { + var frame = selectedBar.frame + frame.size.width = self.frame.size.width / CGFloat(optionsCount) + frame.origin.x = frame.size.width * CGFloat(selectedIndex) + if animation { + UIView.animate(withDuration: 0.3, animations: { [weak self] in + self?.selectedBar.frame = frame + }) + } else { + selectedBar.frame = frame + } + } + + open func moveTo(index: Int, animated: Bool) { + selectedIndex = index + updateSelectedBarPosition(with: animated) + } + + open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat) { + selectedIndex = (progressPercentage > 0.5) ? toIndex : fromIndex + + var newFrame = selectedBar.frame + newFrame.size.width = frame.size.width / CGFloat(optionsCount) + var fromFrame = newFrame + fromFrame.origin.x = newFrame.size.width * CGFloat(fromIndex) + var toFrame = newFrame + toFrame.origin.x = toFrame.size.width * CGFloat(toIndex) + var targetFrame = fromFrame + targetFrame.origin.x += (toFrame.origin.x - targetFrame.origin.x) * CGFloat(progressPercentage) + selectedBar.frame = targetFrame + } + + open override func layoutSubviews() { + super.layoutSubviews() + updateSelectedBarPosition(with: false) + } +} diff --git a/Pods/XLPagerTabStrip/Sources/BaseButtonBarPagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/BaseButtonBarPagerTabStripViewController.swift new file mode 100644 index 0000000..68684ac --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/BaseButtonBarPagerTabStripViewController.swift @@ -0,0 +1,352 @@ +// BaseButtonBarPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +open class BaseButtonBarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { + + public var settings = ButtonBarPagerTabStripSettings() + public var buttonBarItemSpec: ButtonBarItemSpec! + public var changeCurrentIndex: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ animated: Bool) -> Void)? + public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarCellType?, _ newCell: ButtonBarCellType?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)? + + @IBOutlet public weak var buttonBarView: ButtonBarView! + + lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in + return self.calculateWidths() + }() + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + + open override func viewDidLoad() { + super.viewDidLoad() + let buttonBarViewAux = buttonBarView ?? { + let flowLayout = UICollectionViewFlowLayout() + flowLayout.scrollDirection = .horizontal + flowLayout.sectionInset = UIEdgeInsets(top: 0, left: settings.style.buttonBarLeftContentInset ?? 35, bottom: 0, right: settings.style.buttonBarRightContentInset ?? 35) + let buttonBarHeight = settings.style.buttonBarHeight ?? 44 + let buttonBar = ButtonBarView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: buttonBarHeight), collectionViewLayout: flowLayout) + buttonBar.backgroundColor = .orange + buttonBar.selectedBar.backgroundColor = .black + buttonBar.autoresizingMask = .flexibleWidth + var newContainerViewFrame = containerView.frame + newContainerViewFrame.origin.y = buttonBarHeight + newContainerViewFrame.size.height = containerView.frame.size.height - (buttonBarHeight - containerView.frame.origin.y) + containerView.frame = newContainerViewFrame + return buttonBar + }() + buttonBarView = buttonBarViewAux + + if buttonBarView.superview == nil { + view.addSubview(buttonBarView) + } + if buttonBarView.delegate == nil { + buttonBarView.delegate = self + } + if buttonBarView.dataSource == nil { + buttonBarView.dataSource = self + } + buttonBarView.scrollsToTop = false + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + flowLayout.scrollDirection = .horizontal + flowLayout.minimumInteritemSpacing = settings.style.buttonBarMinimumInteritemSpacing ?? flowLayout.minimumInteritemSpacing + flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing + let sectionInset = flowLayout.sectionInset + flowLayout.sectionInset = UIEdgeInsets(top: sectionInset.top, left: settings.style.buttonBarLeftContentInset ?? sectionInset.left, bottom: sectionInset.bottom, right: settings.style.buttonBarRightContentInset ?? sectionInset.right) + buttonBarView.showsHorizontalScrollIndicator = false + buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor + buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor + buttonBarView.selectedBarVerticalAlignment = settings.style.selectedBarVerticalAlignment + buttonBarView.selectedBarHeight = settings.style.selectedBarHeight + // register button bar item cell + switch buttonBarItemSpec! { + case .nibFile(let nibName, let bundle, _): + buttonBarView.register(UINib(nibName: nibName, bundle: bundle), forCellWithReuseIdentifier:"Cell") + case .cellClass: + buttonBarView.register(ButtonBarCellType.self, forCellWithReuseIdentifier:"Cell") + } + //- + } + + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + buttonBarView.layoutIfNeeded() + isViewAppearing = true + } + + open override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + isViewAppearing = false + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + guard isViewAppearing || isViewRotating else { return } + + // Force the UICollectionViewFlowLayout to get laid out again with the new size if + // a) The view is appearing. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called for a second time + // when the view is shown and when the view *frame(s)* are actually set + // (we need the view frame's to have been set to work out the size's and on the + // first call to collectionView:layout:sizeForItemAtIndexPath: the view frame(s) + // aren't set correctly) + // b) The view is rotating. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called again and can use the views + // *new* frame so that the buttonBarView cell's actually get resized correctly + cachedCellWidths = calculateWidths() + buttonBarView.collectionViewLayout.invalidateLayout() + // When the view first appears or is rotated we also need to ensure that the barButtonView's + // selectedBar is resized and its contentOffset/scroll is set correctly (the selected + // tab/cell may end up either skewed or off screen after a rotation otherwise) + buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen) + buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: []) + } + + // MARK: - View Rotation + + open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + } + + // MARK: - Public Methods + + open override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + guard isViewLoaded else { return } + buttonBarView.reloadData() + cachedCellWidths = calculateWidths() + buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes) + } + + open func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat { + var numberOfLargeCells = 0 + var totalWidthOfLargeCells: CGFloat = 0 + + for minimumCellWidthValue in minimumCellWidths where minimumCellWidthValue > suggestedStretchedCellWidth { + totalWidthOfLargeCells += minimumCellWidthValue + numberOfLargeCells += 1 + } + + guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth } + + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + let numberOfCells = minimumCellWidths.count + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing + + let numberOfSmallCells = numberOfCells - numberOfLargeCells + let newSuggestedStretchedCellWidth = (collectionViewAvailiableWidth - totalWidthOfLargeCells - cellSpacingTotal) / CGFloat(numberOfSmallCells) + + return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells) + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { + guard shouldUpdateButtonBarView else { return } + buttonBarView.moveTo(index: toIndex, animated: true, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes) + + if let changeCurrentIndex = changeCurrentIndex { + let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)) as? ButtonBarCellType + let newCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarCellType + changeCurrentIndex(oldCell, newCell, true) + } + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { + guard shouldUpdateButtonBarView else { return } + buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes) + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0)) as? ButtonBarCellType + let newCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarCellType + changeCurrentIndexProgressive(oldCell, newCell, progressPercentage, indexWasChanged, true) + } + } + + // MARK: - UICollectionViewDelegateFlowLayut + + @objc open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { + guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { + fatalError("cachedCellWidths for \(indexPath.row) must not be nil") + } + return CGSize(width: cellWidthValue, height: collectionView.frame.size.height) + } + + open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard indexPath.item != currentIndex else { return } + + buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes) + shouldUpdateButtonBarView = false + + let oldCell = buttonBarView.cellForItem(at: IndexPath(item: currentIndex, section: 0)) as? ButtonBarCellType + let newCell = buttonBarView.cellForItem(at: IndexPath(item: indexPath.item, section: 0)) as? ButtonBarCellType + if pagerBehaviour.isProgressiveIndicator { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(oldCell, newCell, 1, true, true) + } + } else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(oldCell, newCell, true) + } + } + moveToViewController(at: indexPath.item) + } + + // MARK: - UICollectionViewDataSource + + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return viewControllers.count + } + + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarCellType else { + fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") + } + let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast + let indicatorInfo = childController.indicatorInfo(for: self) + + configure(cell: cell, for: indicatorInfo) + + if pagerBehaviour.isProgressiveIndicator { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false) + } + } else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false) + } + } + + return cell + } + + // MARK: - UIScrollViewDelegate + + open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + super.scrollViewDidEndScrollingAnimation(scrollView) + + guard scrollView == containerView else { return } + shouldUpdateButtonBarView = true + } + + open func configure(cell: ButtonBarCellType, for indicatorInfo: IndicatorInfo) { + fatalError("You must override this method to set up ButtonBarView cell accordingly") + } + + private func calculateWidths() -> [CGFloat] { + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + let numberOfCells = viewControllers.count + + var minimumCellWidths = [CGFloat]() + var collectionViewContentWidth: CGFloat = 0 + + for viewController in viewControllers { + let childController = viewController as! IndicatorInfoProvider // swiftlint:disable:this force_cast + let indicatorInfo = childController.indicatorInfo(for: self) + switch buttonBarItemSpec! { + case .cellClass(let widthCallback): + let width = widthCallback(indicatorInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + case .nibFile(_, _, let widthCallback): + let width = widthCallback(indicatorInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + } + } + + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing + collectionViewContentWidth += cellSpacingTotal + + let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + + if !settings.style.buttonBarItemsShouldFillAvailableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth { + return minimumCellWidths + } else { + let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells) + let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0) + var stretchedCellWidths = [CGFloat]() + + for minimumCellWidthValue in minimumCellWidths { + let cellWidth = (minimumCellWidthValue > generalMinimumCellWidth) ? minimumCellWidthValue : generalMinimumCellWidth + stretchedCellWidths.append(cellWidth) + } + + return stretchedCellWidths + } + } + + private var shouldUpdateButtonBarView = true +} + +open class ExampleBaseButtonBarPagerTabStripViewController: BaseButtonBarPagerTabStripViewController { + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + initialize() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + initialize() + } + + open func initialize() { + var bundle = Bundle(for: ButtonBarViewCell.self) + if let resourcePath = bundle.path(forResource: "XLPagerTabStrip", ofType: "bundle") { + if let resourcesBundle = Bundle(path: resourcePath) { + bundle = resourcesBundle + } + } + + buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: bundle, width: { [weak self] (childItemInfo) -> CGFloat in + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = self?.settings.style.buttonBarItemFont ?? label.font + label.text = childItemInfo.title + let labelSize = label.intrinsicContentSize + return labelSize.width + CGFloat(self?.settings.style.buttonBarItemLeftRightMargin ?? 8 * 2) + }) + } + + open override func configure(cell: ButtonBarViewCell, for indicatorInfo: IndicatorInfo) { + cell.label.text = indicatorInfo.title + cell.accessibilityLabel = indicatorInfo.accessibilityLabel + if let image = indicatorInfo.image { + cell.imageView.image = image + } + if let highlightedImage = indicatorInfo.highlightedImage { + cell.imageView.highlightedImage = highlightedImage + } + } +} diff --git a/Pods/XLPagerTabStrip/Sources/ButtonBarPagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/ButtonBarPagerTabStripViewController.swift new file mode 100644 index 0000000..36e008d --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/ButtonBarPagerTabStripViewController.swift @@ -0,0 +1,405 @@ +// ButtonBarPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public enum ButtonBarItemSpec { + + case nibFile(nibName: String, bundle: Bundle?, width:((IndicatorInfo)-> CGFloat)) + case cellClass(width:((IndicatorInfo)-> CGFloat)) + + public var weight: ((IndicatorInfo) -> CGFloat) { + switch self { + case .cellClass(let widthCallback): + return widthCallback + case .nibFile(_, _, let widthCallback): + return widthCallback + } + } +} + +public struct ButtonBarPagerTabStripSettings { + + public struct Style { + public var buttonBarBackgroundColor: UIColor? + public var buttonBarMinimumInteritemSpacing: CGFloat? + public var buttonBarMinimumLineSpacing: CGFloat? + public var buttonBarLeftContentInset: CGFloat? + public var buttonBarRightContentInset: CGFloat? + + public var selectedBarBackgroundColor = UIColor.black + public var selectedBarHeight: CGFloat = 5 + public var selectedBarVerticalAlignment: SelectedBarVerticalAlignment = .bottom + + public var buttonBarItemBackgroundColor: UIColor? + public var buttonBarItemFont = UIFont.systemFont(ofSize: 18) + public var buttonBarItemLeftRightMargin: CGFloat = 8 + public var buttonBarItemTitleColor: UIColor? + public var buttonBarItemsShouldFillAvailableWidth = true + // only used if button bar is created programaticaly and not using storyboards or nib files + public var buttonBarHeight: CGFloat? + } + + public var style = Style() +} + +open class ButtonBarPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate, UICollectionViewDelegate, UICollectionViewDataSource { + + public var settings = ButtonBarPagerTabStripSettings() + + public var buttonBarItemSpec: ButtonBarItemSpec! + + public var changeCurrentIndex: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ animated: Bool) -> Void)? + public var changeCurrentIndexProgressive: ((_ oldCell: ButtonBarViewCell?, _ newCell: ButtonBarViewCell?, _ progressPercentage: CGFloat, _ changeCurrentIndex: Bool, _ animated: Bool) -> Void)? + + @IBOutlet public weak var buttonBarView: ButtonBarView! + + lazy private var cachedCellWidths: [CGFloat]? = { [unowned self] in + return self.calculateWidths() + }() + + override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + delegate = self + datasource = self + } + + open override func viewDidLoad() { + super.viewDidLoad() + + var bundle = Bundle(for: ButtonBarViewCell.self) + if let resourcePath = bundle.path(forResource: "XLPagerTabStrip", ofType: "bundle") { + if let resourcesBundle = Bundle(path: resourcePath) { + bundle = resourcesBundle + } + } + + buttonBarItemSpec = .nibFile(nibName: "ButtonCell", bundle: bundle, width: { [weak self] (childItemInfo) -> CGFloat in + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.font = self?.settings.style.buttonBarItemFont + label.text = childItemInfo.title + let labelSize = label.intrinsicContentSize + return labelSize.width + (self?.settings.style.buttonBarItemLeftRightMargin ?? 8) * 2 + }) + + let buttonBarViewAux = buttonBarView ?? { + let flowLayout = UICollectionViewFlowLayout() + flowLayout.scrollDirection = .horizontal + let buttonBarHeight = settings.style.buttonBarHeight ?? 44 + let buttonBar = ButtonBarView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: buttonBarHeight), collectionViewLayout: flowLayout) + buttonBar.backgroundColor = .orange + buttonBar.selectedBar.backgroundColor = .black + buttonBar.autoresizingMask = .flexibleWidth + var newContainerViewFrame = containerView.frame + newContainerViewFrame.origin.y = buttonBarHeight + newContainerViewFrame.size.height = containerView.frame.size.height - (buttonBarHeight - containerView.frame.origin.y) + containerView.frame = newContainerViewFrame + return buttonBar + }() + buttonBarView = buttonBarViewAux + + if buttonBarView.superview == nil { + view.addSubview(buttonBarView) + } + if buttonBarView.delegate == nil { + buttonBarView.delegate = self + } + if buttonBarView.dataSource == nil { + buttonBarView.dataSource = self + } + buttonBarView.scrollsToTop = false + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + flowLayout.scrollDirection = .horizontal + flowLayout.minimumInteritemSpacing = settings.style.buttonBarMinimumInteritemSpacing ?? flowLayout.minimumInteritemSpacing + flowLayout.minimumLineSpacing = settings.style.buttonBarMinimumLineSpacing ?? flowLayout.minimumLineSpacing + let sectionInset = flowLayout.sectionInset + flowLayout.sectionInset = UIEdgeInsets(top: sectionInset.top, left: settings.style.buttonBarLeftContentInset ?? sectionInset.left, bottom: sectionInset.bottom, right: settings.style.buttonBarRightContentInset ?? sectionInset.right) + + buttonBarView.showsHorizontalScrollIndicator = false + buttonBarView.backgroundColor = settings.style.buttonBarBackgroundColor ?? buttonBarView.backgroundColor + buttonBarView.selectedBar.backgroundColor = settings.style.selectedBarBackgroundColor + + buttonBarView.selectedBarHeight = settings.style.selectedBarHeight + buttonBarView.selectedBarVerticalAlignment = settings.style.selectedBarVerticalAlignment + + // register button bar item cell + switch buttonBarItemSpec! { + case .nibFile(let nibName, let bundle, _): + buttonBarView.register(UINib(nibName: nibName, bundle: bundle), forCellWithReuseIdentifier:"Cell") + case .cellClass: + buttonBarView.register(ButtonBarViewCell.self, forCellWithReuseIdentifier:"Cell") + } + //- + } + + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + buttonBarView.layoutIfNeeded() + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + guard isViewAppearing || isViewRotating else { return } + + // Force the UICollectionViewFlowLayout to get laid out again with the new size if + // a) The view is appearing. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called for a second time + // when the view is shown and when the view *frame(s)* are actually set + // (we need the view frame's to have been set to work out the size's and on the + // first call to collectionView:layout:sizeForItemAtIndexPath: the view frame(s) + // aren't set correctly) + // b) The view is rotating. This ensures that + // collectionView:layout:sizeForItemAtIndexPath: is called again and can use the views + // *new* frame so that the buttonBarView cell's actually get resized correctly + cachedCellWidths = calculateWidths() + buttonBarView.collectionViewLayout.invalidateLayout() + // When the view first appears or is rotated we also need to ensure that the barButtonView's + // selectedBar is resized and its contentOffset/scroll is set correctly (the selected + // tab/cell may end up either skewed or off screen after a rotation otherwise) + buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .scrollOnlyIfOutOfScreen) + buttonBarView.selectItem(at: IndexPath(item: currentIndex, section: 0), animated: false, scrollPosition: []) + } + + // MARK: - Public Methods + + open override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + guard isViewLoaded else { return } + buttonBarView.reloadData() + cachedCellWidths = calculateWidths() + buttonBarView.moveTo(index: currentIndex, animated: false, swipeDirection: .none, pagerScroll: .yes) + } + + open func calculateStretchedCellWidths(_ minimumCellWidths: [CGFloat], suggestedStretchedCellWidth: CGFloat, previousNumberOfLargeCells: Int) -> CGFloat { + var numberOfLargeCells = 0 + var totalWidthOfLargeCells: CGFloat = 0 + + for minimumCellWidthValue in minimumCellWidths where minimumCellWidthValue > suggestedStretchedCellWidth { + totalWidthOfLargeCells += minimumCellWidthValue + numberOfLargeCells += 1 + } + + guard numberOfLargeCells > previousNumberOfLargeCells else { return suggestedStretchedCellWidth } + + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + let collectionViewAvailiableWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + let numberOfCells = minimumCellWidths.count + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing + + let numberOfSmallCells = numberOfCells - numberOfLargeCells + let newSuggestedStretchedCellWidth = (collectionViewAvailiableWidth - totalWidthOfLargeCells - cellSpacingTotal) / CGFloat(numberOfSmallCells) + + return calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: newSuggestedStretchedCellWidth, previousNumberOfLargeCells: numberOfLargeCells) + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { + guard shouldUpdateButtonBarView else { return } + buttonBarView.moveTo(index: toIndex, animated: false, swipeDirection: toIndex < fromIndex ? .right : .left, pagerScroll: .yes) + + if let changeCurrentIndex = changeCurrentIndex { + let oldIndexPath = IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0) + let newIndexPath = IndexPath(item: currentIndex, section: 0) + + let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad) + changeCurrentIndex(cells.first!, cells.last!, true) + } + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { + guard shouldUpdateButtonBarView else { return } + buttonBarView.move(fromIndex: fromIndex, toIndex: toIndex, progressPercentage: progressPercentage, pagerScroll: .yes) + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + let oldIndexPath = IndexPath(item: currentIndex != fromIndex ? fromIndex : toIndex, section: 0) + let newIndexPath = IndexPath(item: currentIndex, section: 0) + + let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad) + changeCurrentIndexProgressive(cells.first!, cells.last!, progressPercentage, indexWasChanged, true) + } + } + + private func cellForItems(at indexPaths: [IndexPath], reloadIfNotVisible reload: Bool = true) -> [ButtonBarViewCell?] { + let cells = indexPaths.map { buttonBarView.cellForItem(at: $0) as? ButtonBarViewCell } + + if reload { + let indexPathsToReload = cells.enumerated() + .compactMap { (arg) -> IndexPath? in + let (index, cell) = arg + return cell == nil ? indexPaths[index] : nil + } + .compactMap { (indexPath: IndexPath) -> IndexPath? in + return (indexPath.item >= 0 && indexPath.item < buttonBarView.numberOfItems(inSection: indexPath.section)) ? indexPath : nil + } + + if !indexPathsToReload.isEmpty { + buttonBarView.reloadItems(at: indexPathsToReload) + } + } + + return cells + } + + // MARK: - UICollectionViewDelegateFlowLayut + + @objc open func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize { + guard let cellWidthValue = cachedCellWidths?[indexPath.row] else { + fatalError("cachedCellWidths for \(indexPath.row) must not be nil") + } + return CGSize(width: cellWidthValue, height: collectionView.frame.size.height) + } + + open func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard indexPath.item != currentIndex else { return } + + buttonBarView.moveTo(index: indexPath.item, animated: true, swipeDirection: .none, pagerScroll: .yes) + shouldUpdateButtonBarView = false + + let oldIndexPath = IndexPath(item: currentIndex, section: 0) + let newIndexPath = IndexPath(item: indexPath.item, section: 0) + + let cells = cellForItems(at: [oldIndexPath, newIndexPath], reloadIfNotVisible: collectionViewDidLoad) + + if pagerBehaviour.isProgressiveIndicator { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(cells.first!, cells.last!, 1, true, true) + } + } else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(cells.first!, cells.last!, true) + } + } + moveToViewController(at: indexPath.item) + } + + // MARK: - UICollectionViewDataSource + + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return viewControllers.count + } + + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? ButtonBarViewCell else { + fatalError("UICollectionViewCell should be or extend from ButtonBarViewCell") + } + + collectionViewDidLoad = true + + let childController = viewControllers[indexPath.item] as! IndicatorInfoProvider // swiftlint:disable:this force_cast + let indicatorInfo = childController.indicatorInfo(for: self) + + cell.label.text = indicatorInfo.title + cell.label.font = settings.style.buttonBarItemFont + cell.label.textColor = settings.style.buttonBarItemTitleColor ?? cell.label.textColor + cell.contentView.backgroundColor = settings.style.buttonBarItemBackgroundColor ?? cell.contentView.backgroundColor + cell.backgroundColor = settings.style.buttonBarItemBackgroundColor ?? cell.backgroundColor + if let image = indicatorInfo.image { + cell.imageView.image = image + } + if let highlightedImage = indicatorInfo.highlightedImage { + cell.imageView.highlightedImage = highlightedImage + } + + configureCell(cell, indicatorInfo: indicatorInfo) + + if pagerBehaviour.isProgressiveIndicator { + if let changeCurrentIndexProgressive = changeCurrentIndexProgressive { + changeCurrentIndexProgressive(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, 1, true, false) + } + } else { + if let changeCurrentIndex = changeCurrentIndex { + changeCurrentIndex(currentIndex == indexPath.item ? nil : cell, currentIndex == indexPath.item ? cell : nil, false) + } + } + cell.isAccessibilityElement = true + cell.accessibilityLabel = indicatorInfo.accessibilityLabel ?? cell.label.text + cell.accessibilityTraits.insert([.button, .header]) + return cell + } + + // MARK: - UIScrollViewDelegate + + open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + super.scrollViewDidEndScrollingAnimation(scrollView) + + guard scrollView == containerView else { return } + shouldUpdateButtonBarView = true + } + + open func configureCell(_ cell: ButtonBarViewCell, indicatorInfo: IndicatorInfo) { + } + + private func calculateWidths() -> [CGFloat] { + let flowLayout = buttonBarView.collectionViewLayout as! UICollectionViewFlowLayout // swiftlint:disable:this force_cast + let numberOfCells = viewControllers.count + + var minimumCellWidths = [CGFloat]() + var collectionViewContentWidth: CGFloat = 0 + + for viewController in viewControllers { + let childController = viewController as! IndicatorInfoProvider // swiftlint:disable:this force_cast + let indicatorInfo = childController.indicatorInfo(for: self) + switch buttonBarItemSpec! { + case .cellClass(let widthCallback): + let width = widthCallback(indicatorInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + case .nibFile(_, _, let widthCallback): + let width = widthCallback(indicatorInfo) + minimumCellWidths.append(width) + collectionViewContentWidth += width + } + } + + let cellSpacingTotal = CGFloat(numberOfCells - 1) * flowLayout.minimumLineSpacing + collectionViewContentWidth += cellSpacingTotal + + let collectionViewAvailableVisibleWidth = buttonBarView.frame.size.width - flowLayout.sectionInset.left - flowLayout.sectionInset.right + + if !settings.style.buttonBarItemsShouldFillAvailableWidth || collectionViewAvailableVisibleWidth < collectionViewContentWidth { + return minimumCellWidths + } else { + let stretchedCellWidthIfAllEqual = (collectionViewAvailableVisibleWidth - cellSpacingTotal) / CGFloat(numberOfCells) + let generalMinimumCellWidth = calculateStretchedCellWidths(minimumCellWidths, suggestedStretchedCellWidth: stretchedCellWidthIfAllEqual, previousNumberOfLargeCells: 0) + var stretchedCellWidths = [CGFloat]() + + for minimumCellWidthValue in minimumCellWidths { + let cellWidth = (minimumCellWidthValue > generalMinimumCellWidth) ? minimumCellWidthValue : generalMinimumCellWidth + stretchedCellWidths.append(cellWidth) + } + + return stretchedCellWidths + } + } + + private var shouldUpdateButtonBarView = true + private var collectionViewDidLoad = false + +} diff --git a/Pods/XLPagerTabStrip/Sources/ButtonBarView.swift b/Pods/XLPagerTabStrip/Sources/ButtonBarView.swift new file mode 100644 index 0000000..a204971 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/ButtonBarView.swift @@ -0,0 +1,191 @@ +// ButtonBarView.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +public enum PagerScroll { + case no + case yes + case scrollOnlyIfOutOfScreen +} + +public enum SelectedBarAlignment { + case left + case center + case right + case progressive +} + +public enum SelectedBarVerticalAlignment { + case top + case middle + case bottom +} + +open class ButtonBarView: UICollectionView { + + open lazy var selectedBar: UIView = { [unowned self] in + let bar = UIView(frame: CGRect(x: 0, y: self.frame.size.height - CGFloat(self.selectedBarHeight), width: 0, height: CGFloat(self.selectedBarHeight))) + bar.layer.zPosition = 9999 + return bar + }() + + internal var selectedBarHeight: CGFloat = 4 { + didSet { + updateSelectedBarYPosition() + } + } + var selectedBarVerticalAlignment: SelectedBarVerticalAlignment = .bottom + var selectedBarAlignment: SelectedBarAlignment = .center + var selectedIndex = 0 + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + addSubview(selectedBar) + } + + public override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) { + super.init(frame: frame, collectionViewLayout: layout) + addSubview(selectedBar) + } + + open func moveTo(index: Int, animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) { + selectedIndex = index + updateSelectedBarPosition(animated, swipeDirection: swipeDirection, pagerScroll: pagerScroll) + } + + open func move(fromIndex: Int, toIndex: Int, progressPercentage: CGFloat, pagerScroll: PagerScroll) { + selectedIndex = progressPercentage > 0.5 ? toIndex : fromIndex + + let fromFrame = layoutAttributesForItem(at: IndexPath(item: fromIndex, section: 0))!.frame + let numberOfItems = dataSource!.collectionView(self, numberOfItemsInSection: 0) + + var toFrame: CGRect + + if toIndex < 0 || toIndex > numberOfItems - 1 { + if toIndex < 0 { + let cellAtts = layoutAttributesForItem(at: IndexPath(item: 0, section: 0)) + toFrame = cellAtts!.frame.offsetBy(dx: -cellAtts!.frame.size.width, dy: 0) + } else { + let cellAtts = layoutAttributesForItem(at: IndexPath(item: (numberOfItems - 1), section: 0)) + toFrame = cellAtts!.frame.offsetBy(dx: cellAtts!.frame.size.width, dy: 0) + } + } else { + toFrame = layoutAttributesForItem(at: IndexPath(item: toIndex, section: 0))!.frame + } + + var targetFrame = fromFrame + targetFrame.size.height = selectedBar.frame.size.height + targetFrame.size.width += (toFrame.size.width - fromFrame.size.width) * progressPercentage + targetFrame.origin.x += (toFrame.origin.x - fromFrame.origin.x) * progressPercentage + + selectedBar.frame = CGRect(x: targetFrame.origin.x, y: selectedBar.frame.origin.y, width: targetFrame.size.width, height: selectedBar.frame.size.height) + + var targetContentOffset: CGFloat = 0.0 + if contentSize.width > frame.size.width { + let toContentOffset = contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) + let fromContentOffset = contentOffsetForCell(withFrame: fromFrame, andIndex: fromIndex) + + targetContentOffset = fromContentOffset + ((toContentOffset - fromContentOffset) * progressPercentage) + } + + setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: false) + } + + open func updateSelectedBarPosition(_ animated: Bool, swipeDirection: SwipeDirection, pagerScroll: PagerScroll) { + var selectedBarFrame = selectedBar.frame + + let selectedCellIndexPath = IndexPath(item: selectedIndex, section: 0) + let attributes = layoutAttributesForItem(at: selectedCellIndexPath) + let selectedCellFrame = attributes!.frame + + updateContentOffset(animated: animated, pagerScroll: pagerScroll, toFrame: selectedCellFrame, toIndex: (selectedCellIndexPath as NSIndexPath).row) + + selectedBarFrame.size.width = selectedCellFrame.size.width + selectedBarFrame.origin.x = selectedCellFrame.origin.x + + if animated { + UIView.animate(withDuration: 0.3, animations: { [weak self] in + self?.selectedBar.frame = selectedBarFrame + }) + } else { + selectedBar.frame = selectedBarFrame + } + } + + // MARK: - Helpers + + private func updateContentOffset(animated: Bool, pagerScroll: PagerScroll, toFrame: CGRect, toIndex: Int) { + guard pagerScroll != .no || (pagerScroll != .scrollOnlyIfOutOfScreen && (toFrame.origin.x < contentOffset.x || toFrame.origin.x >= (contentOffset.x + frame.size.width - contentInset.left))) else { return } + let targetContentOffset = contentSize.width > frame.size.width ? contentOffsetForCell(withFrame: toFrame, andIndex: toIndex) : 0 + setContentOffset(CGPoint(x: targetContentOffset, y: 0), animated: animated) + } + + private func contentOffsetForCell(withFrame cellFrame: CGRect, andIndex index: Int) -> CGFloat { + let sectionInset = (collectionViewLayout as! UICollectionViewFlowLayout).sectionInset // swiftlint:disable:this force_cast + var alignmentOffset: CGFloat = 0.0 + + switch selectedBarAlignment { + case .left: + alignmentOffset = sectionInset.left + case .right: + alignmentOffset = frame.size.width - sectionInset.right - cellFrame.size.width + case .center: + alignmentOffset = (frame.size.width - cellFrame.size.width) * 0.5 + case .progressive: + let cellHalfWidth = cellFrame.size.width * 0.5 + let leftAlignmentOffset = sectionInset.left + cellHalfWidth + let rightAlignmentOffset = frame.size.width - sectionInset.right - cellHalfWidth + let numberOfItems = dataSource!.collectionView(self, numberOfItemsInSection: 0) + let progress = index / (numberOfItems - 1) + alignmentOffset = leftAlignmentOffset + (rightAlignmentOffset - leftAlignmentOffset) * CGFloat(progress) - cellHalfWidth + } + + var contentOffset = cellFrame.origin.x - alignmentOffset + contentOffset = max(0, contentOffset) + contentOffset = min(contentSize.width - frame.size.width, contentOffset) + return contentOffset + } + + private func updateSelectedBarYPosition() { + var selectedBarFrame = selectedBar.frame + + switch selectedBarVerticalAlignment { + case .top: + selectedBarFrame.origin.y = 0 + case .middle: + selectedBarFrame.origin.y = (frame.size.height - selectedBarHeight) / 2 + case .bottom: + selectedBarFrame.origin.y = frame.size.height - selectedBarHeight + } + + selectedBarFrame.size.height = selectedBarHeight + selectedBar.frame = selectedBarFrame + } + + override open func layoutSubviews() { + super.layoutSubviews() + updateSelectedBarYPosition() + } +} diff --git a/Pods/XLPagerTabStrip/Sources/ButtonBarViewCell.swift b/Pods/XLPagerTabStrip/Sources/ButtonBarViewCell.swift new file mode 100644 index 0000000..a16e02f --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/ButtonBarViewCell.swift @@ -0,0 +1,53 @@ +// ButtonBarViewCell.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit +import Foundation + +open class ButtonBarViewCell: UICollectionViewCell { + + @IBOutlet open var imageView: UIImageView! + @IBOutlet open var label: UILabel! + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + + isAccessibilityElement = true + accessibilityTraits.insert([.button, .header]) + } + + open override var isSelected: Bool { + get { + return super.isSelected + } + set { + super.isSelected = newValue + if (newValue) { + accessibilityTraits.insert(.selected) + } else { + accessibilityTraits.remove(.selected) + } + } + } +} diff --git a/Pods/XLPagerTabStrip/Sources/ButtonCell.xib b/Pods/XLPagerTabStrip/Sources/ButtonCell.xib new file mode 100644 index 0000000..7025bc7 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/ButtonCell.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/XLPagerTabStrip/Sources/FXPageControl.h b/Pods/XLPagerTabStrip/Sources/FXPageControl.h new file mode 100755 index 0000000..37a0438 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/FXPageControl.h @@ -0,0 +1,106 @@ +// +// FXPageControl.h +// +// Version 1.4 +// +// Created by Nick Lockwood on 07/01/2010. +// Copyright 2010 Charcoal Design +// +// Distributed under the permissive zlib License +// Get the latest version of FXPageControl from here: +// +// https://github.com/nicklockwood/FXPageControl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" +#import + + +#import +#undef weak_delegate +#if __has_feature(objc_arc_weak) +#define weak_delegate weak +#else +#define weak_delegate unsafe_unretained +#endif + + +extern const CGPathRef FXPageControlDotShapeCircle; +extern const CGPathRef FXPageControlDotShapeSquare; +extern const CGPathRef FXPageControlDotShapeTriangle; + + +@protocol FXPageControlDelegate; + + +IB_DESIGNABLE @interface FXPageControl : UIControl + +- (void)setUp; +- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount; +- (void)updateCurrentPageDisplay; + +@property (nonatomic, weak_delegate) IBOutlet id delegate; + +@property (nonatomic, assign) IBInspectable NSInteger currentPage; +@property (nonatomic, assign) IBInspectable NSInteger numberOfPages; +@property (nonatomic, assign) IBInspectable BOOL defersCurrentPageDisplay; +@property (nonatomic, assign) IBInspectable BOOL hidesForSinglePage; +@property (nonatomic, assign, getter = isWrapEnabled) IBInspectable BOOL wrapEnabled; +@property (nonatomic, assign, getter = isVertical) IBInspectable BOOL vertical; + +@property (nonatomic, strong) IBInspectable UIImage *dotImage; +@property (nonatomic, assign) IBInspectable CGPathRef dotShape; +@property (nonatomic, assign) IBInspectable CGFloat dotSize; +@property (nonatomic, strong) IBInspectable UIColor *dotColor; +@property (nonatomic, strong) IBInspectable UIColor *dotShadowColor; +@property (nonatomic, assign) IBInspectable CGFloat dotShadowBlur; +@property (nonatomic, assign) IBInspectable CGSize dotShadowOffset; + +@property (nonatomic, strong) IBInspectable UIImage *selectedDotImage; +@property (nonatomic, assign) IBInspectable CGPathRef selectedDotShape; +@property (nonatomic, assign) IBInspectable CGFloat selectedDotSize; +@property (nonatomic, strong) IBInspectable UIColor *selectedDotColor; +@property (nonatomic, strong) IBInspectable UIColor *selectedDotShadowColor; +@property (nonatomic, assign) IBInspectable CGFloat selectedDotShadowBlur; +@property (nonatomic, assign) IBInspectable CGSize selectedDotShadowOffset; + +@property (nonatomic, assign) IBInspectable CGFloat dotSpacing; + +@end + + +@protocol FXPageControlDelegate +@optional + +- (UIImage *)pageControl:(FXPageControl *)pageControl imageForDotAtIndex:(NSInteger)index; +- (CGPathRef)pageControl:(FXPageControl *)pageControl shapeForDotAtIndex:(NSInteger)index; +- (UIColor *)pageControl:(FXPageControl *)pageControl colorForDotAtIndex:(NSInteger)index; + +- (UIImage *)pageControl:(FXPageControl *)pageControl selectedImageForDotAtIndex:(NSInteger)index; +- (CGPathRef)pageControl:(FXPageControl *)pageControl selectedShapeForDotAtIndex:(NSInteger)index; +- (UIColor *)pageControl:(FXPageControl *)pageControl selectedColorForDotAtIndex:(NSInteger)index; + +@end + + +#pragma GCC diagnostic pop diff --git a/Pods/XLPagerTabStrip/Sources/FXPageControl.m b/Pods/XLPagerTabStrip/Sources/FXPageControl.m new file mode 100755 index 0000000..01602e8 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/FXPageControl.m @@ -0,0 +1,432 @@ +// +// FXPageControl.m +// +// Version 1.4 +// +// Created by Nick Lockwood on 07/01/2010. +// Copyright 2010 Charcoal Design +// +// Distributed under the permissive zlib License +// Get the latest version of FXPageControl from here: +// +// https://github.com/nicklockwood/FXPageControl +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + +#import "FXPageControl.h" + + +#pragma GCC diagnostic ignored "-Wgnu" +#pragma GCC diagnostic ignored "-Warc-repeated-use-of-weak" +#pragma GCC diagnostic ignored "-Wdirect-ivar-access" + + +#import +#if !__has_feature(objc_arc) +#error This class requires automatic reference counting +#endif + + +const CGPathRef FXPageControlDotShapeCircle = (const CGPathRef)1; +const CGPathRef FXPageControlDotShapeSquare = (const CGPathRef)2; +const CGPathRef FXPageControlDotShapeTriangle = (const CGPathRef)3; +#define LAST_SHAPE FXPageControlDotShapeTriangle + + +@implementation NSObject (FXPageControl) + +- (UIImage *)pageControl:(__unused FXPageControl *)pageControl imageForDotAtIndex:(__unused NSInteger)index { return nil; } +- (CGPathRef)pageControl:(__unused FXPageControl *)pageControl shapeForDotAtIndex:(__unused NSInteger)index { return NULL; } +- (UIColor *)pageControl:(__unused FXPageControl *)pageControl colorForDotAtIndex:(__unused NSInteger)index { return nil; } + +- (UIImage *)pageControl:(__unused FXPageControl *)pageControl selectedImageForDotAtIndex:(__unused NSInteger)index { return nil; } +- (CGPathRef)pageControl:(__unused FXPageControl *)pageControl selectedShapeForDotAtIndex:(__unused NSInteger)index { return NULL; } +- (UIColor *)pageControl:(__unused FXPageControl *)pageControl selectedColorForDotAtIndex:(__unused NSInteger)index { return nil; } + +@end + + +@implementation FXPageControl + +- (void)setUp +{ + //needs redrawing if bounds change + self.contentMode = UIViewContentModeRedraw; + + //set defaults + _dotSpacing = 10.0f; + _dotSize = 6.0f; + _dotShadowOffset = CGSizeMake(0, 1); + _selectedDotShadowOffset = CGSizeMake(0, 1); +} + +- (id)initWithFrame:(CGRect)frame +{ + if ((self = [super initWithFrame:frame])) + { + [self setUp]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + if ((self = [super initWithCoder:aDecoder])) + { + [self setUp]; + } + return self; +} + +- (void)dealloc +{ + if (_dotShape > LAST_SHAPE) CGPathRelease(_dotShape); + if (_selectedDotShape > LAST_SHAPE) CGPathRelease(_selectedDotShape); +} + +- (CGSize)sizeForNumberOfPages:(__unused NSInteger)pageCount +{ + CGFloat width = _dotSize + (_dotSize + _dotSpacing) * (_numberOfPages - 1); + return _vertical? CGSizeMake(_dotSize, width): CGSizeMake(width, _dotSize); +} + +- (void)updateCurrentPageDisplay +{ + [self setNeedsDisplay]; +} + +- (void)drawRect:(__unused CGRect)rect +{ + if (_numberOfPages > 1 || !_hidesForSinglePage) + { + CGContextRef context = UIGraphicsGetCurrentContext(); + CGSize size = [self sizeForNumberOfPages:_numberOfPages]; + if (_vertical) + { + CGContextTranslateCTM(context, self.frame.size.width / 2, (self.frame.size.height - size.height) / 2); + } + else + { + CGContextTranslateCTM(context, (self.frame.size.width - size.width) / 2, self.frame.size.height / 2); + } + + for (int i = 0; i < _numberOfPages; i++) + { + UIImage *dotImage = nil; + UIColor *dotColor = nil; + CGPathRef dotShape = NULL; + CGFloat dotSize = 0; + UIColor *dotShadowColor = nil; + CGSize dotShadowOffset = CGSizeZero; + CGFloat dotShadowBlur = 0; + + if (i == _currentPage) + { + [_selectedDotColor setFill]; + dotImage = [_delegate pageControl:self selectedImageForDotAtIndex:i] ?: _selectedDotImage; + dotShape = [_delegate pageControl:self selectedShapeForDotAtIndex:i] ?: _selectedDotShape ?: _dotShape; + dotColor = [_delegate pageControl:self selectedColorForDotAtIndex:i] ?: _selectedDotColor ?: [UIColor blackColor]; + dotShadowBlur = _selectedDotShadowBlur; + dotShadowColor = _selectedDotShadowColor; + dotShadowOffset = _selectedDotShadowOffset; + dotSize = _selectedDotSize ?: _dotSize; + } + else + { + [_dotColor setFill]; + dotImage = [_delegate pageControl:self imageForDotAtIndex:i] ?: _dotImage; + dotShape = [_delegate pageControl:self shapeForDotAtIndex:i] ?: _dotShape; + dotColor = [_delegate pageControl:self colorForDotAtIndex:i] ?: _dotColor; + if (!dotColor) + { + //fall back to selected dot color with reduced alpha + dotColor = [_delegate pageControl:self selectedColorForDotAtIndex:i] ?: _selectedDotColor ?: [UIColor blackColor]; + dotColor = [dotColor colorWithAlphaComponent:0.25f]; + } + dotShadowBlur = _dotShadowBlur; + dotShadowColor = _dotShadowColor; + dotShadowOffset = _dotShadowOffset; + dotSize = _dotSize; + } + + CGContextSaveGState(context); + CGFloat offset = (_dotSize + _dotSpacing) * i + _dotSize / 2; + CGContextTranslateCTM(context, _vertical? 0: offset, _vertical? offset: 0); + + if (dotShadowColor && ![dotShadowColor isEqual:[UIColor clearColor]]) + { + CGContextSetShadowWithColor(context, dotShadowOffset, dotShadowBlur, dotShadowColor.CGColor); + } + if (dotImage) + { + [dotImage drawInRect:CGRectMake(-dotImage.size.width / 2, -dotImage.size.height / 2, dotImage.size.width, dotImage.size.height)]; + } + else + { + [dotColor setFill]; + if (!dotShape || dotShape == FXPageControlDotShapeCircle) + { + CGContextFillEllipseInRect(context, CGRectMake(-dotSize / 2, -dotSize / 2, dotSize, dotSize)); + } + else if (dotShape == FXPageControlDotShapeSquare) + { + CGContextFillRect(context, CGRectMake(-dotSize / 2, -dotSize / 2, dotSize, dotSize)); + } + else if (dotShape == FXPageControlDotShapeTriangle) + { + CGContextBeginPath(context); + CGContextMoveToPoint(context, 0, -dotSize / 2); + CGContextAddLineToPoint(context, dotSize / 2, dotSize / 2); + CGContextAddLineToPoint(context, -dotSize / 2, dotSize / 2); + CGContextAddLineToPoint(context, 0, -dotSize / 2); + CGContextFillPath(context); + } + else + { + CGContextBeginPath(context); + CGContextAddPath(context, dotShape); + CGContextFillPath(context); + } + } + CGContextRestoreGState(context); + } + } +} + +- (NSInteger)clampedPageValue:(NSInteger)page +{ + if (_wrapEnabled) + { + return _numberOfPages? (page + _numberOfPages) % _numberOfPages: 0; + } + else + { + return MIN(MAX(0, page), _numberOfPages - 1); + } +} + +- (void)setDotImage:(UIImage *)dotImage +{ + if (_dotImage != dotImage) + { + _dotImage = dotImage; + [self setNeedsDisplay]; + } +} + +- (void)setDotShape:(CGPathRef)dotShape +{ + if (_dotShape != dotShape) + { + if (_dotShape > LAST_SHAPE) CGPathRelease(_dotShape); + _dotShape = dotShape; + if (_dotShape > LAST_SHAPE) CGPathRetain(_dotShape); + [self setNeedsDisplay]; + } +} + +- (void)setDotSize:(CGFloat)dotSize +{ + if (ABS(_dotSize - dotSize) > 0.001) + { + _dotSize = dotSize; + [self setNeedsDisplay]; + } +} + +- (void)setDotColor:(UIColor *)dotColor +{ + if (_dotColor != dotColor) + { + _dotColor = dotColor; + [self setNeedsDisplay]; + } +} + +- (void)setDotShadowColor:(UIColor *)dotColor +{ + if (_dotShadowColor != dotColor) + { + _dotShadowColor = dotColor; + [self setNeedsDisplay]; + } +} + +- (void)setDotShadowBlur:(CGFloat)dotShadowBlur +{ + if (ABS(_dotShadowBlur - dotShadowBlur) > 0.001) + { + _dotShadowBlur = dotShadowBlur; + [self setNeedsDisplay]; + } +} + +- (void)setDotShadowOffset:(CGSize)dotShadowOffset +{ + if (!CGSizeEqualToSize(_dotShadowOffset, dotShadowOffset)) + { + _dotShadowOffset = dotShadowOffset; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotImage:(UIImage *)dotImage +{ + if (_selectedDotImage != dotImage) + { + _selectedDotImage = dotImage; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotColor:(UIColor *)dotColor +{ + if (_selectedDotColor != dotColor) + { + _selectedDotColor = dotColor; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotShape:(CGPathRef)dotShape +{ + if (_selectedDotShape != dotShape) + { + if (_selectedDotShape > LAST_SHAPE) CGPathRelease(_selectedDotShape); + _selectedDotShape = dotShape; + if (_selectedDotShape > LAST_SHAPE) CGPathRetain(_selectedDotShape); + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotSize:(CGFloat)dotSize +{ + if (ABS(_selectedDotSize - dotSize) > 0.001) + { + _selectedDotSize = dotSize; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotShadowColor:(UIColor *)dotColor +{ + if (_selectedDotShadowColor != dotColor) + { + _selectedDotShadowColor = dotColor; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotShadowBlur:(CGFloat)dotShadowBlur +{ + if (ABS(_selectedDotShadowBlur - dotShadowBlur) > 0.001) + { + _selectedDotShadowBlur = dotShadowBlur; + [self setNeedsDisplay]; + } +} + +- (void)setSelectedDotShadowOffset:(CGSize)dotShadowOffset +{ + if (!CGSizeEqualToSize(_selectedDotShadowOffset, dotShadowOffset)) + { + _selectedDotShadowOffset = dotShadowOffset; + [self setNeedsDisplay]; + } +} + +- (void)setDotSpacing:(CGFloat)dotSpacing +{ + if (ABS(_dotSpacing - dotSpacing) > 0.001) + { + _dotSpacing = dotSpacing; + [self setNeedsDisplay]; + } +} + +- (void)setDelegate:(id)delegate +{ + if (_delegate != delegate) + { + _delegate = delegate; + [self setNeedsDisplay]; + } +} + +- (void)setCurrentPage:(NSInteger)page +{ + _currentPage = [self clampedPageValue:page]; + [self setNeedsDisplay]; +} + +- (void)setNumberOfPages:(NSInteger)pages +{ + if (_numberOfPages != pages) + { + _numberOfPages = pages; + if (_currentPage >= pages) + { + _currentPage = pages - 1; + } + [self setNeedsDisplay]; + } +} + +- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event +{ + CGPoint point = [touch locationInView:self]; + BOOL forward = _vertical? (point.y > self.frame.size.height / 2): (point.x > self.frame.size.width / 2); + _currentPage = [self clampedPageValue:_currentPage + (forward? 1: -1)]; + if (!_defersCurrentPageDisplay) + { + [self setNeedsDisplay]; + } + [self sendActionsForControlEvents:UIControlEventValueChanged]; + [super endTrackingWithTouch:touch withEvent:event]; +} + +- (CGSize)sizeThatFits:(__unused CGSize)size +{ + CGSize dotSize = [self sizeForNumberOfPages:_numberOfPages]; + if (_selectedDotSize) + { + CGFloat width = (_selectedDotSize - _dotSize); + CGFloat height = MAX(36, MAX(_dotSize, _selectedDotSize)); + dotSize.width = _vertical? height: dotSize.width + width; + dotSize.height = _vertical? dotSize.height + width: height; + + } + if ((_dotShadowColor && ![_dotShadowColor isEqual:[UIColor clearColor]]) || + (_selectedDotShadowColor && ![_selectedDotShadowColor isEqual:[UIColor clearColor]])) + { + dotSize.width += MAX(_dotShadowOffset.width, _selectedDotShadowOffset.width) * 2; + dotSize.height += MAX(_dotShadowOffset.height, _selectedDotShadowOffset.height) * 2; + dotSize.width += MAX(_dotShadowBlur, _selectedDotShadowBlur) * 2; + dotSize.height += MAX(_dotShadowBlur, _selectedDotShadowBlur) * 2; + } + return dotSize; +} + +- (CGSize)intrinsicContentSize +{ + return [self sizeThatFits:self.bounds.size]; +} + +@end diff --git a/Pods/XLPagerTabStrip/Sources/IndicatorInfo.swift b/Pods/XLPagerTabStrip/Sources/IndicatorInfo.swift new file mode 100644 index 0000000..146eb9a --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/IndicatorInfo.swift @@ -0,0 +1,80 @@ +// IndicatorInfo.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public struct IndicatorInfo { + + public var title: String? + public var image: UIImage? + public var highlightedImage: UIImage? + public var accessibilityLabel: String? + public var userInfo: Any? + + public init(title: String?) { + self.title = title + self.accessibilityLabel = title + } + + public init(image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) { + self.image = image + self.highlightedImage = highlightedImage + self.userInfo = userInfo + } + + public init(title: String?, image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) { + self.title = title + self.accessibilityLabel = title + self.image = image + self.highlightedImage = highlightedImage + self.userInfo = userInfo + } + + public init(title: String?, accessibilityLabel:String?, image: UIImage?, highlightedImage: UIImage? = nil, userInfo: Any? = nil) { + self.title = title + self.accessibilityLabel = accessibilityLabel + self.image = image + self.highlightedImage = highlightedImage + self.userInfo = userInfo + } + +} + +extension IndicatorInfo : ExpressibleByStringLiteral { + + public init(stringLiteral value: String) { + title = value + accessibilityLabel = value + } + + public init(extendedGraphemeClusterLiteral value: String) { + title = value + accessibilityLabel = value + } + + public init(unicodeScalarLiteral value: String) { + title = value + accessibilityLabel = value + } +} diff --git a/Pods/XLPagerTabStrip/Sources/PagerTabStripBehaviour.swift b/Pods/XLPagerTabStrip/Sources/PagerTabStripBehaviour.swift new file mode 100644 index 0000000..1ad9dea --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/PagerTabStripBehaviour.swift @@ -0,0 +1,58 @@ +// PagerTabStripOptions.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public enum PagerTabStripBehaviour { + + case common(skipIntermediateViewControllers: Bool) + case progressive(skipIntermediateViewControllers: Bool, elasticIndicatorLimit: Bool) + + public var skipIntermediateViewControllers: Bool { + switch self { + case .common(let skipIntermediateViewControllers): + return skipIntermediateViewControllers + case .progressive(let skipIntermediateViewControllers, _): + return skipIntermediateViewControllers + } + } + + public var isProgressiveIndicator: Bool { + switch self { + case .common: + return false + case .progressive: + return true + } + } + + public var isElasticIndicatorLimit: Bool { + switch self { + case .common: + return false + case .progressive(_, let elasticIndicatorLimit): + return elasticIndicatorLimit + } + } +} diff --git a/Pods/XLPagerTabStrip/Sources/PagerTabStripError.swift b/Pods/XLPagerTabStrip/Sources/PagerTabStripError.swift new file mode 100644 index 0000000..f345365 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/PagerTabStripError.swift @@ -0,0 +1,31 @@ +// PagerTabStripError.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public enum PagerTabStripError: Error { + + case viewControllerOutOfBounds + +} diff --git a/Pods/XLPagerTabStrip/Sources/PagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/PagerTabStripViewController.swift new file mode 100644 index 0000000..9aedb7d --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/PagerTabStripViewController.swift @@ -0,0 +1,396 @@ +// PagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// MARK: Protocols + +public protocol IndicatorInfoProvider { + + func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo + +} + +public protocol PagerTabStripDelegate: class { + + func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) +} + +public protocol PagerTabStripIsProgressiveDelegate: PagerTabStripDelegate { + + func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) +} + +public protocol PagerTabStripDataSource: class { + + func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] +} + +// MARK: PagerTabStripViewController + +open class PagerTabStripViewController: UIViewController, UIScrollViewDelegate { + + @IBOutlet weak public var containerView: UIScrollView! + + open weak var delegate: PagerTabStripDelegate? + open weak var datasource: PagerTabStripDataSource? + + open var pagerBehaviour = PagerTabStripBehaviour.progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) + + open private(set) var viewControllers = [UIViewController]() + open private(set) var currentIndex = 0 + open private(set) var preCurrentIndex = 0 // used *only* to store the index to which move when the pager becomes visible + + open var pageWidth: CGFloat { + return containerView.bounds.width + } + + open var scrollPercentage: CGFloat { + if swipeDirection != .right { + let module = fmod(containerView.contentOffset.x, pageWidth) + return module == 0.0 ? 1.0 : module / pageWidth + } + return 1 - fmod(containerView.contentOffset.x >= 0 ? containerView.contentOffset.x : pageWidth + containerView.contentOffset.x, pageWidth) / pageWidth + } + + open var swipeDirection: SwipeDirection { + if containerView.contentOffset.x > lastContentOffset { + return .left + } else if containerView.contentOffset.x < lastContentOffset { + return .right + } + return .none + } + + override open func viewDidLoad() { + super.viewDidLoad() + let conteinerViewAux = containerView ?? { + let containerView = UIScrollView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)) + containerView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + return containerView + }() + containerView = conteinerViewAux + if containerView.superview == nil { + view.addSubview(containerView) + } + containerView.bounces = true + containerView.alwaysBounceHorizontal = true + containerView.alwaysBounceVertical = false + containerView.scrollsToTop = false + containerView.delegate = self + containerView.showsVerticalScrollIndicator = false + containerView.showsHorizontalScrollIndicator = false + containerView.isPagingEnabled = true + reloadViewControllers() + + let childController = viewControllers[currentIndex] + addChild(childController) + childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] + containerView.addSubview(childController.view) + childController.didMove(toParent: self) + } + + open override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + isViewAppearing = true + children.forEach { $0.beginAppearanceTransition(true, animated: animated) } + } + + override open func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + lastSize = containerView.bounds.size + updateIfNeeded() + let needToUpdateCurrentChild = preCurrentIndex != currentIndex + if needToUpdateCurrentChild { + moveToViewController(at: preCurrentIndex) + } + isViewAppearing = false + children.forEach { $0.endAppearanceTransition() } + } + + open override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + children.forEach { $0.beginAppearanceTransition(false, animated: animated) } + } + + open override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + children.forEach { $0.endAppearanceTransition() } + } + + override open func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + updateIfNeeded() + } + + open override var shouldAutomaticallyForwardAppearanceMethods: Bool { + return false + } + + open func moveToViewController(at index: Int, animated: Bool = true) { + guard isViewLoaded && view.window != nil && currentIndex != index else { + preCurrentIndex = index + return + } + + if animated && pagerBehaviour.skipIntermediateViewControllers && abs(currentIndex - index) > 1 { + var tmpViewControllers = viewControllers + let currentChildVC = viewControllers[currentIndex] + let fromIndex = currentIndex < index ? index - 1 : index + 1 + let fromChildVC = viewControllers[fromIndex] + tmpViewControllers[currentIndex] = fromChildVC + tmpViewControllers[fromIndex] = currentChildVC + pagerTabStripChildViewControllersForScrolling = tmpViewControllers + containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: fromIndex), y: 0), animated: false) + (navigationController?.view ?? view).isUserInteractionEnabled = !animated + containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: true) + } else { + (navigationController?.view ?? view).isUserInteractionEnabled = !animated + containerView.setContentOffset(CGPoint(x: pageOffsetForChild(at: index), y: 0), animated: animated) + } + } + + open func moveTo(viewController: UIViewController, animated: Bool = true) { + moveToViewController(at: viewControllers.firstIndex(of: viewController)!, animated: animated) + } + + // MARK: - PagerTabStripDataSource + + open func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { + assertionFailure("Sub-class must implement the PagerTabStripDataSource viewControllers(for:) method") + return [] + } + + // MARK: - Helpers + + open func updateIfNeeded() { + if isViewLoaded && !lastSize.equalTo(containerView.bounds.size) { + updateContent() + } + } + + open func canMoveTo(index: Int) -> Bool { + return currentIndex != index && viewControllers.count > index + } + + open func pageOffsetForChild(at index: Int) -> CGFloat { + return CGFloat(index) * containerView.bounds.width + } + + open func offsetForChild(at index: Int) -> CGFloat { + return (CGFloat(index) * containerView.bounds.width) + ((containerView.bounds.width - view.bounds.width) * 0.5) + } + + open func offsetForChild(viewController: UIViewController) throws -> CGFloat { + guard let index = viewControllers.firstIndex(of: viewController) else { + throw PagerTabStripError.viewControllerOutOfBounds + } + return offsetForChild(at: index) + } + + open func pageFor(contentOffset: CGFloat) -> Int { + let result = virtualPageFor(contentOffset: contentOffset) + return pageFor(virtualPage: result) + } + + open func virtualPageFor(contentOffset: CGFloat) -> Int { + return Int((contentOffset + 1.5 * pageWidth) / pageWidth) - 1 + } + + open func pageFor(virtualPage: Int) -> Int { + if virtualPage < 0 { + return 0 + } + if virtualPage > viewControllers.count - 1 { + return viewControllers.count - 1 + } + return virtualPage + } + + open func updateContent() { + if lastSize.width != containerView.bounds.size.width { + lastSize = containerView.bounds.size + containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0) + } + lastSize = containerView.bounds.size + + let pagerViewControllers = pagerTabStripChildViewControllersForScrolling ?? viewControllers + containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(pagerViewControllers.count), height: containerView.contentSize.height) + + for (index, childController) in pagerViewControllers.enumerated() { + let pageOffsetForChild = self.pageOffsetForChild(at: index) + if abs(containerView.contentOffset.x - pageOffsetForChild) < containerView.bounds.width { + if childController.parent != nil { + childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height) + childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] + } else { + childController.beginAppearanceTransition(true, animated: false) + addChild(childController) + childController.view.frame = CGRect(x: offsetForChild(at: index), y: 0, width: view.bounds.width, height: containerView.bounds.height) + childController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth] + containerView.addSubview(childController.view) + childController.didMove(toParent: self) + childController.endAppearanceTransition() + } + } else { + if childController.parent != nil { + childController.beginAppearanceTransition(false, animated: false) + childController.willMove(toParent: nil) + childController.view.removeFromSuperview() + childController.removeFromParent() + childController.endAppearanceTransition() + } + } + } + + let oldCurrentIndex = currentIndex + let virtualPage = virtualPageFor(contentOffset: containerView.contentOffset.x) + let newCurrentIndex = pageFor(virtualPage: virtualPage) + currentIndex = newCurrentIndex + preCurrentIndex = currentIndex + let changeCurrentIndex = newCurrentIndex != oldCurrentIndex + + if let progressiveDelegate = self as? PagerTabStripIsProgressiveDelegate, pagerBehaviour.isProgressiveIndicator { + + let (fromIndex, toIndex, scrollPercentage) = progressiveIndicatorData(virtualPage) + progressiveDelegate.updateIndicator(for: self, fromIndex: fromIndex, toIndex: toIndex, withProgressPercentage: scrollPercentage, indexWasChanged: changeCurrentIndex) + } else { + delegate?.updateIndicator(for: self, fromIndex: min(oldCurrentIndex, pagerViewControllers.count - 1), toIndex: newCurrentIndex) + } + } + + open func reloadPagerTabStripView() { + guard isViewLoaded else { return } + for childController in viewControllers where childController.parent != nil { + childController.beginAppearanceTransition(false, animated: false) + childController.willMove(toParent: nil) + childController.view.removeFromSuperview() + childController.removeFromParent() + childController.endAppearanceTransition() + } + reloadViewControllers() + containerView.contentSize = CGSize(width: containerView.bounds.width * CGFloat(viewControllers.count), height: containerView.contentSize.height) + if currentIndex >= viewControllers.count { + currentIndex = viewControllers.count - 1 + } + preCurrentIndex = currentIndex + containerView.contentOffset = CGPoint(x: pageOffsetForChild(at: currentIndex), y: 0) + updateContent() + } + + // MARK: - UIScrollViewDelegate + + open func scrollViewDidScroll(_ scrollView: UIScrollView) { + if containerView == scrollView { + updateContent() + lastContentOffset = scrollView.contentOffset.x + } + } + + open func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { + if containerView == scrollView { + lastPageNumber = pageFor(contentOffset: scrollView.contentOffset.x) + } + } + + open func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + if containerView == scrollView { + pagerTabStripChildViewControllersForScrolling = nil + (navigationController?.view ?? view).isUserInteractionEnabled = true + updateContent() + } + } + + // MARK: - Orientation + + open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + isViewRotating = true + pageBeforeRotate = currentIndex + coordinator.animate(alongsideTransition: nil) { [weak self] _ in + guard let me = self else { return } + me.isViewRotating = false + me.currentIndex = me.pageBeforeRotate + me.preCurrentIndex = me.currentIndex + me.updateIfNeeded() + } + } + + // MARK: Private + + private func progressiveIndicatorData(_ virtualPage: Int) -> (Int, Int, CGFloat) { + let count = viewControllers.count + var fromIndex = currentIndex + var toIndex = currentIndex + let direction = swipeDirection + + if direction == .left { + if virtualPage > count - 1 { + fromIndex = count - 1 + toIndex = count + } else { + if self.scrollPercentage >= 0.5 { + fromIndex = max(toIndex - 1, 0) + } else { + toIndex = fromIndex + 1 + } + } + } else if direction == .right { + if virtualPage < 0 { + fromIndex = 0 + toIndex = -1 + } else { + if self.scrollPercentage > 0.5 { + fromIndex = min(toIndex + 1, count - 1) + } else { + toIndex = fromIndex - 1 + } + } + } + let scrollPercentage = pagerBehaviour.isElasticIndicatorLimit ? self.scrollPercentage : ((toIndex < 0 || toIndex >= count) ? 0.0 : self.scrollPercentage) + return (fromIndex, toIndex, scrollPercentage) + } + + private func reloadViewControllers() { + guard let dataSource = datasource else { + fatalError("dataSource must not be nil") + } + viewControllers = dataSource.viewControllers(for: self) + // viewControllers + guard !viewControllers.isEmpty else { + fatalError("viewControllers(for:) should provide at least one child view controller") + } + viewControllers.forEach { if !($0 is IndicatorInfoProvider) { fatalError("Every view controller provided by PagerTabStripDataSource's viewControllers(for:) method must conform to IndicatorInfoProvider") }} + + } + + private var pagerTabStripChildViewControllersForScrolling: [UIViewController]? + private var lastPageNumber = 0 + private var lastContentOffset: CGFloat = 0.0 + private var pageBeforeRotate = 0 + private var lastSize = CGSize(width: 0, height: 0) + internal var isViewRotating = false + internal var isViewAppearing = false + +} diff --git a/Pods/XLPagerTabStrip/Sources/SegmentedPagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/SegmentedPagerTabStripViewController.swift new file mode 100644 index 0000000..cdd3fb1 --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/SegmentedPagerTabStripViewController.swift @@ -0,0 +1,111 @@ +// SegmentedPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public struct SegmentedPagerTabStripSettings { + + public struct Style { + public var segmentedControlColor: UIColor? + } + + public var style = Style() +} + +open class SegmentedPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripDelegate { + + @IBOutlet weak public var segmentedControl: UISegmentedControl! + + open var settings = SegmentedPagerTabStripSettings() + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + pagerBehaviour = PagerTabStripBehaviour.common(skipIntermediateViewControllers: true) + delegate = self + datasource = self + } + + private(set) var shouldUpdateSegmentedControl = true + + open override func viewDidLoad() { + super.viewDidLoad() + let auxSegmentedControl = segmentedControl ?? UISegmentedControl() + segmentedControl = auxSegmentedControl + if segmentedControl.superview == nil { + navigationItem.titleView = segmentedControl + } + segmentedControl.tintColor = settings.style.segmentedControlColor ?? segmentedControl.tintColor + segmentedControl.addTarget(self, action: #selector(SegmentedPagerTabStripViewController.segmentedControlChanged(_:)), for: .valueChanged) + reloadSegmentedControl() + } + + open override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + if isViewLoaded { + reloadSegmentedControl() + } + } + + func reloadSegmentedControl() { + segmentedControl.removeAllSegments() + for (index, item) in viewControllers.enumerated() { + let child = item as! IndicatorInfoProvider // swiftlint:disable:this force_cast + if let image = child.indicatorInfo(for: self).image { + segmentedControl.insertSegment(with: image, at: index, animated: false) + } else { + segmentedControl.insertSegment(withTitle: child.indicatorInfo(for: self).title, at: index, animated: false) + } + } + segmentedControl.selectedSegmentIndex = currentIndex + } + + @objc func segmentedControlChanged(_ sender: UISegmentedControl) { + let index = sender.selectedSegmentIndex + updateIndicator(for: self, fromIndex: currentIndex, toIndex: index) + shouldUpdateSegmentedControl = false + moveToViewController(at: index) + } + + // MARK: - PagerTabStripDelegate + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { + if shouldUpdateSegmentedControl { + segmentedControl.selectedSegmentIndex = toIndex + } + } + + // MARK: - UIScrollViewDelegate + + open override func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { + super.scrollViewDidEndScrollingAnimation(scrollView) + shouldUpdateSegmentedControl = true + } +} diff --git a/Pods/XLPagerTabStrip/Sources/SwipeDirection.swift b/Pods/XLPagerTabStrip/Sources/SwipeDirection.swift new file mode 100644 index 0000000..d032c7d --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/SwipeDirection.swift @@ -0,0 +1,31 @@ +// SwipeDirection.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public enum SwipeDirection { + case left + case right + case none +} diff --git a/Pods/XLPagerTabStrip/Sources/TwitterPagerTabStripViewController.swift b/Pods/XLPagerTabStrip/Sources/TwitterPagerTabStripViewController.swift new file mode 100644 index 0000000..c37215a --- /dev/null +++ b/Pods/XLPagerTabStrip/Sources/TwitterPagerTabStripViewController.swift @@ -0,0 +1,234 @@ +// TwitterPagerTabStripViewController.swift +// XLPagerTabStrip ( https://github.com/xmartlabs/XLPagerTabStrip ) +// +// Copyright (c) 2017 Xmartlabs ( http://xmartlabs.com ) +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +public struct TwitterPagerTabStripSettings { + + public struct Style { + public var dotColor = UIColor(white: 1, alpha: 0.4) + public var selectedDotColor = UIColor.white + public var portraitTitleFont = UIFont.systemFont(ofSize: 18) + public var landscapeTitleFont = UIFont.systemFont(ofSize: 15) + public var titleColor = UIColor.white + } + + public var style = Style() +} + +open class TwitterPagerTabStripViewController: PagerTabStripViewController, PagerTabStripDataSource, PagerTabStripIsProgressiveDelegate { + + open var settings = TwitterPagerTabStripSettings() + + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) + delegate = self + datasource = self + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + pagerBehaviour = .progressive(skipIntermediateViewControllers: true, elasticIndicatorLimit: true) + delegate = self + datasource = self + } + + open override func viewDidLoad() { + super.viewDidLoad() + + if titleView.superview == nil { + navigationItem.titleView = titleView + } + + // keep watching the frame of titleView + titleView.addObserver(self, forKeyPath: "frame", options: [.new, .old], context: nil) + + guard let navigationController = navigationController else { + fatalError("TwitterPagerTabStripViewController should be embedded in a UINavigationController") + } + titleView.frame = CGRect(x: 0, y: 0, width: navigationController.navigationBar.frame.width, height: navigationController.navigationBar.frame.height) + titleView.addSubview(titleScrollView) + titleView.addSubview(pageControl) + reloadNavigationViewItems() + } + + open override func reloadPagerTabStripView() { + super.reloadPagerTabStripView() + guard isViewLoaded else { return } + + reloadNavigationViewItems() + setNavigationViewItemsPosition(updateAlpha: true) + } + + // MARK: - PagerTabStripDelegate + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int, withProgressPercentage progressPercentage: CGFloat, indexWasChanged: Bool) { + + // move indicator scroll view + guard let distance = distanceValue else { return } + var xOffset: CGFloat = 0 + if fromIndex < toIndex { + xOffset = distance * CGFloat(fromIndex) + distance * progressPercentage + } else if fromIndex > toIndex { + xOffset = distance * CGFloat(fromIndex) - distance * progressPercentage + } else { + xOffset = distance * CGFloat(fromIndex) + } + + titleScrollView.contentOffset = CGPoint(x: xOffset, y: 0) + + // update alpha of titles + setAlphaWith(offset: xOffset, andDistance: distance) + + // update page control page + pageControl.currentPage = currentIndex + } + + open func updateIndicator(for viewController: PagerTabStripViewController, fromIndex: Int, toIndex: Int) { + fatalError() + } + + open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + guard object as AnyObject === titleView && keyPath == "frame" && change?[NSKeyValueChangeKey.kindKey] as? UInt == NSKeyValueChange.setting.rawValue else { return } + + let oldRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue + let newRect = (change![NSKeyValueChangeKey.oldKey]! as AnyObject).cgRectValue + if (oldRect?.equalTo(newRect!))! { + titleScrollView.frame = CGRect(x: 0, y: 0, width: titleView.frame.width, height: titleScrollView.frame.height) + setNavigationViewItemsPosition(updateAlpha: true) + } + } + + deinit { + if isViewLoaded { + titleView.removeObserver(self, forKeyPath: "frame") + } + } + + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + setNavigationViewItemsPosition(updateAlpha: false) + } + + // MARK: - Helpers + + private lazy var titleView: UIView = { + let navigationView = UIView() + navigationView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + return navigationView + }() + + private lazy var titleScrollView: UIScrollView = { [unowned self] in + let titleScrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 44)) + titleScrollView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + titleScrollView.bounces = true + titleScrollView.scrollsToTop = false + titleScrollView.delegate = self + titleScrollView.showsVerticalScrollIndicator = false + titleScrollView.showsHorizontalScrollIndicator = false + titleScrollView.isPagingEnabled = true + titleScrollView.isUserInteractionEnabled = false + titleScrollView.alwaysBounceHorizontal = true + titleScrollView.alwaysBounceVertical = false + return titleScrollView + }() + + private lazy var pageControl: FXPageControl = { [unowned self] in + let pageControl = FXPageControl() + pageControl.backgroundColor = .clear + pageControl.dotSize = 3.8 + pageControl.dotSpacing = 4.0 + pageControl.dotColor = self.settings.style.dotColor + pageControl.selectedDotColor = self.settings.style.selectedDotColor + pageControl.isUserInteractionEnabled = false + return pageControl + }() + + private var childTitleLabels = [UILabel]() + + private func reloadNavigationViewItems() { + // remove all child view controller header labels + childTitleLabels.forEach { $0.removeFromSuperview() } + childTitleLabels.removeAll() + for (index, item) in viewControllers.enumerated() { + let child = item as! IndicatorInfoProvider // swiftlint:disable:this force_cast + let indicatorInfo = child.indicatorInfo(for: self) + let navTitleLabel: UILabel = { + let label = UILabel() + label.text = indicatorInfo.title + label.font = UIApplication.shared.statusBarOrientation.isPortrait ? settings.style.portraitTitleFont : settings.style.landscapeTitleFont + label.textColor = settings.style.titleColor + label.alpha = 0 + return label + }() + navTitleLabel.alpha = currentIndex == index ? 1 : 0 + navTitleLabel.textColor = settings.style.titleColor + titleScrollView.addSubview(navTitleLabel) + childTitleLabels.append(navTitleLabel) + } + } + + private func setNavigationViewItemsPosition(updateAlpha: Bool) { + guard let distance = distanceValue else { return } + let isPortrait = UIApplication.shared.statusBarOrientation.isPortrait + let navBarHeight: CGFloat = navigationController!.navigationBar.frame.size.height + for (index, label) in childTitleLabels.enumerated() { + if updateAlpha { + label.alpha = currentIndex == index ? 1 : 0 + } + label.font = isPortrait ? settings.style.portraitTitleFont : settings.style.landscapeTitleFont + let viewSize = label.intrinsicContentSize + let originX = distance - viewSize.width/2 + CGFloat(index) * distance + let originY = (CGFloat(navBarHeight) - viewSize.height) / 2 + label.frame = CGRect(x: originX, y: originY - 2, width: viewSize.width, height: viewSize.height) + label.tag = index + } + + let xOffset = distance * CGFloat(currentIndex) + titleScrollView.contentOffset = CGPoint(x: xOffset, y: 0) + + pageControl.numberOfPages = childTitleLabels.count + pageControl.currentPage = currentIndex + let viewSize = pageControl.sizeForNumber(ofPages: childTitleLabels.count) + let originX = distance - viewSize.width / 2 + pageControl.frame = CGRect(x: originX, y: navBarHeight - 10, width: viewSize.width, height: viewSize.height) + } + + private func setAlphaWith(offset: CGFloat, andDistance distance: CGFloat) { + for (index, label) in childTitleLabels.enumerated() { + label.alpha = { + if offset < distance * CGFloat(index) { + return (offset - distance * CGFloat(index - 1)) / distance + } else { + return 1 - ((offset - distance * CGFloat(index)) / distance) + } + }() + } + } + + private var distanceValue: CGFloat? { + return navigationController.map { $0.navigationBar.convert($0.navigationBar.center, to: titleView) }?.x + } +}