diff --git a/.gitignore b/.gitignore index 1de2633d..77a537f1 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,7 @@ Pods/ # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts -Carthage/Build +Carthage/* # fastlane # diff --git a/.travis.yml b/.travis.yml index bc1cd7f0..1fe4e843 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,12 @@ language: objective-c osx_image: xcode8.2 -branches: - only: - - master - - develop - before_install: - - pod repo update - +- brew update +- brew outdated carthage || brew upgrade carthage +- gem update fastlane --no-ri --no-rdoc --no-document script: - - xcodebuild -workspace Tabman.xcworkspace -scheme Tabman -destination 'platform=iOS Simulator,name=iPhone 7,OS=10.1' build test - - pod lib lint --quick - +- .travis/build.sh after_success: - - bash <(curl -s https://codecov.io/bash) - +- bash <(curl -s https://codecov.io/bash) notifications: - slack: - on_success: change - on_failure: always - secure: QmQzW3v8D5DQTsYztvBwpZVDxU/B8aWhdwiwj6kjwQ7/BYtKdgndXtgYpIDHNTytrFB7LKnH5xxq2sDdbn9qr85ICi4cdatzPwb3uty8LnbV92KSxnjM1D7Ze1zDp86U773yfJZWlsb/Bz9/AXKxBCOlr9QiU/cbqrLZjufIRI9vHsrC+eLQlQrKNKNRfFZAUdFuCsbFqk05Cg6MVAtNXa+SSWbyCJBmxu4IGkfEpo2IbIeD17gYxmnu9yRH1s/8/U86uSyZw4bmaDIfE1vM911lyZtIqE7BFXUUc+dQ2DgjlOC0FdE8Oa2Nni0B8P6cHkQijJo8XVixDTvpK03I9wPuiwpIQ5waOpx1e2UIkymKovyf4N2i2SM/g+KU4xmNrREYPZpS8NwMh7tYO6Y3/eBc3Oa0MkJiPdZmk7oUQqEKRo5krstFgS05gqhb1ycOdpGEou05n/8xXxS7ccsTexu6H8sjGV49NPvG4s2mX7Ps2UjZkL68SAY6GUOLAPrt8YE9vWC4Jhyn11xL+JhdACa+K/Pcd9IazfeT3zjt8F7juF2KFJwLuMBOnK3MbhinJA+n3VFfV4VKPA1IVTpjPGzsje9a50SloUOismsk9Ls0dViPsQmeFixjFw4ZfMUZXqruLXH7RdNfLrslE2H/1eLEsKMvnA1YlzQXL7PM5ao= + email: false \ No newline at end of file diff --git a/.travis/build.sh b/.travis/build.sh new file mode 100755 index 00000000..3bc8c029 --- /dev/null +++ b/.travis/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +fastlane test +if [ "${TRAVIS_BRANCH}" = "master" ]; then + fastlane deploy +fi \ No newline at end of file diff --git a/Artwork/artwork.sketch b/Artwork/artwork.sketch index 81609c71..5192c89b 100644 Binary files a/Artwork/artwork.sketch and b/Artwork/artwork.sketch differ diff --git a/Artwork/header.png b/Artwork/header.png index 18183402..082f141d 100644 Binary files a/Artwork/header.png and b/Artwork/header.png differ diff --git a/Artwork/logo.png b/Artwork/logo.png index c1b47815..c1160e0e 100644 Binary files a/Artwork/logo.png and b/Artwork/logo.png differ diff --git a/Artwork/styles.png b/Artwork/styles.png index 9f783f99..86f64c72 100644 Binary files a/Artwork/styles.png and b/Artwork/styles.png differ diff --git a/Cartfile b/Cartfile new file mode 100644 index 00000000..7ff4a67a --- /dev/null +++ b/Cartfile @@ -0,0 +1,2 @@ +github "PureLayout/PureLayout" "v3.0.2" +github "uias/Pageboy" "1.0.7" diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 00000000..43fd9c04 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1,2 @@ +github "PureLayout/PureLayout" "v3.0.2" +github "uias/Pageboy" "1.0.5" diff --git a/Example/Tabman-Example.xcodeproj/project.pbxproj b/Example/Tabman-Example.xcodeproj/project.pbxproj index 58c65813..3cb2e36a 100644 --- a/Example/Tabman-Example.xcodeproj/project.pbxproj +++ b/Example/Tabman-Example.xcodeproj/project.pbxproj @@ -3,11 +3,14 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ - 648A830D19F167B986EF7641 /* Pods_Tabman_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BC0D2B4D8925B627AF01AC3 /* Pods_Tabman_Example.framework */; }; + 7BF6B4961E9555DE00BE68B5 /* Pageboy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF6B4941E9555DE00BE68B5 /* Pageboy.framework */; }; + 7BF6B4971E9555DE00BE68B5 /* Pageboy.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF6B4941E9555DE00BE68B5 /* Pageboy.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7BF6B4981E9555DE00BE68B5 /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF6B4951E9555DE00BE68B5 /* PureLayout.framework */; }; + 7BF6B4991E9555DE00BE68B5 /* PureLayout.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7BF6B4951E9555DE00BE68B5 /* PureLayout.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D601367D1E6990650013CD42 /* CustomTabmanBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D601367C1E6990650013CD42 /* CustomTabmanBar.swift */; }; D616D06E1E72E2C600C7AA32 /* PresetAppearanceConfigs.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D06D1E72E2C600C7AA32 /* PresetAppearanceConfigs.swift */; }; D61E50BC1E64452D00AC8C75 /* CircularButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61E50BB1E64452D00AC8C75 /* CircularButton.swift */; }; @@ -31,8 +34,8 @@ D62AC10B1E5736A10020B8AE /* TabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1061E5736A10020B8AE /* TabViewController.swift */; }; D62AC10C1E5736A10020B8AE /* TabViewControllerExtras.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1071E5736A10020B8AE /* TabViewControllerExtras.swift */; }; D62AC10D1E5736A10020B8AE /* TransparentNavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1081E5736A10020B8AE /* TransparentNavigationBar.swift */; }; - D6C759781E83CFAA00471973 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = D6C759751E83CFA300471973 /* Tabman.framework */; }; - D6C759791E83CFAA00471973 /* ReferenceProxy in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6C759751E83CFA300471973 /* Tabman.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + D6C759781E83CFAA00471973 /* Tabman.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6C759751E83CFA300471973 /* Tabman.framework */; }; + D6C759791E83CFAA00471973 /* Tabman.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6C759751E83CFA300471973 /* Tabman.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -66,7 +69,9 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D6C759791E83CFAA00471973 /* ReferenceProxy in Embed Frameworks */, + 7BF6B4971E9555DE00BE68B5 /* Pageboy.framework in Embed Frameworks */, + 7BF6B4991E9555DE00BE68B5 /* PureLayout.framework in Embed Frameworks */, + D6C759791E83CFAA00471973 /* Tabman.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -74,9 +79,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 04C1035495891866C87981E4 /* Pods-Tabman-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman-Example.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman-Example/Pods-Tabman-Example.debug.xcconfig"; sourceTree = ""; }; - 2BC0D2B4D8925B627AF01AC3 /* Pods_Tabman_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tabman_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C6F75EB382CF7502B260DF8C /* Pods-Tabman-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman-Example.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman-Example/Pods-Tabman-Example.release.xcconfig"; sourceTree = ""; }; + 7BF6B4941E9555DE00BE68B5 /* Pageboy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pageboy.framework; path = ../Carthage/Build/iOS/Pageboy.framework; sourceTree = ""; }; + 7BF6B4951E9555DE00BE68B5 /* PureLayout.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PureLayout.framework; path = ../Carthage/Build/iOS/PureLayout.framework; sourceTree = ""; }; D601367C1E6990650013CD42 /* CustomTabmanBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTabmanBar.swift; sourceTree = ""; }; D616D06D1E72E2C600C7AA32 /* PresetAppearanceConfigs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresetAppearanceConfigs.swift; sourceTree = ""; }; D61E50BB1E64452D00AC8C75 /* CircularButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircularButton.swift; sourceTree = ""; }; @@ -102,10 +106,6 @@ D62AC1061E5736A10020B8AE /* TabViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabViewController.swift; sourceTree = ""; }; D62AC1071E5736A10020B8AE /* TabViewControllerExtras.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabViewControllerExtras.swift; sourceTree = ""; }; D62AC1081E5736A10020B8AE /* TransparentNavigationBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransparentNavigationBar.swift; sourceTree = ""; }; - D6C759661E83CE6300471973 /* Tabman.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Tabman.framework; path = "../../../Library/Developer/Xcode/DerivedData/Tabman-gyemaxzrdxauqidxdarxsnxrvixe/Build/Products/Debug-iphonesimulator/Tabman.framework"; sourceTree = ""; }; - D6C759681E83CE6900471973 /* Pods_Tabman.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pods_Tabman.framework; path = "../../../Library/Developer/Xcode/DerivedData/Tabman-gyemaxzrdxauqidxdarxsnxrvixe/Build/Products/Debug-iphonesimulator/Pods_Tabman.framework"; sourceTree = ""; }; - D6C7596A1E83CE6F00471973 /* Pageboy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pageboy.framework; path = "../../../Library/Developer/Xcode/DerivedData/Tabman-gyemaxzrdxauqidxdarxsnxrvixe/Build/Products/Debug-iphonesimulator/Pageboy/Pageboy.framework"; sourceTree = ""; }; - D6C7596C1E83CE7200471973 /* PureLayout.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PureLayout.framework; path = "../../../Library/Developer/Xcode/DerivedData/Tabman-gyemaxzrdxauqidxdarxsnxrvixe/Build/Products/Debug-iphonesimulator/PureLayout/PureLayout.framework"; sourceTree = ""; }; D6C7596F1E83CFA300471973 /* Tabman.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Tabman.xcodeproj; path = ../Sources/Tabman.xcodeproj; sourceTree = ""; }; /* End PBXFileReference section */ @@ -114,23 +114,15 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 648A830D19F167B986EF7641 /* Pods_Tabman_Example.framework in Frameworks */, - D6C759781E83CFAA00471973 /* ReferenceProxy in Frameworks */, + 7BF6B4961E9555DE00BE68B5 /* Pageboy.framework in Frameworks */, + 7BF6B4981E9555DE00BE68B5 /* PureLayout.framework in Frameworks */, + D6C759781E83CFAA00471973 /* Tabman.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 37F43338690A5F84947F6576 /* Pods */ = { - isa = PBXGroup; - children = ( - 04C1035495891866C87981E4 /* Pods-Tabman-Example.debug.xcconfig */, - C6F75EB382CF7502B260DF8C /* Pods-Tabman-Example.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; D61E50CF1E647F0000AC8C75 /* Settings */ = { isa = PBXGroup; children = ( @@ -172,7 +164,6 @@ D62AC0D71E5733A80020B8AE /* Tabman-Example */, D62AC0D61E5733A80020B8AE /* Products */, D6C759651E83CE6300471973 /* Frameworks */, - 37F43338690A5F84947F6576 /* Pods */, ); sourceTree = ""; }; @@ -224,11 +215,8 @@ D6C759651E83CE6300471973 /* Frameworks */ = { isa = PBXGroup; children = ( - D6C7596C1E83CE7200471973 /* PureLayout.framework */, - D6C7596A1E83CE6F00471973 /* Pageboy.framework */, - D6C759681E83CE6900471973 /* Pods_Tabman.framework */, - D6C759661E83CE6300471973 /* Tabman.framework */, - 2BC0D2B4D8925B627AF01AC3 /* Pods_Tabman_Example.framework */, + 7BF6B4941E9555DE00BE68B5 /* Pageboy.framework */, + 7BF6B4951E9555DE00BE68B5 /* PureLayout.framework */, ); name = Frameworks; sourceTree = ""; @@ -249,12 +237,9 @@ isa = PBXNativeTarget; buildConfigurationList = D62AC0E71E5733A80020B8AE /* Build configuration list for PBXNativeTarget "Tabman-Example" */; buildPhases = ( - 2163E8E0024F38991EF8DBF7 /* [CP] Check Pods Manifest.lock */, D62AC0D11E5733A80020B8AE /* Sources */, D62AC0D21E5733A80020B8AE /* Frameworks */, D62AC0D31E5733A80020B8AE /* Resources */, - 8887F6CA40C4AD1DA1F27078 /* [CP] Embed Pods Frameworks */, - 9A41DBE87A8CB56E632FD7E2 /* [CP] Copy Pods Resources */, D6C7597C1E83CFAA00471973 /* Embed Frameworks */, ); buildRules = ( @@ -284,7 +269,7 @@ }; }; buildConfigurationList = D62AC0D01E5733A80020B8AE /* Build configuration list for PBXProject "Tabman-Example" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 8.0"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -337,54 +322,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 2163E8E0024F38991EF8DBF7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../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"; - showEnvVarsInLog = 0; - }; - 8887F6CA40C4AD1DA1F27078 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-Tabman-Example/Pods-Tabman-Example-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9A41DBE87A8CB56E632FD7E2 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-Tabman-Example/Pods-Tabman-Example-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ D62AC0D11E5733A80020B8AE /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -536,10 +473,10 @@ }; D62AC0E81E5733A80020B8AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 04C1035495891866C87981E4 /* Pods-Tabman-Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Carthage/Build/iOS\""; INFOPLIST_FILE = "Tabman-Example/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.msapsford.Tabman-Example"; @@ -550,10 +487,10 @@ }; D62AC0E91E5733A80020B8AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C6F75EB382CF7502B260DF8C /* Pods-Tabman-Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEVELOPMENT_TEAM = ""; + FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Carthage/Build/iOS\""; INFOPLIST_FILE = "Tabman-Example/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.msapsford.Tabman-Example"; diff --git a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Contents.json index f3af5e7c..48b2e1f0 100644 --- a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -33,13 +33,13 @@ { "size" : "60x60", "idiom" : "iphone", - "filename" : "icon@2x.png", + "filename" : "Icon@2x.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", - "filename" : "Icon-512.png", + "filename" : "Icon@3x.png", "scale" : "3x" } ], diff --git a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon-512.png b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon-512.png deleted file mode 100644 index 0e06cd3a..00000000 Binary files a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon-512.png and /dev/null differ diff --git a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png new file mode 100644 index 00000000..15cd9818 Binary files /dev/null and b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@2x.png differ diff --git a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@3x.png b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@3x.png new file mode 100644 index 00000000..c5cbea80 Binary files /dev/null and b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/Icon@3x.png differ diff --git a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/icon@2x.png b/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/icon@2x.png deleted file mode 100644 index de21d4d9..00000000 Binary files a/Example/Tabman-Example/Assets.xcassets/AppIcon.appiconset/icon@2x.png and /dev/null differ diff --git a/Example/Tabman-Example/Base.lproj/LaunchScreen.storyboard b/Example/Tabman-Example/Base.lproj/LaunchScreen.storyboard index 360e7bab..5111150d 100644 --- a/Example/Tabman-Example/Base.lproj/LaunchScreen.storyboard +++ b/Example/Tabman-Example/Base.lproj/LaunchScreen.storyboard @@ -1,10 +1,10 @@ - + - + @@ -23,12 +23,12 @@ - + diff --git a/Example/Tabman-Example/Base.lproj/Main.storyboard b/Example/Tabman-Example/Base.lproj/Main.storyboard index 87699d16..10c9e329 100644 --- a/Example/Tabman-Example/Base.lproj/Main.storyboard +++ b/Example/Tabman-Example/Base.lproj/Main.storyboard @@ -1,10 +1,10 @@ - + - + @@ -61,7 +61,7 @@ - + @@ -120,7 +120,7 @@ - + diff --git a/Example/Tabman-Example/PresetAppearanceConfigs.swift b/Example/Tabman-Example/PresetAppearanceConfigs.swift index 9c0a36ad..0244edd5 100644 --- a/Example/Tabman-Example/PresetAppearanceConfigs.swift +++ b/Example/Tabman-Example/PresetAppearanceConfigs.swift @@ -46,7 +46,7 @@ class PresetAppearanceConfigs: Any { case .blockTabBar: appearance.state.color = UIColor.white.withAlphaComponent(0.6) - appearance.state.selectedColor = UIColor(red:0.92, green:0.20, blue:0.29, alpha:1.0) + appearance.state.selectedColor = UIColor(red:0.00, green:0.45, blue:1.00, alpha:1.0) appearance.style.background = .solid(color: UIColor.white.withAlphaComponent(0.3)) appearance.indicator.color = UIColor.white.withAlphaComponent(0.8) appearance.layout.edgeInset = 0.0 diff --git a/Example/Tabman-Example/TabViewController.swift b/Example/Tabman-Example/TabViewController.swift index 61890153..166c62c7 100644 --- a/Example/Tabman-Example/TabViewController.swift +++ b/Example/Tabman-Example/TabViewController.swift @@ -27,9 +27,9 @@ class TabViewController: TabmanViewController, PageboyViewControllerDataSource { let numberOfPages = 5 let gradients: [GradientConfig] = [ - GradientConfig(topColor: UIColor(red:0.89, green:0.30, blue:0.15, alpha:1.0), bottomColor: UIColor(red:0.95, green:0.40, blue:0.16, alpha:1.0)), - GradientConfig(topColor: UIColor(red:0.01, green:0.11, blue:0.47, alpha:1.0), bottomColor: UIColor(red:0.02, green:0.46, blue:0.90, alpha:1.0)), + GradientConfig(topColor: UIColor(red:0.00, green:0.45, blue:1.00, alpha:1.0), bottomColor: UIColor(red:0.00, green:0.78, blue:1.00, alpha:1.0)), GradientConfig(topColor: UIColor(red:0.97, green:0.21, blue:0.00, alpha:1.0), bottomColor: UIColor(red:1.00, green:0.55, blue:0.00, alpha:1.0)), + GradientConfig(topColor: UIColor(red:0.01, green:0.11, blue:0.47, alpha:1.0), bottomColor: UIColor(red:0.02, green:0.46, blue:0.90, alpha:1.0)), GradientConfig(topColor: UIColor(red:0.20, green:0.20, blue:0.60, alpha:1.0), bottomColor: UIColor(red:1.00, green:0.00, blue:0.80, alpha:1.0)), GradientConfig(topColor: UIColor(red:0.06, green:0.20, blue:0.26, alpha:1.0), bottomColor: UIColor(red:0.20, green:0.91, blue:0.62, alpha:1.0)) ] diff --git a/Podfile b/Podfile deleted file mode 100644 index 983e4737..00000000 --- a/Podfile +++ /dev/null @@ -1,25 +0,0 @@ -platform :ios, '9.0' - -workspace 'Tabman' - -use_frameworks! - -def shared_pods - pod 'Pageboy', '1.0.4' - pod 'PureLayout', '~> 3.0.0' -end - -target 'Tabman' do - project './Sources/Tabman.xcodeproj' - workspace 'Tabman' - target 'TabmanTests' - - shared_pods -end - -target 'Tabman-Example' do - project './Example/Tabman-Example.xcodeproj' - workspace 'Tabman' - - shared_pods -end diff --git a/Podfile.lock b/Podfile.lock deleted file mode 100644 index c3d4f0c3..00000000 --- a/Podfile.lock +++ /dev/null @@ -1,15 +0,0 @@ -PODS: - - Pageboy (1.0.4) - - PureLayout (3.0.2) - -DEPENDENCIES: - - Pageboy (~> 1.0.0) - - PureLayout (~> 3.0.0) - -SPEC CHECKSUMS: - Pageboy: f9d9be7cc7ba2492c6bbea1f29493022bd400602 - PureLayout: 4d550abe49a94f24c2808b9b95db9131685fe4cd - -PODFILE CHECKSUM: fd0820ca8c653c9e1ceb3900d55462536ff3ac55 - -COCOAPODS: 1.2.0 diff --git a/README.md b/README.md index 9cc7f8d4..b4385120 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Build Status](https://travis-ci.org/uias/Pageboy.svg?branch=master)](https://travis-ci.org/uias/Tabman) [![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat)](https://developer.apple.com/swift/) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![CocoaPods](https://img.shields.io/cocoapods/v/Tabman.svg)]() [![codecov](https://codecov.io/gh/uias/Tabman/branch/master/graph/badge.svg)](https://codecov.io/gh/uias/Tabman) [![GitHub release](https://img.shields.io/github/release/uias/Tabman.svg)](https://github.com/uias/Tabman/releases) @@ -31,13 +32,33 @@ pod 'Tabman' And run `pod install`. +### Carthage +Tabman is available through [Carthage](https://github.com/Carthage/Carthage). Simply install carthage with [Homebrew](http://brew.sh/) using the following command: + +```bash +$ brew update +$ brew install carthage +``` + +Add Tabman to your `Cartfile`: + +```ogdl +github "uias/Tabman" +``` + **Dependencies** - [Pageboy](https://www.github.com/msaps/Pageboy) by Merrick Sapsford - [PureLayout](https://www.github.com/PureLayout/PureLayout) by PureLayout ### Example -A nice pretty example project is available to take a look at some of the features that `Tabman` offers. To run the example, simply clone the repo, run `pod install` and build the workspace. +A nice pretty example project is available to take a look at some of the features that `Tabman` offers. To run the example, simply clone the repo, run + +```ogdl +carthage bootstrap --platform ios +``` + +and build the workspace. ## Requirements Tabman requires iOS 9.0 or above. @@ -81,7 +102,7 @@ func defaultPageIndex(forPageboyViewController pageboyViewController: PageboyVie 3) All done! 🍻 ### Doing a bit more -As `Tabman` is based on [Pageboy](github.com/msaps/Pageboy), everything behaves the same and all the same properties/functions are available. Such as these functions for navigation & reloading: +As Tabman is based on [Pageboy](github.com/uias/Pageboy), everything behaves the same and all the same properties/functions are available. Such as these functions for navigation & reloading: ```swift // Scroll the page view controller to a new page. @@ -93,7 +114,16 @@ public func scrollToPage(_ pageIndex: PageIndex, public func reloadPages() ``` -Read up on the `Pageboy` docs to find out a bit more [here](https://www.github.com/msaps/Pageboy/blob/master/README.md). +Read up on the `Pageboy` docs to find out a bit more [here](https://www.github.com/uias/Pageboy/blob/master/README.md). + +## Child Content Insetting +Tabman will automatically inset any `UITableView` or `UICollectionView`'s that are in the child view controllers provided to the `PageboyViewControllerDataSource`. This behaviour can easily be disabled: + +```swift +tabmanViewController.automaticallyAdjustsChildScrollViewInsets = false +``` + +A `requiredContentInset` property is also available on `TabmanBarConfig` which provides the `UIEdgeInsets` required by the currently visible `TabmanBar`. Note, this does not does not include any insets for UIKit components such as a `UINavigationBar`. ## Customisation The `TabmanBar` in Tabman can be completely customised to your liking, by simply modifying the available properties in the `.bar` `TabmanBarConfig` object. @@ -106,7 +136,7 @@ The style of bar to display, by default this is set to `.scrollingButtonBar`. Pageboy

-For examples on implementing real-world bar styles with `Tabman`, check out [Tabman-Styles](https://github.com/YorkUI/Tabman-Styles). +For examples on implementing real-world bar styles with `Tabman`, check out [Tabman-Styles](https://github.com/uias/Tabman-Styles). #### Location Where you want the bar to appear, either at the top or bottom of the screen. By default this is set to `.preferred` which will use the predefined preferred location for the active style. @@ -202,7 +232,7 @@ For more advanced customisation, including defining your own indicator and bar s Please feel free to contact me on [Twitter](https://twitter.com/MerrickSapsford). ## Contributing -Bug reports and pull requests are welcome on GitHub at [https://github.com/MerrickSapsford/Tabman](https://github.com/MerrickSapsford/Tabman). +Bug reports and pull requests are welcome on GitHub at [https://github.com/MerrickSapsford/Tabman](https://github.com/uias/Tabman). ## License diff --git a/Sources/Tabman.xcodeproj/project.pbxproj b/Sources/Tabman.xcodeproj/project.pbxproj index a4bcb242..e7054905 100644 --- a/Sources/Tabman.xcodeproj/project.pbxproj +++ b/Sources/Tabman.xcodeproj/project.pbxproj @@ -3,11 +3,10 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ - 3F3FBEC45A4025CB2DAD180A /* Pods_Tabman.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C04FBA551919D78789054DA7 /* Pods_Tabman.framework */; }; 463F17C01E81D6B100E5A993 /* TabmanSeparator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 463F17BF1E81D6B100E5A993 /* TabmanSeparator.swift */; }; D60136791E69893A0013CD42 /* TabmanIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60136781E69893A0013CD42 /* TabmanIndicator.swift */; }; D601367B1E6989B50013CD42 /* TabmanBarConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = D601367A1E6989B50013CD42 /* TabmanBarConfig.swift */; }; @@ -27,7 +26,7 @@ D616D0AE1E77FA9300C7AA32 /* TabmanStaticBarIndicatorTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0AB1E77FA9300C7AA32 /* TabmanStaticBarIndicatorTransition.swift */; }; D616D0B11E77FCDA00C7AA32 /* TabmanItemTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B01E77FCDA00C7AA32 /* TabmanItemTransition.swift */; }; D616D0B31E77FD5000C7AA32 /* TabmanTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B21E77FD5000C7AA32 /* TabmanTransition.swift */; }; - D616D0B51E77FF6D00C7AA32 /* TabmanItemColorTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B41E77FF6D00C7AA32 /* TabmanItemColorTransition.swift */; }; + D616D0B51E77FF6D00C7AA32 /* TabmanItemColorCrossfadeTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B41E77FF6D00C7AA32 /* TabmanItemColorCrossfadeTransition.swift */; }; D616D0B71E77FF7600C7AA32 /* TabmanItemMaskTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B61E77FF7600C7AA32 /* TabmanItemMaskTransition.swift */; }; D616D0B91E78065500C7AA32 /* PositionalUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0B81E78065500C7AA32 /* PositionalUtils.swift */; }; D616D0BD1E783E6400C7AA32 /* ImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D616D0BC1E783E6400C7AA32 /* ImageUtils.swift */; }; @@ -41,23 +40,27 @@ D62AC1231E5748D80020B8AE /* TabmanAutoLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1221E5748D80020B8AE /* TabmanAutoLayout.swift */; }; D62AC1A91E5C54570020B8AE /* TabmanViewUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1A81E5C54570020B8AE /* TabmanViewUtils.swift */; }; D62AC1AB1E5C55290020B8AE /* TabmanScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62AC1AA1E5C55290020B8AE /* TabmanScrollView.swift */; }; + D65F101D1EAEA2730090980C /* Pageboy.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D65F101C1EAEA2730090980C /* Pageboy.framework */; }; + D66F583C1EC0F66000418B40 /* TabmanButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66F583A1EC0F66000418B40 /* TabmanButtonBar.swift */; }; + D66F583D1EC0F66000418B40 /* TabmanStaticButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66F583B1EC0F66000418B40 /* TabmanStaticButtonBar.swift */; }; D66FEEBC1E79662C00E7E87A /* TabmanBar+Indicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEBB1E79662C00E7E87A /* TabmanBar+Indicator.swift */; }; D66FEEBE1E79670700E7E87A /* TabmanBar+Protocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEBD1E79670700E7E87A /* TabmanBar+Protocols.swift */; }; D66FEEC01E79688000E7E87A /* TabmanBar+Construction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEBF1E79688000E7E87A /* TabmanBar+Construction.swift */; }; - D66FEEC31E7971AF00E7E87A /* TabmanButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEC21E7971AF00E7E87A /* TabmanButtonBar.swift */; }; D66FEEDC1E7AA51000E7E87A /* ViewUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEDB1E7AA51000E7E87A /* ViewUtils.swift */; }; D66FEEF61E7BFF8E00E7E87A /* TabmanChevronIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEF51E7BFF8E00E7E87A /* TabmanChevronIndicator.swift */; }; D66FEEF81E7C024E00E7E87A /* TabmanChevronView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66FEEF71E7C024E00E7E87A /* TabmanChevronView.swift */; }; - D670521B1E8565F4003348BD /* TabmanStaticButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D670521A1E8565F4003348BD /* TabmanStaticButtonBar.swift */; }; D670521D1E856664003348BD /* TabmanFixedButtonBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D670521C1E856664003348BD /* TabmanFixedButtonBar.swift */; }; + D6822CDE1EAD2A9500E246AD /* TabmanViewController+Insetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6822CDD1EAD2A9500E246AD /* TabmanViewController+Insetting.swift */; }; + D68767021EAEA263003C8D11 /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D68767011EAEA263003C8D11 /* PureLayout.framework */; }; D68FBA761E700E2400B96EC0 /* TabmanIndicatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FBA751E700E2400B96EC0 /* TabmanIndicatorTests.swift */; }; D68FBA781E700F1300B96EC0 /* TabmanTestIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FBA771E700F1300B96EC0 /* TabmanTestIndicator.swift */; }; D68FBA7A1E70159400B96EC0 /* TabmanViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FBA791E70159400B96EC0 /* TabmanViewControllerTests.swift */; }; D68FBA7C1E7015ED00B96EC0 /* TabmanTestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FBA7B1E7015ED00B96EC0 /* TabmanTestViewController.swift */; }; D68FBA811E701D1A00B96EC0 /* TabmanCircularView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D68FBA801E701D1A00B96EC0 /* TabmanCircularView.swift */; }; + D696BFAC1E92531900771F22 /* TabmanViewController+Embedding.swift in Sources */ = {isa = PBXBuildFile; fileRef = D696BFAB1E92531900771F22 /* TabmanViewController+Embedding.swift */; }; D697AB421E7C166800586DCF /* TabmanClearIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D697AB411E7C166800586DCF /* TabmanClearIndicator.swift */; }; D6E5C1AF1E705CF1003FF39D /* TabmanBarConfigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E5C1AE1E705CF1003FF39D /* TabmanBarConfigTests.swift */; }; - E7008672C1E4B88CB32CD0D0 /* Pods_Tabman_TabmanTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1B7C5594C27BD4D2C470997 /* Pods_Tabman_TabmanTests.framework */; }; + D6F7FF4C1EC39E050077219B /* TabmanBar+Insets.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F7FF4B1EC39E050077219B /* TabmanBar+Insets.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -72,11 +75,6 @@ /* Begin PBXFileReference section */ 463F17BF1E81D6B100E5A993 /* TabmanSeparator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanSeparator.swift; sourceTree = ""; }; - 542F14F62547D80F90AA805C /* Pods-Tabman-TabmanTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman-TabmanTests.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman-TabmanTests/Pods-Tabman-TabmanTests.release.xcconfig"; sourceTree = ""; }; - 5D5DE4D5EEEAB85B547E7FC0 /* Pods-Tabman.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman/Pods-Tabman.release.xcconfig"; sourceTree = ""; }; - C04FBA551919D78789054DA7 /* Pods_Tabman.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tabman.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D00CF0DC231AE0A411D98DFE /* Pods-Tabman.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman/Pods-Tabman.debug.xcconfig"; sourceTree = ""; }; - D3B4C0BEC03CD97F13346EC3 /* Pods-Tabman-TabmanTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tabman-TabmanTests.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tabman-TabmanTests/Pods-Tabman-TabmanTests.debug.xcconfig"; sourceTree = ""; }; D60136781E69893A0013CD42 /* TabmanIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanIndicator.swift; sourceTree = ""; }; D601367A1E6989B50013CD42 /* TabmanBarConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanBarConfig.swift; sourceTree = ""; }; D60136891E6992BB0013CD42 /* TabmanBarBackgroundView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanBarBackgroundView.swift; sourceTree = ""; }; @@ -95,7 +93,7 @@ D616D0AB1E77FA9300C7AA32 /* TabmanStaticBarIndicatorTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanStaticBarIndicatorTransition.swift; sourceTree = ""; }; D616D0B01E77FCDA00C7AA32 /* TabmanItemTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanItemTransition.swift; sourceTree = ""; }; D616D0B21E77FD5000C7AA32 /* TabmanTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanTransition.swift; sourceTree = ""; }; - D616D0B41E77FF6D00C7AA32 /* TabmanItemColorTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanItemColorTransition.swift; sourceTree = ""; }; + D616D0B41E77FF6D00C7AA32 /* TabmanItemColorCrossfadeTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanItemColorCrossfadeTransition.swift; sourceTree = ""; }; D616D0B61E77FF7600C7AA32 /* TabmanItemMaskTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanItemMaskTransition.swift; sourceTree = ""; }; D616D0B81E78065500C7AA32 /* PositionalUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PositionalUtils.swift; sourceTree = ""; }; D616D0BC1E783E6400C7AA32 /* ImageUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageUtils.swift; sourceTree = ""; }; @@ -110,27 +108,29 @@ D62AC11B1E573AA00020B8AE /* TabmanBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanBar.swift; sourceTree = ""; }; D62AC11F1E573FD20020B8AE /* TabmanBarItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanBarItem.swift; sourceTree = ""; }; D62AC1221E5748D80020B8AE /* TabmanAutoLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanAutoLayout.swift; sourceTree = ""; }; - D62AC1541E5AF5500020B8AE /* Pageboy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pageboy.framework; path = "../Example/Dependencies/Pageboy/Sources/build/Debug-iphoneos/Pageboy.framework"; sourceTree = ""; }; - D62AC19E1E5B03BB0020B8AE /* PureLayout.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PureLayout.framework; path = "../Example/Dependencies/PureLayout/PureLayout/build/Debug-iphoneos/PureLayout.framework"; sourceTree = ""; }; D62AC1A81E5C54570020B8AE /* TabmanViewUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanViewUtils.swift; sourceTree = ""; }; D62AC1AA1E5C55290020B8AE /* TabmanScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanScrollView.swift; sourceTree = ""; }; + D65F101C1EAEA2730090980C /* Pageboy.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Pageboy.framework; path = ../Carthage/Build/iOS/Pageboy.framework; sourceTree = ""; }; + D66F583A1EC0F66000418B40 /* TabmanButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanButtonBar.swift; sourceTree = ""; }; + D66F583B1EC0F66000418B40 /* TabmanStaticButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanStaticButtonBar.swift; sourceTree = ""; }; D66FEEBB1E79662C00E7E87A /* TabmanBar+Indicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanBar+Indicator.swift"; sourceTree = ""; }; D66FEEBD1E79670700E7E87A /* TabmanBar+Protocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanBar+Protocols.swift"; sourceTree = ""; }; D66FEEBF1E79688000E7E87A /* TabmanBar+Construction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanBar+Construction.swift"; sourceTree = ""; }; - D66FEEC21E7971AF00E7E87A /* TabmanButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanButtonBar.swift; sourceTree = ""; }; D66FEEDB1E7AA51000E7E87A /* ViewUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewUtils.swift; sourceTree = ""; }; D66FEEF51E7BFF8E00E7E87A /* TabmanChevronIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanChevronIndicator.swift; sourceTree = ""; }; D66FEEF71E7C024E00E7E87A /* TabmanChevronView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanChevronView.swift; sourceTree = ""; }; - D670521A1E8565F4003348BD /* TabmanStaticButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanStaticButtonBar.swift; sourceTree = ""; }; D670521C1E856664003348BD /* TabmanFixedButtonBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanFixedButtonBar.swift; sourceTree = ""; }; + D6822CDD1EAD2A9500E246AD /* TabmanViewController+Insetting.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanViewController+Insetting.swift"; sourceTree = ""; }; + D68767011EAEA263003C8D11 /* PureLayout.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PureLayout.framework; path = ../Carthage/Build/iOS/PureLayout.framework; sourceTree = ""; }; D68FBA751E700E2400B96EC0 /* TabmanIndicatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanIndicatorTests.swift; sourceTree = ""; }; D68FBA771E700F1300B96EC0 /* TabmanTestIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanTestIndicator.swift; sourceTree = ""; }; D68FBA791E70159400B96EC0 /* TabmanViewControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanViewControllerTests.swift; sourceTree = ""; }; D68FBA7B1E7015ED00B96EC0 /* TabmanTestViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanTestViewController.swift; sourceTree = ""; }; D68FBA801E701D1A00B96EC0 /* TabmanCircularView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanCircularView.swift; sourceTree = ""; }; + D696BFAB1E92531900771F22 /* TabmanViewController+Embedding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanViewController+Embedding.swift"; sourceTree = ""; }; D697AB411E7C166800586DCF /* TabmanClearIndicator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanClearIndicator.swift; sourceTree = ""; }; D6E5C1AE1E705CF1003FF39D /* TabmanBarConfigTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabmanBarConfigTests.swift; sourceTree = ""; }; - E1B7C5594C27BD4D2C470997 /* Pods_Tabman_TabmanTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tabman_TabmanTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D6F7FF4B1EC39E050077219B /* TabmanBar+Insets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TabmanBar+Insets.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -138,7 +138,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3F3FBEC45A4025CB2DAD180A /* Pods_Tabman.framework in Frameworks */, + D68767021EAEA263003C8D11 /* PureLayout.framework in Frameworks */, + D65F101D1EAEA2730090980C /* Pageboy.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -147,7 +148,6 @@ buildActionMask = 2147483647; files = ( D62AC0BC1E5733810020B8AE /* Tabman.framework in Frameworks */, - E7008672C1E4B88CB32CD0D0 /* Pods_Tabman_TabmanTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -162,17 +162,6 @@ path = Separator; sourceTree = ""; }; - D314E9EB7361350B8EA4E0F8 /* Pods */ = { - isa = PBXGroup; - children = ( - D00CF0DC231AE0A411D98DFE /* Pods-Tabman.debug.xcconfig */, - 5D5DE4D5EEEAB85B547E7FC0 /* Pods-Tabman.release.xcconfig */, - D3B4C0BEC03CD97F13346EC3 /* Pods-Tabman-TabmanTests.debug.xcconfig */, - 542F14F62547D80F90AA805C /* Pods-Tabman-TabmanTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; D60136751E69892F0013CD42 /* Indicator */ = { isa = PBXGroup; children = ( @@ -194,7 +183,7 @@ D6020AA51E5DE4A800C2B7BA /* Styles */ = { isa = PBXGroup; children = ( - D66FEEC11E7971AF00E7E87A /* Concrete */, + D66F58391EC0F66000418B40 /* Abstract */, D6020AA81E5DE4D600C2B7BA /* TabmanLineBar.swift */, D6020AA61E5DE4A800C2B7BA /* TabmanScrollingButtonBar.swift */, D670521C1E856664003348BD /* TabmanFixedButtonBar.swift */, @@ -240,7 +229,7 @@ isa = PBXGroup; children = ( D616D0B01E77FCDA00C7AA32 /* TabmanItemTransition.swift */, - D616D0B41E77FF6D00C7AA32 /* TabmanItemColorTransition.swift */, + D616D0B41E77FF6D00C7AA32 /* TabmanItemColorCrossfadeTransition.swift */, D616D0B61E77FF7600C7AA32 /* TabmanItemMaskTransition.swift */, ); path = ItemTransition; @@ -263,7 +252,6 @@ D62AC0BF1E5733810020B8AE /* TabmanTests */, D62AC0B31E5733810020B8AE /* Products */, D62AC1531E5AF5500020B8AE /* Frameworks */, - D314E9EB7361350B8EA4E0F8 /* Pods */, ); sourceTree = ""; }; @@ -281,6 +269,8 @@ children = ( D62AC0B51E5733810020B8AE /* Tabman.h */, D62AC0F41E5733FE0020B8AE /* TabmanViewController.swift */, + D696BFAB1E92531900771F22 /* TabmanViewController+Embedding.swift */, + D6822CDD1EAD2A9500E246AD /* TabmanViewController+Insetting.swift */, D601367A1E6989B50013CD42 /* TabmanBarConfig.swift */, D62AC11A1E573AA00020B8AE /* TabmanBar */, D62AC1211E5748C80020B8AE /* Utilities */, @@ -307,11 +297,12 @@ isa = PBXGroup; children = ( D62AC11B1E573AA00020B8AE /* TabmanBar.swift */, + D62AC11F1E573FD20020B8AE /* TabmanBarItem.swift */, D66FEEBF1E79688000E7E87A /* TabmanBar+Construction.swift */, D66FEEBB1E79662C00E7E87A /* TabmanBar+Indicator.swift */, D66FEEBD1E79670700E7E87A /* TabmanBar+Protocols.swift */, - D62AC11F1E573FD20020B8AE /* TabmanBarItem.swift */, D6020A931E5DB57400C2B7BA /* TabmanBar+Appearance.swift */, + D6F7FF4B1EC39E050077219B /* TabmanBar+Insets.swift */, D6020AA51E5DE4A800C2B7BA /* Styles */, D616D09F1E77EFC600C7AA32 /* Transitioning */, D62AC1AE1E5C84CB0020B8AE /* Components */, @@ -334,10 +325,8 @@ D62AC1531E5AF5500020B8AE /* Frameworks */ = { isa = PBXGroup; children = ( - D62AC19E1E5B03BB0020B8AE /* PureLayout.framework */, - D62AC1541E5AF5500020B8AE /* Pageboy.framework */, - C04FBA551919D78789054DA7 /* Pods_Tabman.framework */, - E1B7C5594C27BD4D2C470997 /* Pods_Tabman_TabmanTests.framework */, + D65F101C1EAEA2730090980C /* Pageboy.framework */, + D68767011EAEA263003C8D11 /* PureLayout.framework */, ); name = Frameworks; sourceTree = ""; @@ -362,13 +351,13 @@ path = Utilities; sourceTree = ""; }; - D66FEEC11E7971AF00E7E87A /* Concrete */ = { + D66F58391EC0F66000418B40 /* Abstract */ = { isa = PBXGroup; children = ( - D66FEEC21E7971AF00E7E87A /* TabmanButtonBar.swift */, - D670521A1E8565F4003348BD /* TabmanStaticButtonBar.swift */, + D66F583A1EC0F66000418B40 /* TabmanButtonBar.swift */, + D66F583B1EC0F66000418B40 /* TabmanStaticButtonBar.swift */, ); - path = Concrete; + path = Abstract; sourceTree = ""; }; D68FBA7F1E701D1100B96EC0 /* Views */ = { @@ -398,13 +387,11 @@ isa = PBXNativeTarget; buildConfigurationList = D62AC0C61E5733810020B8AE /* Build configuration list for PBXNativeTarget "Tabman" */; buildPhases = ( - CD99F4CA7550180E33FC9BA7 /* [CP] Check Pods Manifest.lock */, D62AC0AD1E5733810020B8AE /* Sources */, D62AC0AE1E5733810020B8AE /* Frameworks */, D62AC0AF1E5733810020B8AE /* Headers */, D62AC0B01E5733810020B8AE /* Resources */, D6607C9E1E8023DE00FEB9F4 /* Increment Build Number */, - 9505793F243C6BE84DF28493 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -419,12 +406,10 @@ isa = PBXNativeTarget; buildConfigurationList = D62AC0C91E5733810020B8AE /* Build configuration list for PBXNativeTarget "TabmanTests" */; buildPhases = ( - 22DFAD8335B2EADD6315DA6E /* [CP] Check Pods Manifest.lock */, D62AC0B71E5733810020B8AE /* Sources */, D62AC0B81E5733810020B8AE /* Frameworks */, D62AC0B91E5733810020B8AE /* Resources */, - E2444D3293FC6304D7578FCF /* [CP] Embed Pods Frameworks */, - 47937725A9CDB8AFCC27F286 /* [CP] Copy Pods Resources */, + D68766FB1EAE9685003C8D11 /* Copy Carthage Frameworks */, ); buildRules = ( ); @@ -458,7 +443,7 @@ }; }; buildConfigurationList = D62AC0AC1E5733810020B8AE /* Build configuration list for PBXProject "Tabman" */; - compatibilityVersion = "Xcode 3.2"; + compatibilityVersion = "Xcode 8.0"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( @@ -493,66 +478,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 22DFAD8335B2EADD6315DA6E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../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"; - showEnvVarsInLog = 0; - }; - 47937725A9CDB8AFCC27F286 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-Tabman-TabmanTests/Pods-Tabman-TabmanTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 9505793F243C6BE84DF28493 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-Tabman/Pods-Tabman-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - CD99F4CA7550180E33FC9BA7 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../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"; - showEnvVarsInLog = 0; - }; D6607C9E1E8023DE00FEB9F4 /* Increment Build Number */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -567,20 +492,21 @@ shellPath = /bin/sh; shellScript = "git=`sh /etc/profile; which git`\nappBuild=`\"$git\" rev-list HEAD --count`\n\n/usr/libexec/PlistBuddy -c \"Set :CFBundleVersion $appBuild\" \"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\n\necho \"Incremented the build number ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\""; }; - E2444D3293FC6304D7578FCF /* [CP] Embed Pods Frameworks */ = { + D68766FB1EAE9685003C8D11 /* Copy Carthage Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "$(SRCROOT)/../Carthage/Build/iOS/Pageboy.framework", + "$(SRCROOT)/../Carthage/Build/iOS/PureLayout.framework", ); - name = "[CP] Embed Pods Frameworks"; + name = "Copy Carthage Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/../Pods/Target Support Files/Pods-Tabman-TabmanTests/Pods-Tabman-TabmanTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/usr/local/bin/carthage copy-frameworks\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -592,7 +518,8 @@ D66FEEBE1E79670700E7E87A /* TabmanBar+Protocols.swift in Sources */, D6020A981E5DC59500C2B7BA /* TabmanColorUtils.swift in Sources */, D62AC11C1E573AA00020B8AE /* TabmanBar.swift in Sources */, - D66FEEC31E7971AF00E7E87A /* TabmanButtonBar.swift in Sources */, + D696BFAC1E92531900771F22 /* TabmanViewController+Embedding.swift in Sources */, + D66F583C1EC0F66000418B40 /* TabmanButtonBar.swift in Sources */, D616D0B71E77FF7600C7AA32 /* TabmanItemMaskTransition.swift in Sources */, D6020AA71E5DE4A800C2B7BA /* TabmanScrollingButtonBar.swift in Sources */, D616D0BD1E783E6400C7AA32 /* ImageUtils.swift in Sources */, @@ -600,10 +527,10 @@ D62AC1201E573FD20020B8AE /* TabmanBarItem.swift in Sources */, D6020A941E5DB57400C2B7BA /* TabmanBar+Appearance.swift in Sources */, D6020AA91E5DE4D600C2B7BA /* TabmanLineBar.swift in Sources */, + D66F583D1EC0F66000418B40 /* TabmanStaticButtonBar.swift in Sources */, D616D0AC1E77FA9300C7AA32 /* TabmanIndicatorTransition.swift in Sources */, - D616D0B51E77FF6D00C7AA32 /* TabmanItemColorTransition.swift in Sources */, + D616D0B51E77FF6D00C7AA32 /* TabmanItemColorCrossfadeTransition.swift in Sources */, D601367B1E6989B50013CD42 /* TabmanBarConfig.swift in Sources */, - D670521B1E8565F4003348BD /* TabmanStaticButtonBar.swift in Sources */, D616D0A31E77EFC600C7AA32 /* TabmanBarTransitionStore.swift in Sources */, D62AC1231E5748D80020B8AE /* TabmanAutoLayout.swift in Sources */, D66FEEDC1E7AA51000E7E87A /* ViewUtils.swift in Sources */, @@ -614,6 +541,7 @@ D616D0AD1E77FA9300C7AA32 /* TabmanScrollingBarIndicatorTransition.swift in Sources */, 463F17C01E81D6B100E5A993 /* TabmanSeparator.swift in Sources */, D66FEEC01E79688000E7E87A /* TabmanBar+Construction.swift in Sources */, + D6F7FF4C1EC39E050077219B /* TabmanBar+Insets.swift in Sources */, D601368A1E6992BB0013CD42 /* TabmanBarBackgroundView.swift in Sources */, D697AB421E7C166800586DCF /* TabmanClearIndicator.swift in Sources */, D62AC1AB1E5C55290020B8AE /* TabmanScrollView.swift in Sources */, @@ -628,6 +556,7 @@ D616D0601E719D3B00C7AA32 /* TabmanBlockTabBar.swift in Sources */, D62AC0F51E5733FE0020B8AE /* TabmanViewController.swift in Sources */, D616D06B1E72C1FC00C7AA32 /* TabmanDotIndicator.swift in Sources */, + D6822CDE1EAD2A9500E246AD /* TabmanViewController+Insetting.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -684,6 +613,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Carthage/Build/iOS\""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -737,6 +667,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)/../Carthage/Build/iOS\""; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -758,7 +689,6 @@ }; D62AC0C71E5733810020B8AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D00CF0DC231AE0A411D98DFE /* Pods-Tabman.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; @@ -766,6 +696,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO; INFOPLIST_FILE = Tabman/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -779,7 +710,6 @@ }; D62AC0C81E5733810020B8AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5D5DE4D5EEEAB85B547E7FC0 /* Pods-Tabman.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; @@ -787,6 +717,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO; INFOPLIST_FILE = Tabman/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -799,8 +730,10 @@ }; D62AC0CA1E5733810020B8AE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D3B4C0BEC03CD97F13346EC3 /* Pods-Tabman-TabmanTests.debug.xcconfig */; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO; INFOPLIST_FILE = TabmanTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.msapsford.TabmanTests; @@ -811,8 +744,10 @@ }; D62AC0CB1E5733810020B8AE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 542F14F62547D80F90AA805C /* Pods-Tabman-TabmanTests.release.xcconfig */; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; + EMBED_ASSET_PACKS_IN_PRODUCT_BUNDLE = NO; INFOPLIST_FILE = TabmanTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.msapsford.TabmanTests; diff --git a/Sources/Tabman/Info.plist b/Sources/Tabman/Info.plist index 2a8782ae..04cf3d6a 100644 --- a/Sources/Tabman/Info.plist +++ b/Sources/Tabman/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.4.8 + 0.5.0 CFBundleVersion AUTO_GENERATED NSPrincipalClass diff --git a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanChevronIndicator.swift b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanChevronIndicator.swift index b06f753c..434514f8 100644 --- a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanChevronIndicator.swift +++ b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanChevronIndicator.swift @@ -48,6 +48,6 @@ internal class TabmanChevronIndicator: TabmanIndicator { } override func itemTransitionType() -> TabmanItemTransition.Type? { - return TabmanItemColorTransition.self + return TabmanItemColorCrossfadeTransition.self } } diff --git a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanClearIndicator.swift b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanClearIndicator.swift index ebabfadf..5a603e5a 100644 --- a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanClearIndicator.swift +++ b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanClearIndicator.swift @@ -19,6 +19,6 @@ internal class TabmanClearIndicator: TabmanIndicator { } override func itemTransitionType() -> TabmanItemTransition.Type? { - return TabmanItemColorTransition.self + return TabmanItemColorCrossfadeTransition.self } } diff --git a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanDotIndicator.swift b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanDotIndicator.swift index c59f8bb0..fa44b80b 100644 --- a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanDotIndicator.swift +++ b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanDotIndicator.swift @@ -50,6 +50,6 @@ internal class TabmanDotIndicator: TabmanIndicator { } override func itemTransitionType() -> TabmanItemTransition.Type? { - return TabmanItemColorTransition.self + return TabmanItemColorCrossfadeTransition.self } } diff --git a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanLineIndicator.swift b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanLineIndicator.swift index 9786f424..423c6093 100644 --- a/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanLineIndicator.swift +++ b/Sources/Tabman/TabmanBar/Components/Indicator/Styles/TabmanLineIndicator.swift @@ -81,6 +81,6 @@ internal class TabmanLineIndicator: TabmanIndicator { } override func itemTransitionType() -> TabmanItemTransition.Type? { - return TabmanItemColorTransition.self + return TabmanItemColorCrossfadeTransition.self } } diff --git a/Sources/Tabman/TabmanBar/Styles/Concrete/TabmanButtonBar.swift b/Sources/Tabman/TabmanBar/Styles/Abstract/TabmanButtonBar.swift similarity index 99% rename from Sources/Tabman/TabmanBar/Styles/Concrete/TabmanButtonBar.swift rename to Sources/Tabman/TabmanBar/Styles/Abstract/TabmanButtonBar.swift index 7ea636dc..86279bd7 100644 --- a/Sources/Tabman/TabmanBar/Styles/Concrete/TabmanButtonBar.swift +++ b/Sources/Tabman/TabmanBar/Styles/Abstract/TabmanButtonBar.swift @@ -221,7 +221,7 @@ internal class TabmanButtonBar: TabmanBar { internal func tabButtonPressed(_ sender: UIButton) { if let index = self.buttons.index(of: sender) { - self.delegate?.bar(self, didSelectItemAtIndex: index) + self.delegate?.bar(self, didSelectItemAt: index) } } diff --git a/Sources/Tabman/TabmanBar/Styles/Concrete/TabmanStaticButtonBar.swift b/Sources/Tabman/TabmanBar/Styles/Abstract/TabmanStaticButtonBar.swift similarity index 100% rename from Sources/Tabman/TabmanBar/Styles/Concrete/TabmanStaticButtonBar.swift rename to Sources/Tabman/TabmanBar/Styles/Abstract/TabmanStaticButtonBar.swift diff --git a/Sources/Tabman/TabmanBar/TabmanBar+Insets.swift b/Sources/Tabman/TabmanBar/TabmanBar+Insets.swift new file mode 100644 index 00000000..2e895c9a --- /dev/null +++ b/Sources/Tabman/TabmanBar/TabmanBar+Insets.swift @@ -0,0 +1,66 @@ +// +// TabmanBarInsets.swift +// Pods +// +// Created by Merrick Sapsford on 10/05/2017. +// +// + +import Foundation + +public extension TabmanBar { + + /// Collection of inset values required to inset child content below TabmanBar. + public struct Insets { + + /// Raw TabmanBar UIEdgeInsets + internal let barInsets: UIEdgeInsets + + /// The inset required for the top layout guide (UINavigationBar etc.). + public let topLayoutGuide: CGFloat + /// The inset required for the bottom layout guide (UITabBar etc.). + public let bottomLayoutGuide: CGFloat + /// The inset required for the bar. + public var bar: CGFloat { + return max(barInsets.top, barInsets.bottom) + } + + /// The total insets required to display under the TabmanBar. + /// + /// This takes topLayoutGuide, bottomlayoutGuide and the bar height into account. + /// Set on a UIScrollView's contentInset to manually inset the contents. + public var all: UIEdgeInsets { + let top = topLayoutGuide + barInsets.top + let bottom = bottomLayoutGuide + barInsets.bottom + + if barInsets.top > 0.0 { + return UIEdgeInsetsMake(top, 0.0, 0.0, 0.0) + } else { + return UIEdgeInsetsMake(0.0, 0.0, bottom, 0.0) + } + } + + // MARK: Init + + internal init(topLayoutGuide: CGFloat, + bottomLayoutGuide: CGFloat, + bar: UIEdgeInsets) { + self.topLayoutGuide = topLayoutGuide + self.bottomLayoutGuide = bottomLayoutGuide + self.barInsets = bar + } + + internal init() { + self.init(topLayoutGuide: 0.0, + bottomLayoutGuide: 0.0, + bar: .zero) + } + + internal static var zero: Insets { + return Insets() + } + + } + +} + diff --git a/Sources/Tabman/TabmanBar/TabmanBar+Protocols.swift b/Sources/Tabman/TabmanBar/TabmanBar+Protocols.swift index b3a5635d..94449401 100644 --- a/Sources/Tabman/TabmanBar/TabmanBar+Protocols.swift +++ b/Sources/Tabman/TabmanBar/TabmanBar+Protocols.swift @@ -15,7 +15,7 @@ public protocol TabmanBarDataSource: class { /// /// - Parameter bar: The bar. /// - Returns: Items to display in the tab bar. - func items(forBar bar: TabmanBar) -> [TabmanBarItem]? + func items(for bar: TabmanBar) -> [TabmanBarItem]? } internal protocol TabmanBarDelegate: class { @@ -25,7 +25,7 @@ internal protocol TabmanBarDelegate: class { /// - Parameters: /// - bar: The bar. /// - index: The selected index. - func bar(_ bar: TabmanBar, didSelectItemAtIndex index: Int) + func bar(_ bar: TabmanBar, didSelectItemAt index: Int) } /// Lifecycle functions of TabmanBar diff --git a/Sources/Tabman/TabmanBar/TabmanBar.swift b/Sources/Tabman/TabmanBar/TabmanBar.swift index c9fefd0b..7dd5b813 100644 --- a/Sources/Tabman/TabmanBar/TabmanBar.swift +++ b/Sources/Tabman/TabmanBar/TabmanBar.swift @@ -13,9 +13,7 @@ import Pageboy /// A bar that displays the current page status of a TabmanViewController. open class TabmanBar: UIView, TabmanBarLifecycle { - // // MARK: Types - // /// The style of the bar. /// @@ -41,18 +39,18 @@ open class TabmanBar: UIView, TabmanBarLifecycle { case explicit(value: CGFloat) } - // // MARK: Properties - // - - // Private + /// The items that are displayed in the bar. internal var items: [TabmanBarItem]? { didSet { self.isHidden = (items?.count ?? 0) == 0 } } + + /// The current position of the bar. internal private(set) var currentPosition: CGFloat = 0.0 + /// Store of available transitions for bar item/indicator transitions. internal weak var transitionStore: TabmanBarTransitionStore? /// The object that acts as a delegate to the bar. @@ -98,7 +96,6 @@ open class TabmanBar: UIView, TabmanBarLifecycle { public private(set) var contentView = UIView(forAutoLayout: ()) /// The bottom separator view for the bar. internal private(set) var bottomSeparator = TabmanSeparator() - /// Indicator for the bar. public internal(set) var indicator: TabmanIndicator? { didSet { @@ -106,8 +103,16 @@ open class TabmanBar: UIView, TabmanBarLifecycle { self.clear(indicator: oldValue) } } + /// Mask view used for indicator. + internal var indicatorMaskView: UIView = { + let maskView = UIView() + maskView.backgroundColor = .black + return maskView + }() + internal var indicatorLeftMargin: NSLayoutConstraint? internal var indicatorWidth: NSLayoutConstraint? + internal var indicatorIsProgressive: Bool = TabmanBar.Appearance.defaultAppearance.indicator.isProgressive ?? false { didSet { guard indicatorIsProgressive != oldValue else { return } @@ -119,11 +124,6 @@ open class TabmanBar: UIView, TabmanBarLifecycle { } internal var indicatorBounces: Bool = TabmanBar.Appearance.defaultAppearance.indicator.bounces ?? false internal var indicatorCompresses: Bool = TabmanBar.Appearance.defaultAppearance.indicator.compresses ?? false - internal var indicatorMaskView: UIView = { - let maskView = UIView() - maskView.backgroundColor = .black - return maskView - }() /// Preferred style for the indicator. /// Bar conforms at own discretion via usePreferredIndicatorStyle() @@ -140,9 +140,7 @@ open class TabmanBar: UIView, TabmanBarLifecycle { } } - // // MARK: Init - // required public init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) @@ -167,9 +165,7 @@ open class TabmanBar: UIView, TabmanBarLifecycle { self.indicator = self.create(indicatorForStyle: self.defaultIndicatorStyle()) } - // // MARK: Lifecycle - // open override func layoutSubviews() { super.layoutSubviews() @@ -209,19 +205,15 @@ open class TabmanBar: UIView, TabmanBarLifecycle { return nil } - // // MARK: Data - // /// Reload and reconstruct the contents of the bar. public func reloadData() { - self.items = self.dataSource?.items(forBar: self) + self.items = self.dataSource?.items(for: self) self.clearAndConstructBar() } - // // MARK: Updating - // internal func updatePosition(_ position: CGFloat, direction: PageboyViewController.NavigationDirection, @@ -244,9 +236,7 @@ open class TabmanBar: UIView, TabmanBarLifecycle { bounds: bounds) } - // // MARK: TabmanBarLifecycle - // open func constructTabBar(items: [TabmanBarItem]) { fatalError("constructTabBar() should be implemented in TabmanBar subclasses.") diff --git a/Sources/Tabman/TabmanBar/Transitioning/IndicatorTransition/TabmanIndicatorTransition.swift b/Sources/Tabman/TabmanBar/Transitioning/IndicatorTransition/TabmanIndicatorTransition.swift index cffdeac7..023df535 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/IndicatorTransition/TabmanIndicatorTransition.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/IndicatorTransition/TabmanIndicatorTransition.swift @@ -9,6 +9,8 @@ import UIKit import Pageboy -/// Transition protocol for indicators. +/// A transition that occurs on the indicator within a TabmanBar when the position is updated. +/// +/// This should be used to update the position / state of the indicator etc. internal class TabmanIndicatorTransition: TabmanTransition { } diff --git a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorTransition.swift b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorCrossfadeTransition.swift similarity index 91% rename from Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorTransition.swift rename to Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorCrossfadeTransition.swift index 27c387fc..778b9cb4 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorTransition.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemColorCrossfadeTransition.swift @@ -1,5 +1,5 @@ // -// TabmanItemColorTransition.swift +// TabmanItemColorCrossfadeTransition.swift // Tabman // // Created by Merrick Sapsford on 14/03/2017. @@ -9,7 +9,10 @@ import UIKit import Pageboy -class TabmanItemColorTransition: TabmanItemTransition { +/// TabmanItemColorCrossfadeTransition +/// +/// Transition that cross-fades colors on the selected and unselected items to signify the active item. +class TabmanItemColorCrossfadeTransition: TabmanItemTransition { override func transition(withPosition position: CGFloat, direction: PageboyViewController.NavigationDirection, diff --git a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemMaskTransition.swift b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemMaskTransition.swift index 3ed7bd3f..1cd94fea 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemMaskTransition.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemMaskTransition.swift @@ -9,6 +9,9 @@ import UIKit import Pageboy +/// TabmanItemMaskTransition +/// +/// Transition that adjusts the frame of the TabmanBar indicatorMaskView to be over the active item frame. class TabmanItemMaskTransition: TabmanItemTransition { override func transition(withPosition position: CGFloat, diff --git a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemTransition.swift b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemTransition.swift index 991e5e78..a9696135 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemTransition.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/ItemTransition/TabmanItemTransition.swift @@ -9,5 +9,8 @@ import Foundation import Pageboy +/// A transition that occurs on an item in a TabmanBar when the position is updated. +/// +/// This should be used to update the selected state on the active item etc. class TabmanItemTransition: TabmanTransition { } diff --git a/Sources/Tabman/TabmanBar/Transitioning/TabmanBarTransitionStore.swift b/Sources/Tabman/TabmanBar/Transitioning/TabmanBarTransitionStore.swift index 95856181..bb9fc55e 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/TabmanBarTransitionStore.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/TabmanBarTransitionStore.swift @@ -26,7 +26,7 @@ internal class TabmanBarTransitionStore: Any { // initialize available transitions let scrollingIndicatorTransition = TabmanScrollingBarIndicatorTransition() let staticIndicatorTransition = TabmanStaticBarIndicatorTransition() - let itemColorTransition = TabmanItemColorTransition() + let itemColorTransition = TabmanItemColorCrossfadeTransition() let itemMaskTransition = TabmanItemMaskTransition() // create transitions hashmap diff --git a/Sources/Tabman/TabmanBar/Transitioning/TabmanTransition.swift b/Sources/Tabman/TabmanBar/Transitioning/TabmanTransition.swift index d8513ddf..9cdc754c 100644 --- a/Sources/Tabman/TabmanBar/Transitioning/TabmanTransition.swift +++ b/Sources/Tabman/TabmanBar/Transitioning/TabmanTransition.swift @@ -11,13 +11,22 @@ import Pageboy internal protocol TabmanTransitionLifecycle { + /// The TabmanBar to use for the transition. var tabmanBar: TabmanBar? { get set } + /// Update the transition for a new position. + /// + /// - Parameters: + /// - position: The new position. + /// - direction: The direction of the scroll. + /// - indexRange: The range of valid indexes. + /// - bounds: The bounds for the TabmanBar. func transition(withPosition position: CGFloat, direction: PageboyViewController.NavigationDirection, indexRange: Range, bounds: CGRect) + /// Reload the transition for the current bar position. func updateForCurrentPosition() } diff --git a/Sources/Tabman/TabmanBarConfig.swift b/Sources/Tabman/TabmanBarConfig.swift index ccaa3314..ce20b701 100644 --- a/Sources/Tabman/TabmanBarConfig.swift +++ b/Sources/Tabman/TabmanBarConfig.swift @@ -16,28 +16,28 @@ internal protocol TabmanBarConfigDelegate: class { /// - Parameters: /// - config: The config. /// - style: The new style. - func config(_ config: TabmanBarConfig, didUpdateStyle style: TabmanBar.Style) + func config(_ config: TabmanBarConfig, didUpdate style: TabmanBar.Style) /// The config had its location updated. /// /// - Parameters: /// - config: The config. /// - location: The new location. - func config(_ config: TabmanBarConfig, didUpdateLocation location: TabmanBarConfig.Location) + func config(_ config: TabmanBarConfig, didUpdate location: TabmanBarConfig.Location) /// The config had its items updated. /// /// - Parameters: /// - config: The config. /// - items: The new items. - func config(_ config: TabmanBarConfig, didUpdateItems items: [TabmanBarItem]?) + func config(_ config: TabmanBarConfig, didUpdate items: [TabmanBarItem]?) /// The config had its appearance config updated. /// /// - Parameters: /// - config: The config. /// - appearance: The new appearance config. - func config(_ config: TabmanBarConfig, didUpdateAppearance appearance: TabmanBar.Appearance) + func config(_ config: TabmanBarConfig, didUpdate appearance: TabmanBar.Appearance) } /// Configuration object for adjusting appearance and contents of a TabmanBar. @@ -70,7 +70,7 @@ public class TabmanBarConfig: Any { didSet { guard style.rawType != oldValue.rawType else { return } - self.delegate?.config(self, didUpdateStyle: style) + self.delegate?.config(self, didUpdate: style) } } @@ -80,26 +80,32 @@ public class TabmanBarConfig: Any { guard location != oldValue else { return } - self.delegate?.config(self, didUpdateLocation: location) + self.delegate?.config(self, didUpdate: location) } } /// The items to display in the bar. public var items: [TabmanBarItem]? { didSet { - self.delegate?.config(self, didUpdateItems: items) + self.delegate?.config(self, didUpdate: items) } } /// The appearance configuration of the bar. public var appearance: TabmanBar.Appearance? { didSet { - self.delegate?.config(self, didUpdateAppearance: appearance ?? .defaultAppearance) + self.delegate?.config(self, didUpdate: appearance ?? .defaultAppearance) } } /// The content inset required for content underneath the bar. - public internal(set) var requiredContentInset: UIEdgeInsets = .zero + @available(*, deprecated: 0.5.0, message: "Use requiredInsets") + public var requiredContentInset: UIEdgeInsets { + return requiredInsets.barInsets + } + + /// The required insets for the bar. + public internal(set) var requiredInsets: TabmanBar.Insets = .zero } // MARK: - Additional Style properties for internal use diff --git a/Sources/Tabman/TabmanViewController+Embedding.swift b/Sources/Tabman/TabmanViewController+Embedding.swift new file mode 100644 index 00000000..51bac853 --- /dev/null +++ b/Sources/Tabman/TabmanViewController+Embedding.swift @@ -0,0 +1,94 @@ +// +// TabmanViewController+Embedding.swift +// Tabman +// +// Created by Merrick Sapsford on 03/04/2017. +// Copyright © 2017 Merrick Sapsford. All rights reserved. +// + +import UIKit + +// MARK: - External TabmanBar attach/detachment. +public extension TabmanViewController { + + /// Attach a TabmanBar that is somewhere in the view hierarchy. + /// This will replace the TabmanViewController managed instance. + /// + /// - Parameter bar: The bar to attach. + public func attach(bar: TabmanBar) { + guard self.attachedTabmanBar == nil else { return } + + self.tabmanBar?.isHidden = true + self.reloadRequiredBarInsets() + + // hook up new bar + bar.dataSource = self + bar.delegate = self + bar.transitionStore = self.barTransitionStore + if let appearance = self.bar.appearance { + bar.appearance = appearance + } + bar.isHidden = true + self.attachedTabmanBar = bar + + bar.reloadData() + } + + /// Detach a currently attached external TabmanBar. + /// This will reinstate the TabmanViewController managed instance. + /// + /// - Returns: The detached bar. + @discardableResult public func detachAttachedBar() -> TabmanBar? { + guard let bar = self.attachedTabmanBar else { return nil } + guard self.attachedTabmanBar === bar else { return nil } + + bar.dataSource = nil + bar.delegate = nil + bar.transitionStore = nil + bar.isHidden = false + self.attachedTabmanBar = nil + + self.tabmanBar?.reloadData() + self.view.layoutIfNeeded() + + self.reloadRequiredBarInsets() + + return bar + } + +} + +// MARK: - Internal TabmanBar embedding in external view. +public extension TabmanViewController { + + /// Embed the TabmanBar in an external view. + /// This will add the bar to the specified view, and pin the bar edges to the view edges. + /// + /// - Parameter view: The view to embed the bar in. + public func embedBar(inView view: UIView) { + guard let bar = self.tabmanBar else { return } + guard self.embeddingView == nil || view === self.embeddingView else { return } + + self.embeddingView = view + + bar.removeFromSuperview() + view.addSubview(bar) + bar.autoPinEdgesToSuperviewEdges() + self.reloadRequiredBarInsets() + + view.layoutIfNeeded() + } + + /// Disembed the TabmanBar from an external view if it is currently embedded. + public func disembedBar() { + guard let bar = self.tabmanBar else { return } + guard self.embeddingView != nil else { return } + + bar.removeFromSuperview() + self.embeddingView = nil + + self.updateBar(withLocation: self.bar.location) + self.reloadRequiredBarInsets() + } + +} diff --git a/Sources/Tabman/TabmanViewController+Insetting.swift b/Sources/Tabman/TabmanViewController+Insetting.swift new file mode 100644 index 00000000..1aef099c --- /dev/null +++ b/Sources/Tabman/TabmanViewController+Insetting.swift @@ -0,0 +1,117 @@ +// +// TabmanViewController+Insetting.swift +// Tabman +// +// Created by Merrick Sapsford on 19/04/2017. +// Copyright © 2017 Merrick Sapsford. All rights reserved. +// + +import Foundation + +// MARK: - Required Bar inset calculation. +internal extension TabmanViewController { + + /// Reload the required bar insets for the current bar. + func reloadRequiredBarInsets() { + self.bar.requiredInsets = TabmanBar.Insets(topLayoutGuide: self.topLayoutGuide.length, + bottomLayoutGuide: self.bottomLayoutGuide.length, + bar: self.calculateRequiredBarInsets()) + } + + /// Calculate the required insets for the current bar. + /// + /// - Returns: The required bar insets + private func calculateRequiredBarInsets() -> UIEdgeInsets { + guard self.embeddingView == nil && self.attachedTabmanBar == nil else { + return .zero + } + + let frame = self.activeTabmanBar?.frame ?? .zero + var insets = UIEdgeInsets.zero + + var location = self.bar.location + if location == .preferred { + location = self.bar.style.preferredLocation + } + + switch location { + case .bottom: + insets.bottom = frame.size.height + + default: + insets.top = frame.size.height + } + return insets + } +} + +// MARK: - Child view controller insetting. +internal extension TabmanViewController { + + /// Automatically inset any table/collection views in a child view controller for the TabmanBar. + /// + /// - Parameter childViewController: The child view controller. + func insetChildViewControllerIfNeeded(_ childViewController: UIViewController?) { + + guard let childViewController = childViewController else { return } + guard self.automaticallyAdjustsChildScrollViewInsets else { return } + + // if a scroll view is found in child VC subviews inset by the required content inset. + for subview in childViewController.view?.subviews ?? [] { + if let scrollView = subview as? UIScrollView { + + var requiredContentInset = self.bar.requiredInsets.barInsets + let currentContentInset = self.viewControllerInsets[scrollView.hash] ?? .zero + + requiredContentInset.top += self.topLayoutGuide.length + self.viewControllerInsets[scrollView.hash] = requiredContentInset + + // take account of custom top / bottom insets + let topInset = scrollView.contentInset.top - currentContentInset.top + if topInset != 0.0 { + requiredContentInset.top += topInset + } + let bottomInset = scrollView.contentInset.bottom - currentContentInset.bottom + if bottomInset != 0.0 { + requiredContentInset.bottom += bottomInset + } + + requiredContentInset.left = currentContentInset.left + requiredContentInset.right = currentContentInset.right + + // ensure scroll view is either at top or full height before doing automatic insetting + if requiredContentInset.top > 0.0 { + guard scrollView.frame.minY == 0.0 else { continue } + } + if requiredContentInset.bottom > 0.0 { + guard scrollView.superview!.bounds.maxY - scrollView.frame.maxY == 0.0 else { continue } + } + + // dont update if we dont need to + if scrollView.contentInset != requiredContentInset { + + scrollView.contentInset = requiredContentInset + scrollView.scrollIndicatorInsets = requiredContentInset + + var contentOffset = scrollView.contentOffset + contentOffset.y = -requiredContentInset.top + scrollView.contentOffset = contentOffset + } + } + } + } +} + +// MARK: - UIViewController extension for handling insetting. +public extension UIViewController { + + /// Indicates to the TabmanViewController that a child scroll view inset + /// needs to be updated. + /// + /// This should be called if the contentInset of a UITableView or UICollectionView is changed + /// after viewDidLoad. + public func setNeedsScrollViewInsetUpdate() { + guard let tabmanViewController = self.parent?.parent as? TabmanViewController else { return } + tabmanViewController.insetChildViewControllerIfNeeded(self) + } +} diff --git a/Sources/Tabman/TabmanViewController.swift b/Sources/Tabman/TabmanViewController.swift index 617710db..e1def52c 100644 --- a/Sources/Tabman/TabmanViewController.swift +++ b/Sources/Tabman/TabmanViewController.swift @@ -12,19 +12,17 @@ import Pageboy /// Page view controller with a bar indicator component. open class TabmanViewController: PageboyViewController, PageboyViewControllerDelegate { - // // MARK: Properties - // - /// The instance managed Tabman bar. + /// The internally managed Tabman bar. internal fileprivate(set) var tabmanBar: TabmanBar? - /// Currently attached TabmanBar if it exists. - internal fileprivate(set) var attachedTabmanBar: TabmanBar? + /// The currently attached TabmanBar (if it exists). + internal var attachedTabmanBar: TabmanBar? /// The view that is currently being used to embed the instance managed TabmanBar. - internal fileprivate(set) var embeddingView: UIView? + internal var embeddingView: UIView? /// Returns the active bar, prefers attachedTabmanBar if available. - fileprivate var activeTabmanBar: TabmanBar? { + internal var activeTabmanBar: TabmanBar? { if let attachedTabmanBar = self.attachedTabmanBar { return attachedTabmanBar } @@ -38,12 +36,24 @@ open class TabmanViewController: PageboyViewController, PageboyViewControllerDel /// Internal store for bar component transitions. internal lazy var barTransitionStore = TabmanBarTransitionStore() - // + internal lazy var viewControllerInsets: [Int : UIEdgeInsets] = [:] + + /// Whether any UICollectionView / UITableView in child view controllers should be + /// automatically insetted to display below the TabmanBar. + public var automaticallyAdjustsChildScrollViewInsets: Bool = true { + didSet { + if automaticallyAdjustsScrollViewInsets { + self.automaticallyAdjustsScrollViewInsets = false + } + } + } + // MARK: Lifecycle - // - open override func loadView() { - super.loadView() + open override func viewDidLoad() { + super.viewDidLoad() + + self.automaticallyAdjustsScrollViewInsets = false self.delegate = self self.bar.delegate = self @@ -53,6 +63,13 @@ open class TabmanViewController: PageboyViewController, PageboyViewControllerDel self.updateBar(withLocation: self.bar.location) } + open override func viewDidLayoutSubviews() { + super.viewDidLayoutSubviews() + + self.reloadRequiredBarInsets() + self.insetChildViewControllerIfNeeded(self.currentViewController) + } + open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { super.viewWillTransition(to: size, with: coordinator) let bounds = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height) @@ -62,14 +79,14 @@ open class TabmanViewController: PageboyViewController, PageboyViewControllerDel }, completion: nil) } - // // MARK: PageboyViewControllerDelegate - // open func pageboyViewController(_ pageboyViewController: PageboyViewController, willScrollToPageAtIndex index: Int, direction: PageboyViewController.NavigationDirection, animated: Bool) { + self.insetChildViewControllerIfNeeded(self.viewControllers?[index]) + if animated { UIView.animate(withDuration: 0.3, animations: { self.activeTabmanBar?.updatePosition(CGFloat(index), direction: direction) @@ -99,7 +116,7 @@ open class TabmanViewController: PageboyViewController, PageboyViewControllerDel open func pageboyViewController(_ pageboyViewController: PageboyViewController, didReload viewControllers: [UIViewController], currentIndex: PageboyViewController.PageIndex) { - + self.insetChildViewControllerIfNeeded(self.currentViewController) } private func updateBar(withPosition position: CGFloat, @@ -145,7 +162,6 @@ internal extension TabmanViewController { self.tabmanBar = bar } - /// Update the bar with a new screen location. /// /// - Parameter location: The new location. @@ -186,124 +202,15 @@ internal extension TabmanViewController { let position = self.navigationOrientation == .horizontal ? self.currentPosition?.x : self.currentPosition?.y bar.updatePosition(position ?? 0.0, direction: .neutral) - } - - /// Reload the required bar insets for the current bar. - func reloadRequiredBarInsets() { - self.bar.requiredContentInset = self.calculateRequiredBarInsets() - } - - /// Calculate the required insets for the current bar. - /// - /// - Returns: The required bar insets - private func calculateRequiredBarInsets() -> UIEdgeInsets { - guard self.embeddingView == nil && self.attachedTabmanBar == nil else { - return .zero - } - let frame = self.activeTabmanBar?.frame ?? .zero - var insets = UIEdgeInsets.zero - - var location = self.bar.location - if location == .preferred { - location = self.bar.style.preferredLocation - } - - switch location { - case .bottom: - insets.bottom = frame.size.height - - default: - insets.top = frame.size.height - } - return insets - } -} - -// MARK: - TabmanBar attach/detachment -public extension TabmanViewController { - - /// Attach a TabmanBar that is somewhere in the view hierarchy. - /// This will replace the TabmanViewController managed instance. - /// - /// - Parameter bar: The bar to attach. - public func attach(bar: TabmanBar) { - guard self.attachedTabmanBar == nil else { return } - - self.tabmanBar?.isHidden = true - self.reloadRequiredBarInsets() - - // hook up new bar - bar.dataSource = self - bar.delegate = self - bar.transitionStore = self.barTransitionStore - if let appearance = self.bar.appearance { - bar.appearance = appearance - } - bar.isHidden = true - self.attachedTabmanBar = bar - - bar.reloadData() - } - - - /// Detach a currently attached external TabmanBar. - /// This will reinstate the TabmanViewController managed instance. - /// - /// - Returns: The detached bar. - @discardableResult public func detachAttachedBar() -> TabmanBar? { - guard let bar = self.attachedTabmanBar else { return nil } - guard self.attachedTabmanBar === bar else { return nil } - - bar.dataSource = nil - bar.delegate = nil - bar.transitionStore = nil - bar.isHidden = false - self.attachedTabmanBar = nil - - self.tabmanBar?.reloadData() - self.view.layoutIfNeeded() - - self.reloadRequiredBarInsets() - - return bar - } - - /// Embed the TabmanBar in an external view. - /// This will add the bar to the specified view, and pin the bar edges to the view edges. - /// - /// - Parameter view: The view to embed the bar in. - public func embedBar(inView view: UIView) { - guard let bar = self.tabmanBar else { return } - guard self.embeddingView == nil || view === self.embeddingView else { return } - - self.embeddingView = view - - bar.removeFromSuperview() - view.addSubview(bar) - bar.autoPinEdgesToSuperviewEdges() - self.reloadRequiredBarInsets() - - view.layoutIfNeeded() - } - - /// Disembed the TabmanBar from an external view if it is currently embedded. - public func disembedBar() { - guard let bar = self.tabmanBar else { return } - guard self.embeddingView != nil else { return } - - bar.removeFromSuperview() - self.embeddingView = nil - - self.updateBar(withLocation: self.bar.location) - self.reloadRequiredBarInsets() + self.insetChildViewControllerIfNeeded(self.currentViewController) } } // MARK: - TabmanBarDataSource, TabmanBarDelegate extension TabmanViewController: TabmanBarDataSource, TabmanBarDelegate { - public func items(forBar bar: TabmanBar) -> [TabmanBarItem]? { + public func items(for bar: TabmanBar) -> [TabmanBarItem]? { if let itemCountLimit = bar.itemCountLimit { guard self.bar.items?.count ?? 0 <= itemCountLimit else { print("TabmanBar Error:\nItems in bar.items exceed the available count for the current bar style: (\(itemCountLimit)).") @@ -315,7 +222,7 @@ extension TabmanViewController: TabmanBarDataSource, TabmanBarDelegate { return self.bar.items } - public func bar(_ bar: TabmanBar, didSelectItemAtIndex index: Int) { + public func bar(_ bar: TabmanBar, didSelectItemAt index: Int) { self.scrollToPage(.at(index: index), animated: true) } } @@ -323,7 +230,7 @@ extension TabmanViewController: TabmanBarDataSource, TabmanBarDelegate { // MARK: - TabmanBarConfigDelegate extension TabmanViewController: TabmanBarConfigDelegate { - func config(_ config: TabmanBarConfig, didUpdateStyle style: TabmanBar.Style) { + func config(_ config: TabmanBarConfig, didUpdate style: TabmanBar.Style) { guard self.attachedTabmanBar == nil else { return } self.clearUpBar(&self.tabmanBar) @@ -331,19 +238,19 @@ extension TabmanViewController: TabmanBarConfigDelegate { self.updateBar(withLocation: config.location) } - func config(_ config: TabmanBarConfig, didUpdateLocation location: TabmanBarConfig.Location) { + func config(_ config: TabmanBarConfig, didUpdate location: TabmanBarConfig.Location) { guard self.attachedTabmanBar == nil else { return } self.updateBar(withLocation: location) } - func config(_ config: TabmanBarConfig, didUpdateAppearance appearance: TabmanBar.Appearance) { + func config(_ config: TabmanBarConfig, didUpdate appearance: TabmanBar.Appearance) { self.activeTabmanBar?.appearance = appearance } - func config(_ config: TabmanBarConfig, didUpdateItems items: [TabmanBarItem]?) { + func config(_ config: TabmanBarConfig, didUpdate items: [TabmanBarItem]?) { self.activeTabmanBar?.reloadData() - + self.view.layoutIfNeeded() self.reloadRequiredBarInsets() } diff --git a/Sources/TabmanTests/Components/TabmanTestBar.swift b/Sources/TabmanTests/Components/TabmanTestBar.swift index d2b7ada8..eddee131 100644 --- a/Sources/TabmanTests/Components/TabmanTestBar.swift +++ b/Sources/TabmanTests/Components/TabmanTestBar.swift @@ -85,7 +85,7 @@ class TabmanTestBar: TabmanBar { extension TabmanTestBar: TabmanBarDataSource { - func items(forBar bar: TabmanBar) -> [TabmanBarItem]? { + func items(for bar: TabmanBar) -> [TabmanBarItem]? { guard numberOfTabs > 0 else { return nil } diff --git a/Sources/TabmanTests/TabmanViewControllerTests.swift b/Sources/TabmanTests/TabmanViewControllerTests.swift index 8ce167c6..47e5ed96 100644 --- a/Sources/TabmanTests/TabmanViewControllerTests.swift +++ b/Sources/TabmanTests/TabmanViewControllerTests.swift @@ -13,11 +13,7 @@ import Pageboy class TabmanViewControllerTests: XCTestCase { var tabmanViewController: TabmanTestViewController! - - // - // MARK: Environment - // - + override func setUp() { super.setUp() @@ -25,11 +21,6 @@ class TabmanViewControllerTests: XCTestCase { self.tabmanViewController.loadViewIfNeeded() } - - // - // MARK: Tests - // - /// Test that the item count limit on a TabmanBar is correctly handled /// with valid data. func testItemCountLimit() { @@ -59,6 +50,8 @@ class TabmanViewControllerTests: XCTestCase { "TabmanBar itemCountLimit is not evaluated correctly for invalid item count.") } + // MARK: Attachment + /// Test that TabmanViewController allows attaching of an external TabmanBar correctly. func testAttachExternalBar() { let testBar = TabmanTestBar() @@ -84,6 +77,8 @@ class TabmanViewControllerTests: XCTestCase { "Detaching external TabmanBar does not clean up correctly.") } + // MARK: Embedding + /// Test that TambmanViewController handles embedding internal TabmanBar in an external view. func testEmbedBarExternally() { let testView = UIView() @@ -107,4 +102,11 @@ class TabmanViewControllerTests: XCTestCase { self.tabmanViewController.embeddingView == nil, "Disembedding TabmanBar from an external view does not clean up correctly.") } + + // MARK: Insetting + + /// Test that automaticallyAdjustsScrollViewInsets is set to false. + func testAutomaticallyAdjustScrollViewInsetsFlag() { + XCTAssertFalse(self.tabmanViewController.automaticallyAdjustsScrollViewInsets) + } } diff --git a/Tabman.podspec b/Tabman.podspec index 33bd7f25..c0fa68ef 100644 --- a/Tabman.podspec +++ b/Tabman.podspec @@ -4,7 +4,7 @@ Pod::Spec.new do |s| s.platform = :ios, "9.0" s.requires_arc = true - s.version = "0.4.8" + s.version = "0.5.0" s.summary = "A powerful paging view controller with indicator bar for iOS" s.description = <<-DESC Tabman is a highly customisable, powerful and extendable paging view controller with indicator bar. @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.source = { :git => "https://github.com/uias/Tabman.git", :tag => s.version.to_s } s.source_files = "Sources/Tabman/**/*.{h,m,swift}" - s.dependency 'Pageboy', '1.0.4' + s.dependency 'Pageboy', '1.0.7' s.dependency 'PureLayout', '~> 3.0.0' end diff --git a/Tabman.xcworkspace/contents.xcworkspacedata b/Tabman.xcworkspace/contents.xcworkspacedata index 6bf08029..ddf0571d 100644 --- a/Tabman.xcworkspace/contents.xcworkspacedata +++ b/Tabman.xcworkspace/contents.xcworkspacedata @@ -7,7 +7,4 @@ - - diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 00000000..18bea987 --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1 @@ +app_identifier "com.msapsford.tabman" # The bundle identifier of your app diff --git a/fastlane/Fastfile b/fastlane/Fastfile new file mode 100644 index 00000000..b4498636 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,46 @@ + +fastlane_version "2.26.1" + +default_platform :ios + +platform :ios do + + desc "Bootstrap dependencies" + lane :bootstrap do + carthage( + command: "bootstrap", + platform: "iOS" + ) + end + + desc "Run unit tests" + lane :test do + bootstrap + scan(workspace: "Tabman.xcworkspace", scheme: "Tabman", clean: true) + end + + desc "Deploy a new version to CocoaPods and GitHub" + lane :deploy do + podspec = "Tabman.podspec" + + # get Podspec version + version = version_get_podspec(path: podspec) + + # Push new Github release + github_release = set_github_release( + repository_name: "uias/Tabman", + api_token: ENV["GITHUB_TOKEN"], + name: version, + tag_name: version, + description: "#{version} release.", + commitish: "master" + ) + + # Push spec + pod_push(allow_warnings: true, verbose: true) + + slack( + message: "Tabman v#{version} released!" + ) + end +end \ No newline at end of file