diff --git a/TrainingXLPagerTabStrip/Podfile b/TrainingXLPagerTabStrip/Podfile new file mode 100644 index 0000000..724ac2d --- /dev/null +++ b/TrainingXLPagerTabStrip/Podfile @@ -0,0 +1,10 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'TrainingXLPagerTabStrip' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for TrainingXLPagerTabStrip + pod 'XLPagerTabStrip', '~> 9.0' +end diff --git a/TrainingXLPagerTabStrip/Podfile.lock b/TrainingXLPagerTabStrip/Podfile.lock new file mode 100644 index 0000000..13a24a2 --- /dev/null +++ b/TrainingXLPagerTabStrip/Podfile.lock @@ -0,0 +1,16 @@ +PODS: + - XLPagerTabStrip (9.0.0) + +DEPENDENCIES: + - XLPagerTabStrip (~> 9.0) + +SPEC REPOS: + trunk: + - XLPagerTabStrip + +SPEC CHECKSUMS: + XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 + +PODFILE CHECKSUM: 14b0ad190cb8f4176a4dc4c328393c60dc791e5b + +COCOAPODS: 1.8.4 diff --git a/TrainingXLPagerTabStrip/Pods/Manifest.lock b/TrainingXLPagerTabStrip/Pods/Manifest.lock new file mode 100644 index 0000000..13a24a2 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Manifest.lock @@ -0,0 +1,16 @@ +PODS: + - XLPagerTabStrip (9.0.0) + +DEPENDENCIES: + - XLPagerTabStrip (~> 9.0) + +SPEC REPOS: + trunk: + - XLPagerTabStrip + +SPEC CHECKSUMS: + XLPagerTabStrip: 61c57fd61f611ee5f01ff1495ad6fbee8bf496c5 + +PODFILE CHECKSUM: 14b0ad190cb8f4176a4dc4c328393c60dc791e5b + +COCOAPODS: 1.8.4 diff --git a/TrainingXLPagerTabStrip/Pods/Pods.xcodeproj/project.pbxproj b/TrainingXLPagerTabStrip/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9bedbab --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,778 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 1B7E7B16CDEC321A263291419E7CE00B /* XLPagerTabStrip.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 78BA4BB1A553AB4136F879792D99C87D /* XLPagerTabStrip.bundle */; }; + 28336F1C947B57D07831C63C31B84A0C /* IndicatorInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ED0FB1DFD0FD5C5EF6E380D9D5DA73E /* IndicatorInfo.swift */; }; + 2B39B33ECADFF6B44583C4DBA8854A9C /* ButtonBarViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5794F85C5DE025295185B3B91013B710 /* ButtonBarViewCell.swift */; }; + 2BC8DF4EADD024A30A84555CB575CAC6 /* SwipeDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36EBC5AF914E2A4F83EBFB42052A4147 /* SwipeDirection.swift */; }; + 2DABB7F30476F072B6A15D510614C93E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 312B988EF117AE4DE76A268D970131FE /* UIKit.framework */; }; + 311557DC2943E068608D1B6A7B663232 /* SegmentedPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FB14C25505A4AC6A7BC2666B105A582 /* SegmentedPagerTabStripViewController.swift */; }; + 399F2A0161278488DC1E5ADD297DE3B7 /* BaseButtonBarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE9175D11C67841744A3D79FDD07432 /* BaseButtonBarPagerTabStripViewController.swift */; }; + 3F1E6AE0B8A22678DB406AE072F213FC /* PagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD998D9956F8E44E334BB5EA7A6C2D6B /* PagerTabStripViewController.swift */; }; + 445D61C3F4F1E353873FE474EA856E02 /* FXPageControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 400770E843EECC0090CE7BCE153A398A /* FXPageControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4F86F33F807A003D18DEDBCA01210037 /* BarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52CA94DE37FFF07BD65D80A263915CFD /* BarView.swift */; }; + 59BA6FD61F0A9B68CD58C371DA1F1D60 /* BarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E286B8960AA0878D5ABEFEEA423AB41 /* BarPagerTabStripViewController.swift */; }; + 69B419B8DBDE3DC6EA250BA01BEEAC62 /* XLPagerTabStrip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3042A64B5530F9457E0537D70A61A8C4 /* XLPagerTabStrip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6A332AF6C1B4A44654EEA9A031A751F6 /* ButtonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 772BB489EA695E9C0C8B76EC5D2F90EB /* ButtonCell.xib */; }; + 701A2CA5C91621CDFC253F5D1FC422F7 /* Pods-TrainingXLPagerTabStrip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FE9FA01DEEC999B26A581F917934226 /* Pods-TrainingXLPagerTabStrip-dummy.m */; }; + 775542D5BE6B24392EF7FCA2CE7C5E97 /* TwitterPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC2961763AA246B0732E582749520E6C /* TwitterPagerTabStripViewController.swift */; }; + 7CB8B7C83DFD8A7B763433345BFE417F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 436BAA54A31999B53B3CC7115C55FE50 /* Foundation.framework */; }; + 911CC04F55219F3CB8EE70FA8F7347E7 /* ButtonBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E393287CE7695AFB080F9CC17FAD75F3 /* ButtonBarView.swift */; }; + A26276F206FFA15CF0A57BE54526140C /* XLPagerTabStrip-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A9C25E04177AABC2EF45D6A58FF189AA /* XLPagerTabStrip-dummy.m */; }; + A46FE9297CF389BBEE797C369CDB5AD2 /* Pods-TrainingXLPagerTabStrip-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D96ADA13CE1DF4EE146CD4E6A96D3EE /* Pods-TrainingXLPagerTabStrip-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A7AEEE825346429BB80914A7D2365A51 /* PagerTabStripBehaviour.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8973188062F58242DAC9535B26DBBD98 /* PagerTabStripBehaviour.swift */; }; + E554C1894F7994C45693A532CC18769A /* ButtonBarPagerTabStripViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BB09B05EAD18A2230E99ACC3749D5D8 /* ButtonBarPagerTabStripViewController.swift */; }; + F2E3366710556B8D518FF6F12259CFA5 /* PagerTabStripError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33389AE8178458A26F9FACC5C030383 /* PagerTabStripError.swift */; }; + F805832DAAFB6DFA063DCE467BC59B9F /* FXPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 3201347FE0101E02F67D29E374C0BBCF /* FXPageControl.m */; }; + FB7C01AB26481D05ABFF2C7F60D7D67C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 436BAA54A31999B53B3CC7115C55FE50 /* Foundation.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 5B8329DD02E7A5BBD4BB45C327ED895A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBF90A3A56D4C5830C212D000AB67BC1; + remoteInfo = "XLPagerTabStrip-XLPagerTabStrip"; + }; + C6242154D4FBE78C95BEF6AA8548102C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC5C3A7662FFA04D04D29F4657D032CE; + remoteInfo = XLPagerTabStrip; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 06BB9DBDA6B8F07B629C6F22A9E46000 /* Pods-TrainingXLPagerTabStrip-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TrainingXLPagerTabStrip-acknowledgements.markdown"; sourceTree = ""; }; + 25CD360BFC03FF98C31CE6C01DDCFB95 /* Pods-TrainingXLPagerTabStrip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-TrainingXLPagerTabStrip.modulemap"; sourceTree = ""; }; + 3042A64B5530F9457E0537D70A61A8C4 /* XLPagerTabStrip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XLPagerTabStrip-umbrella.h"; sourceTree = ""; }; + 312B988EF117AE4DE76A268D970131FE /* 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; }; + 3201347FE0101E02F67D29E374C0BBCF /* FXPageControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FXPageControl.m; path = Sources/FXPageControl.m; sourceTree = ""; }; + 35528C6A1D760E0ED1D42B0EBC978704 /* Pods_TrainingXLPagerTabStrip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = Pods_TrainingXLPagerTabStrip.framework; path = "Pods-TrainingXLPagerTabStrip.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; + 36EBC5AF914E2A4F83EBFB42052A4147 /* SwipeDirection.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwipeDirection.swift; path = Sources/SwipeDirection.swift; sourceTree = ""; }; + 400770E843EECC0090CE7BCE153A398A /* FXPageControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FXPageControl.h; path = Sources/FXPageControl.h; sourceTree = ""; }; + 436BAA54A31999B53B3CC7115C55FE50 /* 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; }; + 44762CA3ADEA5496653B4A9789BDF4ED /* XLPagerTabStrip.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = XLPagerTabStrip.modulemap; sourceTree = ""; }; + 4E286B8960AA0878D5ABEFEEA423AB41 /* BarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarPagerTabStripViewController.swift; path = Sources/BarPagerTabStripViewController.swift; sourceTree = ""; }; + 4ED0FB1DFD0FD5C5EF6E380D9D5DA73E /* IndicatorInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IndicatorInfo.swift; path = Sources/IndicatorInfo.swift; sourceTree = ""; }; + 52CA94DE37FFF07BD65D80A263915CFD /* BarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarView.swift; path = Sources/BarView.swift; sourceTree = ""; }; + 5794F85C5DE025295185B3B91013B710 /* ButtonBarViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarViewCell.swift; path = Sources/ButtonBarViewCell.swift; sourceTree = ""; }; + 5B8D3AB301BC8B3B0535B62B185661DA /* XLPagerTabStrip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "XLPagerTabStrip-Info.plist"; sourceTree = ""; }; + 5BB09B05EAD18A2230E99ACC3749D5D8 /* ButtonBarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarPagerTabStripViewController.swift; path = Sources/ButtonBarPagerTabStripViewController.swift; sourceTree = ""; }; + 6FDF43F03BBCC051C75FA2C9C70BCA36 /* ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist"; sourceTree = ""; }; + 772BB489EA695E9C0C8B76EC5D2F90EB /* ButtonCell.xib */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file.xib; name = ButtonCell.xib; path = Sources/ButtonCell.xib; sourceTree = ""; }; + 78BA4BB1A553AB4136F879792D99C87D /* XLPagerTabStrip.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = XLPagerTabStrip.bundle; path = "XLPagerTabStrip-XLPagerTabStrip.bundle"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FB14C25505A4AC6A7BC2666B105A582 /* SegmentedPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SegmentedPagerTabStripViewController.swift; path = Sources/SegmentedPagerTabStripViewController.swift; sourceTree = ""; }; + 8973188062F58242DAC9535B26DBBD98 /* PagerTabStripBehaviour.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripBehaviour.swift; path = Sources/PagerTabStripBehaviour.swift; sourceTree = ""; }; + 8FE9FA01DEEC999B26A581F917934226 /* Pods-TrainingXLPagerTabStrip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TrainingXLPagerTabStrip-dummy.m"; sourceTree = ""; }; + 97708219483A35BF52A0F6BD4D46C687 /* Pods-TrainingXLPagerTabStrip-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TrainingXLPagerTabStrip-acknowledgements.plist"; 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; }; + 9D96ADA13CE1DF4EE146CD4E6A96D3EE /* Pods-TrainingXLPagerTabStrip-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TrainingXLPagerTabStrip-umbrella.h"; sourceTree = ""; }; + A0B6F27DE3C02BF2E448E620F477FF22 /* Pods-TrainingXLPagerTabStrip.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TrainingXLPagerTabStrip.debug.xcconfig"; sourceTree = ""; }; + A9C25E04177AABC2EF45D6A58FF189AA /* XLPagerTabStrip-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "XLPagerTabStrip-dummy.m"; sourceTree = ""; }; + AC2961763AA246B0732E582749520E6C /* TwitterPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TwitterPagerTabStripViewController.swift; path = Sources/TwitterPagerTabStripViewController.swift; sourceTree = ""; }; + AD998D9956F8E44E334BB5EA7A6C2D6B /* PagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripViewController.swift; path = Sources/PagerTabStripViewController.swift; sourceTree = ""; }; + BE081545676A9DDA498433907A0E52CB /* XLPagerTabStrip.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = XLPagerTabStrip.xcconfig; sourceTree = ""; }; + CA47AEE4D3EF2D7ECAF235BF8640CC2E /* Pods-TrainingXLPagerTabStrip-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TrainingXLPagerTabStrip-Info.plist"; sourceTree = ""; }; + CB8B406794310E576133E3A0B6BEAE60 /* Pods-TrainingXLPagerTabStrip-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TrainingXLPagerTabStrip-frameworks.sh"; sourceTree = ""; }; + D228EC3A182B7AF98BC197599DFFF5F8 /* Pods-TrainingXLPagerTabStrip.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TrainingXLPagerTabStrip.release.xcconfig"; sourceTree = ""; }; + D33389AE8178458A26F9FACC5C030383 /* PagerTabStripError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PagerTabStripError.swift; path = Sources/PagerTabStripError.swift; sourceTree = ""; }; + D618DB4DA1F1773D9F322EF9C4C7259E /* XLPagerTabStrip-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "XLPagerTabStrip-prefix.pch"; sourceTree = ""; }; + E393287CE7695AFB080F9CC17FAD75F3 /* ButtonBarView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ButtonBarView.swift; path = Sources/ButtonBarView.swift; sourceTree = ""; }; + EAE9175D11C67841744A3D79FDD07432 /* BaseButtonBarPagerTabStripViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BaseButtonBarPagerTabStripViewController.swift; path = Sources/BaseButtonBarPagerTabStripViewController.swift; sourceTree = ""; }; + F1DDEA945255A18F0B9913AB1C2AB718 /* XLPagerTabStrip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = XLPagerTabStrip.framework; path = XLPagerTabStrip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0FD2D10FD6321FFD178496667854F045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A5FF0531E932EC9C748D4B918305397F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7CB8B7C83DFD8A7B763433345BFE417F /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AF7861E3E33A6BA2B9F973559B8C53D5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FB7C01AB26481D05ABFF2C7F60D7D67C /* Foundation.framework in Frameworks */, + 2DABB7F30476F072B6A15D510614C93E /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */ = { + isa = PBXGroup; + children = ( + E2983683FD097A93297E2F5D4E382B36 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + 387564B26554EF4F86ED93D94A9BF884 /* XLPagerTabStrip */ = { + isa = PBXGroup; + children = ( + 4E286B8960AA0878D5ABEFEEA423AB41 /* BarPagerTabStripViewController.swift */, + 52CA94DE37FFF07BD65D80A263915CFD /* BarView.swift */, + EAE9175D11C67841744A3D79FDD07432 /* BaseButtonBarPagerTabStripViewController.swift */, + 5BB09B05EAD18A2230E99ACC3749D5D8 /* ButtonBarPagerTabStripViewController.swift */, + E393287CE7695AFB080F9CC17FAD75F3 /* ButtonBarView.swift */, + 5794F85C5DE025295185B3B91013B710 /* ButtonBarViewCell.swift */, + 400770E843EECC0090CE7BCE153A398A /* FXPageControl.h */, + 3201347FE0101E02F67D29E374C0BBCF /* FXPageControl.m */, + 4ED0FB1DFD0FD5C5EF6E380D9D5DA73E /* IndicatorInfo.swift */, + 8973188062F58242DAC9535B26DBBD98 /* PagerTabStripBehaviour.swift */, + D33389AE8178458A26F9FACC5C030383 /* PagerTabStripError.swift */, + AD998D9956F8E44E334BB5EA7A6C2D6B /* PagerTabStripViewController.swift */, + 7FB14C25505A4AC6A7BC2666B105A582 /* SegmentedPagerTabStripViewController.swift */, + 36EBC5AF914E2A4F83EBFB42052A4147 /* SwipeDirection.swift */, + AC2961763AA246B0732E582749520E6C /* TwitterPagerTabStripViewController.swift */, + 5D7176543B1057EAFB9E7588611AED9D /* Resources */, + 4C91EAF5340372C1E6F0F96943934682 /* Support Files */, + ); + name = XLPagerTabStrip; + path = XLPagerTabStrip; + sourceTree = ""; + }; + 47380D26E832E71B8DEA6585A06F795F /* Pods */ = { + isa = PBXGroup; + children = ( + 387564B26554EF4F86ED93D94A9BF884 /* XLPagerTabStrip */, + ); + name = Pods; + sourceTree = ""; + }; + 4C91EAF5340372C1E6F0F96943934682 /* Support Files */ = { + isa = PBXGroup; + children = ( + 6FDF43F03BBCC051C75FA2C9C70BCA36 /* ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist */, + 44762CA3ADEA5496653B4A9789BDF4ED /* XLPagerTabStrip.modulemap */, + BE081545676A9DDA498433907A0E52CB /* XLPagerTabStrip.xcconfig */, + A9C25E04177AABC2EF45D6A58FF189AA /* XLPagerTabStrip-dummy.m */, + 5B8D3AB301BC8B3B0535B62B185661DA /* XLPagerTabStrip-Info.plist */, + D618DB4DA1F1773D9F322EF9C4C7259E /* XLPagerTabStrip-prefix.pch */, + 3042A64B5530F9457E0537D70A61A8C4 /* XLPagerTabStrip-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/XLPagerTabStrip"; + sourceTree = ""; + }; + 5D7176543B1057EAFB9E7588611AED9D /* Resources */ = { + isa = PBXGroup; + children = ( + 772BB489EA695E9C0C8B76EC5D2F90EB /* ButtonCell.xib */, + ); + name = Resources; + sourceTree = ""; + }; + 7F786C084A5A8954E23852514B9B1600 /* Products */ = { + isa = PBXGroup; + children = ( + 35528C6A1D760E0ED1D42B0EBC978704 /* Pods_TrainingXLPagerTabStrip.framework */, + 78BA4BB1A553AB4136F879792D99C87D /* XLPagerTabStrip.bundle */, + F1DDEA945255A18F0B9913AB1C2AB718 /* XLPagerTabStrip.framework */, + ); + name = Products; + sourceTree = ""; + }; + A20C695FD47E84CA0F121ED4026D6D60 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + E55272AB9C01EFFFAF58BA903A76E1C4 /* Pods-TrainingXLPagerTabStrip */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + CF1408CF629C7361332E53B88F7BD30C = { + isa = PBXGroup; + children = ( + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, + 1628BF05B4CAFDCC3549A101F5A10A17 /* Frameworks */, + 47380D26E832E71B8DEA6585A06F795F /* Pods */, + 7F786C084A5A8954E23852514B9B1600 /* Products */, + A20C695FD47E84CA0F121ED4026D6D60 /* Targets Support Files */, + ); + sourceTree = ""; + }; + E2983683FD097A93297E2F5D4E382B36 /* iOS */ = { + isa = PBXGroup; + children = ( + 436BAA54A31999B53B3CC7115C55FE50 /* Foundation.framework */, + 312B988EF117AE4DE76A268D970131FE /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + E55272AB9C01EFFFAF58BA903A76E1C4 /* Pods-TrainingXLPagerTabStrip */ = { + isa = PBXGroup; + children = ( + 25CD360BFC03FF98C31CE6C01DDCFB95 /* Pods-TrainingXLPagerTabStrip.modulemap */, + 06BB9DBDA6B8F07B629C6F22A9E46000 /* Pods-TrainingXLPagerTabStrip-acknowledgements.markdown */, + 97708219483A35BF52A0F6BD4D46C687 /* Pods-TrainingXLPagerTabStrip-acknowledgements.plist */, + 8FE9FA01DEEC999B26A581F917934226 /* Pods-TrainingXLPagerTabStrip-dummy.m */, + CB8B406794310E576133E3A0B6BEAE60 /* Pods-TrainingXLPagerTabStrip-frameworks.sh */, + CA47AEE4D3EF2D7ECAF235BF8640CC2E /* Pods-TrainingXLPagerTabStrip-Info.plist */, + 9D96ADA13CE1DF4EE146CD4E6A96D3EE /* Pods-TrainingXLPagerTabStrip-umbrella.h */, + A0B6F27DE3C02BF2E448E620F477FF22 /* Pods-TrainingXLPagerTabStrip.debug.xcconfig */, + D228EC3A182B7AF98BC197599DFFF5F8 /* Pods-TrainingXLPagerTabStrip.release.xcconfig */, + ); + name = "Pods-TrainingXLPagerTabStrip"; + path = "Target Support Files/Pods-TrainingXLPagerTabStrip"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 2E74127AF027B11FF09F7F50BB4B9622 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 445D61C3F4F1E353873FE474EA856E02 /* FXPageControl.h in Headers */, + 69B419B8DBDE3DC6EA250BA01BEEAC62 /* XLPagerTabStrip-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ABD8FC3462403DF0AC0B386175DC9203 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A46FE9297CF389BBEE797C369CDB5AD2 /* Pods-TrainingXLPagerTabStrip-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 26E2F5DBF9AFB74E23145E8BEF9E20F3 /* Pods-TrainingXLPagerTabStrip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0BAA8EDC20628766334FACA7A9ACDCC1 /* Build configuration list for PBXNativeTarget "Pods-TrainingXLPagerTabStrip" */; + buildPhases = ( + ABD8FC3462403DF0AC0B386175DC9203 /* Headers */, + D2F30E290B1D6C35E109872D9211159C /* Sources */, + A5FF0531E932EC9C748D4B918305397F /* Frameworks */, + 51AEF600B46265F0668396167DF2EEE1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E9B6AD4DEF11A32678F4B1FF9751C0DD /* PBXTargetDependency */, + ); + name = "Pods-TrainingXLPagerTabStrip"; + productName = "Pods-TrainingXLPagerTabStrip"; + productReference = 35528C6A1D760E0ED1D42B0EBC978704 /* Pods_TrainingXLPagerTabStrip.framework */; + productType = "com.apple.product-type.framework"; + }; + DC5C3A7662FFA04D04D29F4657D032CE /* XLPagerTabStrip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 88D866DA052EF93195E917061DB86D9A /* Build configuration list for PBXNativeTarget "XLPagerTabStrip" */; + buildPhases = ( + 2E74127AF027B11FF09F7F50BB4B9622 /* Headers */, + BCDC6490FBBA170437C0B29649B4ED6F /* Sources */, + AF7861E3E33A6BA2B9F973559B8C53D5 /* Frameworks */, + 47847C1AE9C5FA9092141B090DA283A9 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8608636E5CBFC36C931368912AC4340E /* PBXTargetDependency */, + ); + name = XLPagerTabStrip; + productName = XLPagerTabStrip; + productReference = F1DDEA945255A18F0B9913AB1C2AB718 /* XLPagerTabStrip.framework */; + productType = "com.apple.product-type.framework"; + }; + EBF90A3A56D4C5830C212D000AB67BC1 /* XLPagerTabStrip-XLPagerTabStrip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0DC3A1F894722359353AC05A476C7644 /* Build configuration list for PBXNativeTarget "XLPagerTabStrip-XLPagerTabStrip" */; + buildPhases = ( + E55B2DFC65133EF5AF928D548C83EA56 /* Sources */, + 0FD2D10FD6321FFD178496667854F045 /* Frameworks */, + 1E70F53E5F27CFA6149993D34EA76E62 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "XLPagerTabStrip-XLPagerTabStrip"; + productName = "XLPagerTabStrip-XLPagerTabStrip"; + productReference = 78BA4BB1A553AB4136F879792D99C87D /* XLPagerTabStrip.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + BFDFE7DC352907FC980B868725387E98 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; + }; + buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = CF1408CF629C7361332E53B88F7BD30C; + productRefGroup = 7F786C084A5A8954E23852514B9B1600 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 26E2F5DBF9AFB74E23145E8BEF9E20F3 /* Pods-TrainingXLPagerTabStrip */, + DC5C3A7662FFA04D04D29F4657D032CE /* XLPagerTabStrip */, + EBF90A3A56D4C5830C212D000AB67BC1 /* XLPagerTabStrip-XLPagerTabStrip */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1E70F53E5F27CFA6149993D34EA76E62 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6A332AF6C1B4A44654EEA9A031A751F6 /* ButtonCell.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 47847C1AE9C5FA9092141B090DA283A9 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1B7E7B16CDEC321A263291419E7CE00B /* XLPagerTabStrip.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51AEF600B46265F0668396167DF2EEE1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + BCDC6490FBBA170437C0B29649B4ED6F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 59BA6FD61F0A9B68CD58C371DA1F1D60 /* BarPagerTabStripViewController.swift in Sources */, + 4F86F33F807A003D18DEDBCA01210037 /* BarView.swift in Sources */, + 399F2A0161278488DC1E5ADD297DE3B7 /* BaseButtonBarPagerTabStripViewController.swift in Sources */, + E554C1894F7994C45693A532CC18769A /* ButtonBarPagerTabStripViewController.swift in Sources */, + 911CC04F55219F3CB8EE70FA8F7347E7 /* ButtonBarView.swift in Sources */, + 2B39B33ECADFF6B44583C4DBA8854A9C /* ButtonBarViewCell.swift in Sources */, + F805832DAAFB6DFA063DCE467BC59B9F /* FXPageControl.m in Sources */, + 28336F1C947B57D07831C63C31B84A0C /* IndicatorInfo.swift in Sources */, + A7AEEE825346429BB80914A7D2365A51 /* PagerTabStripBehaviour.swift in Sources */, + F2E3366710556B8D518FF6F12259CFA5 /* PagerTabStripError.swift in Sources */, + 3F1E6AE0B8A22678DB406AE072F213FC /* PagerTabStripViewController.swift in Sources */, + 311557DC2943E068608D1B6A7B663232 /* SegmentedPagerTabStripViewController.swift in Sources */, + 2BC8DF4EADD024A30A84555CB575CAC6 /* SwipeDirection.swift in Sources */, + 775542D5BE6B24392EF7FCA2CE7C5E97 /* TwitterPagerTabStripViewController.swift in Sources */, + A26276F206FFA15CF0A57BE54526140C /* XLPagerTabStrip-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D2F30E290B1D6C35E109872D9211159C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 701A2CA5C91621CDFC253F5D1FC422F7 /* Pods-TrainingXLPagerTabStrip-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E55B2DFC65133EF5AF928D548C83EA56 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8608636E5CBFC36C931368912AC4340E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "XLPagerTabStrip-XLPagerTabStrip"; + target = EBF90A3A56D4C5830C212D000AB67BC1 /* XLPagerTabStrip-XLPagerTabStrip */; + targetProxy = 5B8329DD02E7A5BBD4BB45C327ED895A /* PBXContainerItemProxy */; + }; + E9B6AD4DEF11A32678F4B1FF9751C0DD /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = XLPagerTabStrip; + target = DC5C3A7662FFA04D04D29F4657D032CE /* XLPagerTabStrip */; + targetProxy = C6242154D4FBE78C95BEF6AA8548102C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 32A41CBCA398292BC9A11DD5846CD79C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A0B6F27DE3C02BF2E448E620F477FF22 /* Pods-TrainingXLPagerTabStrip.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-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.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; + }; + 58C6AEA56689CFE0595D13BE333D7BC7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE081545676A9DDA498433907A0E52CB /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/XLPagerTabStrip"; + IBSC_MODULE = 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; + }; + 653458889DD330BC821EF8E2A0B337E0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D228EC3A182B7AF98BC197599DFFF5F8 /* Pods-TrainingXLPagerTabStrip.release.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-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.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"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 939F1A8F6BCEB7F9F64D9EEE50CAE014 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 9F0443855CA5B9A50AE6FEE5D362E6B0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE081545676A9DDA498433907A0E52CB /* 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; + }; + D1C3A9887FA027696EA4F68AB3247B46 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE081545676A9DDA498433907A0E52CB /* XLPagerTabStrip.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/XLPagerTabStrip"; + IBSC_MODULE = 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; + }; + D43951F6AFB26750906F6BC3783C430A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE081545676A9DDA498433907A0E52CB /* 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; + }; + ECB437504DF805BD96CAABF97400B526 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0BAA8EDC20628766334FACA7A9ACDCC1 /* Build configuration list for PBXNativeTarget "Pods-TrainingXLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32A41CBCA398292BC9A11DD5846CD79C /* Debug */, + 653458889DD330BC821EF8E2A0B337E0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0DC3A1F894722359353AC05A476C7644 /* Build configuration list for PBXNativeTarget "XLPagerTabStrip-XLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58C6AEA56689CFE0595D13BE333D7BC7 /* Debug */, + D1C3A9887FA027696EA4F68AB3247B46 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 939F1A8F6BCEB7F9F64D9EEE50CAE014 /* Debug */, + ECB437504DF805BD96CAABF97400B526 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 88D866DA052EF93195E917061DB86D9A /* Build configuration list for PBXNativeTarget "XLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9F0443855CA5B9A50AE6FEE5D362E6B0 /* Debug */, + D43951F6AFB26750906F6BC3783C430A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; +} diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-Info.plist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.markdown b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.markdown new file mode 100644 index 0000000..d48f271 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.markdown @@ -0,0 +1,28 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## 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/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.plist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.plist new file mode 100644 index 0000000..1010dd4 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-acknowledgements.plist @@ -0,0 +1,60 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + 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 + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-dummy.m b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-dummy.m new file mode 100644 index 0000000..a1034c6 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TrainingXLPagerTabStrip : NSObject +@end +@implementation PodsDummy_Pods_TrainingXLPagerTabStrip +@end diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-input-files.xcfilelist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-input-files.xcfilelist new file mode 100644 index 0000000..a53477e --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-input-files.xcfilelist @@ -0,0 +1,2 @@ +${PODS_ROOT}/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh +${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-output-files.xcfilelist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-output-files.xcfilelist new file mode 100644 index 0000000..375aa80 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Debug-output-files.xcfilelist @@ -0,0 +1 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XLPagerTabStrip.framework \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-input-files.xcfilelist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-input-files.xcfilelist new file mode 100644 index 0000000..a53477e --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-input-files.xcfilelist @@ -0,0 +1,2 @@ +${PODS_ROOT}/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh +${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-output-files.xcfilelist b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-output-files.xcfilelist new file mode 100644 index 0000000..375aa80 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-Release-output-files.xcfilelist @@ -0,0 +1 @@ +${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/XLPagerTabStrip.framework \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh new file mode 100755 index 0000000..bf22d21 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh @@ -0,0 +1,171 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +function on_error { + echo "$(realpath -mq "${0}"):$1: error: Unexpected failure" +} +trap 'on_error $LINENO' ERR + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + elif [ -L "${binary}" ]; then + echo "Destination binary is symlinked..." + dirname="$(dirname "${binary}")" + binary="${dirname}/$(readlink "${binary}")" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O "*"dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Copies the bcsymbolmap files of a vendored framework +install_bcsymbolmap() { + local bcsymbolmap_path="$1" + local destination="${BUILT_PRODUCTS_DIR}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${bcsymbolmap_path}" "${destination}" +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identity + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-umbrella.h b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-umbrella.h new file mode 100644 index 0000000..183ab5a --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-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 Pods_TrainingXLPagerTabStripVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TrainingXLPagerTabStripVersionString[]; + diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.debug.xcconfig b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.debug.xcconfig new file mode 100644 index 0000000..ad3894e --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.debug.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -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) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.modulemap b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.modulemap new file mode 100644 index 0000000..5fb2a24 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TrainingXLPagerTabStrip { + umbrella header "Pods-TrainingXLPagerTabStrip-umbrella.h" + + export * + module * { export * } +} diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.release.xcconfig b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.release.xcconfig new file mode 100644 index 0000000..ad3894e --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.release.xcconfig @@ -0,0 +1,12 @@ +ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/XLPagerTabStrip/XLPagerTabStrip.framework/Headers" +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_LDFLAGS = $(inherited) -framework "Foundation" -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) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/ResourceBundle-XLPagerTabStrip-XLPagerTabStrip-Info.plist new file mode 100644 index 0000000..885dc7a --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-Info.plist new file mode 100644 index 0000000..ee83e4d --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-dummy.m b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-dummy.m new file mode 100644 index 0000000..a2a5f5d --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-umbrella.h b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip-umbrella.h new file mode 100644 index 0000000..f2d3ecc --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.modulemap new file mode 100644 index 0000000..999fe0e --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig new file mode 100644 index 0000000..1f948e5 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/Target Support Files/XLPagerTabStrip/XLPagerTabStrip.xcconfig @@ -0,0 +1,11 @@ +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 +USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES diff --git a/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/LICENSE b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/LICENSE new file mode 100644 index 0000000..fb6581a --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/README.md b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/README.md new file mode 100644 index 0000000..d9d5e2b --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BarPagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BarPagerTabStripViewController.swift new file mode 100644 index 0000000..e231268 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BarView.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BarView.swift new file mode 100644 index 0000000..1183524 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BaseButtonBarPagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/BaseButtonBarPagerTabStripViewController.swift new file mode 100644 index 0000000..68684ac --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarPagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarPagerTabStripViewController.swift new file mode 100644 index 0000000..36e008d --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarView.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarView.swift new file mode 100644 index 0000000..a204971 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarViewCell.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonBarViewCell.swift new file mode 100644 index 0000000..a16e02f --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonCell.xib b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonCell.xib new file mode 100644 index 0000000..7025bc7 --- /dev/null +++ b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/ButtonCell.xib @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/FXPageControl.h b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/FXPageControl.h new file mode 100755 index 0000000..37a0438 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/FXPageControl.m b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/FXPageControl.m new file mode 100755 index 0000000..01602e8 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/IndicatorInfo.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/IndicatorInfo.swift new file mode 100644 index 0000000..146eb9a --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripBehaviour.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripBehaviour.swift new file mode 100644 index 0000000..1ad9dea --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripError.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripError.swift new file mode 100644 index 0000000..f345365 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/PagerTabStripViewController.swift new file mode 100644 index 0000000..9aedb7d --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/SegmentedPagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/SegmentedPagerTabStripViewController.swift new file mode 100644 index 0000000..cdd3fb1 --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/SwipeDirection.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/SwipeDirection.swift new file mode 100644 index 0000000..d032c7d --- /dev/null +++ b/TrainingXLPagerTabStrip/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/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/TwitterPagerTabStripViewController.swift b/TrainingXLPagerTabStrip/Pods/XLPagerTabStrip/Sources/TwitterPagerTabStripViewController.swift new file mode 100644 index 0000000..c37215a --- /dev/null +++ b/TrainingXLPagerTabStrip/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 + } +} diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.pbxproj b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.pbxproj new file mode 100644 index 0000000..36d32e8 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.pbxproj @@ -0,0 +1,417 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXBuildFile section */ + 11C1374DF2E9B0E9AA7C04C4 /* Pods_TrainingXLPagerTabStrip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2EBD88D195FF04B872B1AF83 /* Pods_TrainingXLPagerTabStrip.framework */; }; + 550E72732437080C0093A23C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 550E72722437080C0093A23C /* AppDelegate.swift */; }; + 550E72752437080C0093A23C /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 550E72742437080C0093A23C /* SceneDelegate.swift */; }; + 550E72772437080C0093A23C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 550E72762437080C0093A23C /* ViewController.swift */; }; + 550E727A2437080C0093A23C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 550E72782437080C0093A23C /* Main.storyboard */; }; + 550E727C2437080D0093A23C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 550E727B2437080D0093A23C /* Assets.xcassets */; }; + 550E727F2437080D0093A23C /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 550E727D2437080D0093A23C /* LaunchScreen.storyboard */; }; + 55D4F3C324370D8300DA4B88 /* ChildViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55D4F3C224370D8300DA4B88 /* ChildViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2EBD88D195FF04B872B1AF83 /* Pods_TrainingXLPagerTabStrip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TrainingXLPagerTabStrip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 550E726F2437080C0093A23C /* TrainingXLPagerTabStrip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrainingXLPagerTabStrip.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 550E72722437080C0093A23C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 550E72742437080C0093A23C /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 550E72762437080C0093A23C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 550E72792437080C0093A23C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 550E727B2437080D0093A23C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 550E727E2437080D0093A23C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 550E72802437080D0093A23C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 55D4F3C224370D8300DA4B88 /* ChildViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChildViewController.swift; sourceTree = ""; }; + 874CB45B108E532C6D7E5928 /* Pods-TrainingXLPagerTabStrip.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrainingXLPagerTabStrip.debug.xcconfig"; path = "Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.debug.xcconfig"; sourceTree = ""; }; + B6B43179CC6CAC21D7A856F3 /* Pods-TrainingXLPagerTabStrip.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TrainingXLPagerTabStrip.release.xcconfig"; path = "Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 550E726C2437080C0093A23C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 11C1374DF2E9B0E9AA7C04C4 /* Pods_TrainingXLPagerTabStrip.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 550E72662437080C0093A23C = { + isa = PBXGroup; + children = ( + 550E72712437080C0093A23C /* TrainingXLPagerTabStrip */, + 550E72702437080C0093A23C /* Products */, + C3379E951DF14A3ACDDD0BEC /* Pods */, + B1E380C8CA78EEC43CFA7E29 /* Frameworks */, + ); + sourceTree = ""; + }; + 550E72702437080C0093A23C /* Products */ = { + isa = PBXGroup; + children = ( + 550E726F2437080C0093A23C /* TrainingXLPagerTabStrip.app */, + ); + name = Products; + sourceTree = ""; + }; + 550E72712437080C0093A23C /* TrainingXLPagerTabStrip */ = { + isa = PBXGroup; + children = ( + 550E72722437080C0093A23C /* AppDelegate.swift */, + 550E72742437080C0093A23C /* SceneDelegate.swift */, + 550E72762437080C0093A23C /* ViewController.swift */, + 550E72782437080C0093A23C /* Main.storyboard */, + 550E727B2437080D0093A23C /* Assets.xcassets */, + 550E727D2437080D0093A23C /* LaunchScreen.storyboard */, + 550E72802437080D0093A23C /* Info.plist */, + 55D4F3C224370D8300DA4B88 /* ChildViewController.swift */, + ); + path = TrainingXLPagerTabStrip; + sourceTree = ""; + }; + B1E380C8CA78EEC43CFA7E29 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 2EBD88D195FF04B872B1AF83 /* Pods_TrainingXLPagerTabStrip.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + C3379E951DF14A3ACDDD0BEC /* Pods */ = { + isa = PBXGroup; + children = ( + 874CB45B108E532C6D7E5928 /* Pods-TrainingXLPagerTabStrip.debug.xcconfig */, + B6B43179CC6CAC21D7A856F3 /* Pods-TrainingXLPagerTabStrip.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 550E726E2437080C0093A23C /* TrainingXLPagerTabStrip */ = { + isa = PBXNativeTarget; + buildConfigurationList = 550E72832437080D0093A23C /* Build configuration list for PBXNativeTarget "TrainingXLPagerTabStrip" */; + buildPhases = ( + D1550E570C7F88C44D87F9C9 /* [CP] Check Pods Manifest.lock */, + 550E726B2437080C0093A23C /* Sources */, + 550E726C2437080C0093A23C /* Frameworks */, + 550E726D2437080C0093A23C /* Resources */, + 8D4C934BFCC6A4ECBB715A2D /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TrainingXLPagerTabStrip; + productName = TrainingXLPagerTabStrip; + productReference = 550E726F2437080C0093A23C /* TrainingXLPagerTabStrip.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 550E72672437080C0093A23C /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1130; + LastUpgradeCheck = 1130; + ORGANIZATIONNAME = jun; + TargetAttributes = { + 550E726E2437080C0093A23C = { + CreatedOnToolsVersion = 11.3.1; + }; + }; + }; + buildConfigurationList = 550E726A2437080C0093A23C /* Build configuration list for PBXProject "TrainingXLPagerTabStrip" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 550E72662437080C0093A23C; + productRefGroup = 550E72702437080C0093A23C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 550E726E2437080C0093A23C /* TrainingXLPagerTabStrip */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 550E726D2437080C0093A23C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 550E727F2437080D0093A23C /* LaunchScreen.storyboard in Resources */, + 550E727C2437080D0093A23C /* Assets.xcassets in Resources */, + 550E727A2437080C0093A23C /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 8D4C934BFCC6A4ECBB715A2D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-TrainingXLPagerTabStrip/Pods-TrainingXLPagerTabStrip-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + D1550E570C7F88C44D87F9C9 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-TrainingXLPagerTabStrip-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 550E726B2437080C0093A23C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 550E72772437080C0093A23C /* ViewController.swift in Sources */, + 550E72732437080C0093A23C /* AppDelegate.swift in Sources */, + 550E72752437080C0093A23C /* SceneDelegate.swift in Sources */, + 55D4F3C324370D8300DA4B88 /* ChildViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 550E72782437080C0093A23C /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 550E72792437080C0093A23C /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 550E727D2437080D0093A23C /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 550E727E2437080D0093A23C /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 550E72812437080D0093A23C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 550E72822437080D0093A23C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 550E72842437080D0093A23C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 874CB45B108E532C6D7E5928 /* Pods-TrainingXLPagerTabStrip.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = PMD54H53GA; + INFOPLIST_FILE = TrainingXLPagerTabStrip/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = gamsung.TrainingXLPagerTabStrip; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 550E72852437080D0093A23C /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B6B43179CC6CAC21D7A856F3 /* Pods-TrainingXLPagerTabStrip.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = PMD54H53GA; + INFOPLIST_FILE = TrainingXLPagerTabStrip/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = gamsung.TrainingXLPagerTabStrip; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 550E726A2437080C0093A23C /* Build configuration list for PBXProject "TrainingXLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 550E72812437080D0093A23C /* Debug */, + 550E72822437080D0093A23C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 550E72832437080D0093A23C /* Build configuration list for PBXNativeTarget "TrainingXLPagerTabStrip" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 550E72842437080D0093A23C /* Debug */, + 550E72852437080D0093A23C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 550E72672437080C0093A23C /* Project object */; +} diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..131678b --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/contents.xcworkspacedata b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..a26c112 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/AppDelegate.swift b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/AppDelegate.swift new file mode 100644 index 0000000..86d7e85 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/AppDelegate.swift @@ -0,0 +1,37 @@ +// +// AppDelegate.swift +// TrainingXLPagerTabStrip +// +// Created by IJ . on 2020/04/03. +// Copyright © 2020 jun. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/AppIcon.appiconset/Contents.json b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/Contents.json b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/LaunchScreen.storyboard b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/Main.storyboard b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/Main.storyboard new file mode 100644 index 0000000..e67cf7f --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Base.lproj/Main.storyboard @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ChildViewController.swift b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ChildViewController.swift new file mode 100644 index 0000000..c7adcf8 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ChildViewController.swift @@ -0,0 +1,35 @@ +// +// ChildViewController.swift +// TrainingXLPagerTabStrip +// +// Created by IJ . on 2020/04/03. +// Copyright © 2020 jun. All rights reserved. +// + +import UIKit +import XLPagerTabStrip +class ChildViewController: UIViewController, IndicatorInfoProvider { + + var childNumber: String = "" + + + @IBOutlet weak var childNameLabel: UILabel! + + + + override func viewDidLoad() { + super.viewDidLoad() + childNameLabel.text = childNumber + + } + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + + func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo { + return IndicatorInfo(title: "\(childNumber)") + } + + + +} diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Info.plist b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Info.plist new file mode 100644 index 0000000..2a3483c --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/SceneDelegate.swift b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/SceneDelegate.swift new file mode 100644 index 0000000..6603d8b --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/SceneDelegate.swift @@ -0,0 +1,53 @@ +// +// SceneDelegate.swift +// TrainingXLPagerTabStrip +// +// Created by IJ . on 2020/04/03. +// Copyright © 2020 jun. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ViewController.swift b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ViewController.swift new file mode 100644 index 0000000..1488353 --- /dev/null +++ b/TrainingXLPagerTabStrip/TrainingXLPagerTabStrip/ViewController.swift @@ -0,0 +1,50 @@ +// +// ViewController.swift +// TrainingXLPagerTabStrip +// +// Created by IJ . on 2020/04/03. +// Copyright © 2020 jun. All rights reserved. +// + +import UIKit +import XLPagerTabStrip + +class ViewController: ButtonBarPagerTabStripViewController { + + override func viewDidLoad() { + self.settings.style.buttonBarItemBackgroundColor = UIColor.white + self.settings.style.buttonBarItemTitleColor = UIColor.init(red: 213.0/255.0, green: 213.0/255.0, blue: 213.0/255.0, alpha: 1) + //선택된거 검은색 없음 + self.settings.style.buttonBarBackgroundColor = UIColor.white + // UIColor.init(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1) + + self.settings.style.selectedBarBackgroundColor = UIColor.init(red: 19.0/255.0, green: 139.0/255.0, blue: 255.0/255.0, alpha: 1) + self.settings.style.selectedBarHeight = 2.0 + + self.settings.style.buttonBarHeight = 130 + + changeCurrentIndexProgressive = { (oldCell: ButtonBarViewCell?, newCell: ButtonBarViewCell?, progressPercentage: CGFloat, changeCurrentIndex: Bool, animated: Bool) -> Void in + guard changeCurrentIndex == true else { return } + + oldCell?.label.textColor = UIColor.init(red: 213.0/255.0, green: 213.0/255.0, blue: 213.0/255.0, alpha: 1) + newCell?.label.textColor = UIColor.black + + + } + + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { + let child1 = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChildVC") as! ChildViewController + child1.childNumber = "One" + + let child2 = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChildVC") as! ChildViewController + child2.childNumber = "Two" + + return [child1, child2] + } + +} + diff --git a/practicePopupView/practicePopupView/PoPUPViewController.swift b/practicePopupView/practicePopupView/PoPUPViewController.swift index 21768a8..754ac66 100644 --- a/practicePopupView/practicePopupView/PoPUPViewController.swift +++ b/practicePopupView/practicePopupView/PoPUPViewController.swift @@ -14,7 +14,7 @@ class PoPUPViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - testView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector(("backgroundTap:")))) +// testView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: Selector(("backgroundTap:")))) // Do any additional setup after loading the view. } @@ -25,5 +25,12 @@ class PoPUPViewController: UIViewController { self.dismiss(animated: true, completion: nil) print(11111) } - + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + if touches.first?.view == testView { + return + } + self.dismiss(animated: true, completion: nil) + } + }