├── .gitignore ├── .swift-version ├── .travis.yml ├── CHANGELOG.md ├── Example ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── SJSegmentedScrollView.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── SJSegmentedScrollView.xcscheme │ └── Target Support Files │ │ ├── Pods-SJSegmentedScrollViewDemo │ │ ├── Info.plist │ │ ├── Pods-SJSegmentedScrollViewDemo-acknowledgements.markdown │ │ ├── Pods-SJSegmentedScrollViewDemo-acknowledgements.plist │ │ ├── Pods-SJSegmentedScrollViewDemo-dummy.m │ │ ├── Pods-SJSegmentedScrollViewDemo-frameworks.sh │ │ ├── Pods-SJSegmentedScrollViewDemo-resources.sh │ │ ├── Pods-SJSegmentedScrollViewDemo-umbrella.h │ │ ├── Pods-SJSegmentedScrollViewDemo.debug.xcconfig │ │ ├── Pods-SJSegmentedScrollViewDemo.modulemap │ │ └── Pods-SJSegmentedScrollViewDemo.release.xcconfig │ │ └── SJSegmentedScrollView │ │ ├── Info.plist │ │ ├── SJSegmentedScrollView-dummy.m │ │ ├── SJSegmentedScrollView-prefix.pch │ │ ├── SJSegmentedScrollView-umbrella.h │ │ ├── SJSegmentedScrollView.modulemap │ │ └── SJSegmentedScrollView.xcconfig ├── SJSegmentedScrollViewDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── SJSegmentedScrollViewDemo.xcscheme ├── SJSegmentedScrollViewDemo.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── SJSegmentedScrollViewDemo │ ├── AppDelegate.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ ├── ViewControllers │ ├── CollectionViewController.swift │ ├── ExamplePresentViewController.swift │ ├── ExamplePushViewController.swift │ ├── FirstTableViewController.swift │ ├── HeaderViewController.swift │ ├── PresentHeaderViewController.swift │ ├── SecondViewController.swift │ ├── ThirdViewController.swift │ └── ViewController.swift │ ├── ar.lproj │ ├── LaunchScreen.strings │ └── Main.strings │ └── image3.JPG ├── LICENSE ├── README.md ├── SJSegmentedScrollView.podspec ├── SJSegmentedScrollView └── Classes │ ├── .gitkeep │ ├── SJContentView.swift │ ├── SJSegmentTab.swift │ ├── SJSegmentView.swift │ ├── SJSegmentedScrollView.swift │ ├── SJSegmentedViewController.swift │ ├── SJShadow.swift │ └── SJUtil.swift ├── _Pods.xcodeproj └── new_demo.gif /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | *.DS_Store 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | .build/ 40 | 41 | # CocoaPods 42 | # 43 | # We recommend against adding the Pods directory to your .gitignore. However 44 | # you should judge for yourself, the pros and cons are mentioned at: 45 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 46 | # 47 | # Pods/ 48 | 49 | # Carthage 50 | # 51 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 52 | # Carthage/Checkouts 53 | 54 | Carthage/Build 55 | 56 | # fastlane 57 | # 58 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 59 | # screenshots whenever they are needed. 60 | # For more information about the recommended setup visit: 61 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 62 | 63 | fastlane/report.xml 64 | fastlane/Preview.html 65 | fastlane/screenshots 66 | fastlane/test_output 67 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.2 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8 3 | env: 4 | global: 5 | - LC_CTYPE=en_US.UTF-8 6 | - LANG=en_US.UTF-8 7 | - WORKSPACE=Example/SJSegmentedScrollViewDemo.xcworkspace 8 | - IOS_FRAMEWORK_SCHEME="SJSegmentedScrollView" 9 | - IOS_SDK=iphonesimulator10.0 10 | matrix: 11 | - DESTINATION="OS=10.0,name=iPhone 6" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="NO" 12 | - DESTINATION="OS=10.0,name=iPhone 6s" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="NO" 13 | - DESTINATION="OS=10.0,name=iPhone 6s Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="NO" 14 | script: 15 | - set -o pipefail 16 | - xcodebuild -version 17 | - xcodebuild -showsdks 18 | 19 | # Run `pod lib lint` if specified 20 | - if [ $POD_LINT == "YES" ]; then 21 | pod lib lint; 22 | fi 23 | 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | `SJSegmentedScrollView` adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | #### 1.x Releases 6 | 7 | #### `1.0.0` to `1.0.10` 8 | * Initial releases 9 | 10 | #### `1.0.11` 11 | * Added objective c project support 12 | * Resolved header view height nil issue 13 | 14 | #### `1.0.12` 15 | * Resolved SplitViewController orientation issues. 16 | * Renamed SJSegmentedViewController contentControllers property to segmentControllers. 17 | 18 | #### `1.1.0` 19 | * Added shadow to segment view. (issue #6) 20 | * Added SJSegmentedViewControllerDelegate to access current viewcontroller, segment and index. 21 | * Added a property to get SJSegmentedScrollView segments. 22 | 23 | #### `1.2.0` 24 | * Upgraded to Swift 3.0 25 | 26 | #### `1.2.1` 27 | * Updated documentations. 28 | 29 | #### `1.3.1` 30 | * Added support to CollectionViewController. 31 | * Added Custom Segment tab view support. (issue #22) 32 | * Resolved crash issue. (issue #23) 33 | 34 | #### `1.3.2` 35 | * Resolved white space issue. 36 | 37 | #### `1.3.3` 38 | * Resolved issue #25. Using '`func setSelectedSegmentAt(_ index: Int, animated: Bool)` to change segment programmatically. 39 | 40 | #### `1.3.5` 41 | * Resolved issue #29. Added supports for UIRefreshControl and custom pull to refresh libraries. 42 | 43 | #### `1.3.6` 44 | * Resolved issue #54. How to disable Scroll indicator. 45 | 46 | #### `1.3.8` 47 | * Migrated to Swift 4. 48 | 49 | #### `1.3.9` 50 | * Added 'segmentBounces' property to set content view bounces. 51 | 52 | #### `1.4.0` 53 | * Migrated to Swift 4.2 54 | 55 | #### `1.5.0` 56 | * RTL support added. 57 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '10.0' 3 | 4 | target 'SJSegmentedScrollViewDemo' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | pod 'SJSegmentedScrollView', :path => '../' 8 | end 9 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SJSegmentedScrollView (1.3.9) 3 | 4 | DEPENDENCIES: 5 | - SJSegmentedScrollView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SJSegmentedScrollView: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SJSegmentedScrollView: c0060ff2df5de621c4f7f2b2dc6c3d12dbcb5353 13 | 14 | PODFILE CHECKSUM: e226e41b52abc228846f2f327774db2d17f87ac4 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/SJSegmentedScrollView.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SJSegmentedScrollView", 3 | "platforms": { 4 | "ios": "9.0" 5 | }, 6 | "summary": "Custom segmented header scrollview controller.", 7 | "requires_arc": true, 8 | "version": "1.3.9", 9 | "license": { 10 | "type": "MIT", 11 | "file": "LICENSE" 12 | }, 13 | "homepage": "https://github.com/subinspathilettu/SJSegmentedViewController", 14 | "authors": { 15 | "Subins Jose": "subinsjose@gmail.com" 16 | }, 17 | "source": { 18 | "git": "https://github.com/subinspathilettu/SJSegmentedViewController.git", 19 | "tag": "v1.3.9" 20 | }, 21 | "source_files": "SJSegmentedScrollView/Classes/*.{swift}", 22 | "social_media_url": "https://twitter.com/subinsjose", 23 | "frameworks": "UIKit" 24 | } 25 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SJSegmentedScrollView (1.3.9) 3 | 4 | DEPENDENCIES: 5 | - SJSegmentedScrollView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SJSegmentedScrollView: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SJSegmentedScrollView: c0060ff2df5de621c4f7f2b2dc6c3d12dbcb5353 13 | 14 | PODFILE CHECKSUM: e226e41b52abc228846f2f327774db2d17f87ac4 15 | 16 | COCOAPODS: 1.5.3 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 181D595350D2975D3FC271E89978EC1E /* SJSegmentedScrollView-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B1C79664797D2604112C74DFC0BE7E0 /* SJSegmentedScrollView-dummy.m */; }; 11 | 2C7919367FE13478901C76F2CB888417 /* SJUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 334DBBC57FA135A655045BAAC8C09DFE /* SJUtil.swift */; }; 12 | 42BD38DD4F8BF48F094C7759FCED9EB3 /* SJSegmentedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E9C0FC47F377BCF1FDF048D0ECFA5EA /* SJSegmentedScrollView.swift */; }; 13 | 50E2ECE61460C2CB9C0ECA3655ACDAE8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 908E902E026C5C22904CF9014A5604AD /* Foundation.framework */; }; 14 | 557818CB88EC38ACBFC35EEDC19FCBE4 /* SJContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC62BA8D4EEDCDFFF1AEA3765480414B /* SJContentView.swift */; }; 15 | 6192ABC2AF56D3697C236E19E65EA4D3 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC2C02191C153C1554B35DEE8B2D09D4 /* UIKit.framework */; }; 16 | 6C309369D7E7362853343E04762EDFE4 /* SJShadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09A8A08F3D48D990D2147F29BE7C992E /* SJShadow.swift */; }; 17 | 744ABA1746C52B67CAD57B6646E9C4EB /* Pods-SJSegmentedScrollViewDemo-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E1D7DB9D40BD01F225B389D15370B926 /* Pods-SJSegmentedScrollViewDemo-dummy.m */; }; 18 | 9545E1BA43722E514650364870CC4E38 /* SJSegmentedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35343CAAE2AC757A2DDF5B28DE0FA109 /* SJSegmentedViewController.swift */; }; 19 | A309D53B5E9A344A0F602F51F3491B08 /* SJSegmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FC89E51D581D024CB216CAD730B64A8 /* SJSegmentView.swift */; }; 20 | AC1161EB456643BB60DA9BB69425596E /* Pods-SJSegmentedScrollViewDemo-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C032181D786A5454895B11840213900 /* Pods-SJSegmentedScrollViewDemo-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | D266C8A8756942CDEFE9AE4A9F4E5565 /* SJSegmentedScrollView-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C3C7280DE7C4E7705D14406BAD78B0 /* SJSegmentedScrollView-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | EE6CE46D29E6143B789762C825990123 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 908E902E026C5C22904CF9014A5604AD /* Foundation.framework */; }; 23 | EED10265998E1D26D80C17779B32645A /* SJSegmentTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 120C27CBA23CF7DE1B9269CA5BB705CB /* SJSegmentTab.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | 1544CB80828654963C075F2360F4637C /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 33F3826C7F86DF5250ACD6ABEDD18C3F; 32 | remoteInfo = SJSegmentedScrollView; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 06822C469AB3304A139C07650CF16A84 /* Pods-SJSegmentedScrollViewDemo-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SJSegmentedScrollViewDemo-resources.sh"; sourceTree = ""; }; 38 | 09A8A08F3D48D990D2147F29BE7C992E /* SJShadow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJShadow.swift; path = SJSegmentedScrollView/Classes/SJShadow.swift; sourceTree = ""; }; 39 | 120C27CBA23CF7DE1B9269CA5BB705CB /* SJSegmentTab.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJSegmentTab.swift; path = SJSegmentedScrollView/Classes/SJSegmentTab.swift; sourceTree = ""; }; 40 | 1E9C0FC47F377BCF1FDF048D0ECFA5EA /* SJSegmentedScrollView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJSegmentedScrollView.swift; path = SJSegmentedScrollView/Classes/SJSegmentedScrollView.swift; sourceTree = ""; }; 41 | 334DBBC57FA135A655045BAAC8C09DFE /* SJUtil.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJUtil.swift; path = SJSegmentedScrollView/Classes/SJUtil.swift; sourceTree = ""; }; 42 | 35343CAAE2AC757A2DDF5B28DE0FA109 /* SJSegmentedViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJSegmentedViewController.swift; path = SJSegmentedScrollView/Classes/SJSegmentedViewController.swift; sourceTree = ""; }; 43 | 36C8B1870E66131248D723B98F6A2686 /* SJSegmentedScrollView.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SJSegmentedScrollView.modulemap; sourceTree = ""; }; 44 | 4873FC594543922C47486996F28797FF /* Pods-SJSegmentedScrollViewDemo-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-SJSegmentedScrollViewDemo-frameworks.sh"; sourceTree = ""; }; 45 | 54FE8A96D7B23300DCB655442C934F84 /* SJSegmentedScrollView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SJSegmentedScrollView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 5E72248195D35929900357670CAFC7ED /* Pods-SJSegmentedScrollViewDemo-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-SJSegmentedScrollViewDemo-acknowledgements.markdown"; sourceTree = ""; }; 47 | 664217D3E7C2BAAB0A5E9883587ADF82 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 689BE07B6372BC44585327709184FA60 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SJSegmentedScrollViewDemo.release.xcconfig"; sourceTree = ""; }; 49 | 6B1C79664797D2604112C74DFC0BE7E0 /* SJSegmentedScrollView-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SJSegmentedScrollView-dummy.m"; sourceTree = ""; }; 50 | 6C032181D786A5454895B11840213900 /* Pods-SJSegmentedScrollViewDemo-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-SJSegmentedScrollViewDemo-umbrella.h"; sourceTree = ""; }; 51 | 6FC89E51D581D024CB216CAD730B64A8 /* SJSegmentView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJSegmentView.swift; path = SJSegmentedScrollView/Classes/SJSegmentView.swift; sourceTree = ""; }; 52 | 7A74F88D1FA8D7128A8A9020F2A97144 /* SJSegmentedScrollView.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SJSegmentedScrollView.xcconfig; sourceTree = ""; }; 53 | 83C3C7280DE7C4E7705D14406BAD78B0 /* SJSegmentedScrollView-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SJSegmentedScrollView-umbrella.h"; sourceTree = ""; }; 54 | 908E902E026C5C22904CF9014A5604AD /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 55 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 56 | 9C575CDEE6CDB2FC70CEFCC5AAE08804 /* Pods-SJSegmentedScrollViewDemo-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-SJSegmentedScrollViewDemo-acknowledgements.plist"; sourceTree = ""; }; 57 | 9D9C68CF80C40B2232CF212705E41E61 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 58 | A62CA11EEE751578E483C5EA6E94C648 /* SJSegmentedScrollView-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SJSegmentedScrollView-prefix.pch"; sourceTree = ""; }; 59 | AE398EE0044A53DB8F88F472A46E2F6E /* Pods-SJSegmentedScrollViewDemo.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-SJSegmentedScrollViewDemo.modulemap"; sourceTree = ""; }; 60 | BC2C02191C153C1554B35DEE8B2D09D4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 61 | BCE501D5824E669B724DA0EBBE228CC0 /* Pods_SJSegmentedScrollViewDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SJSegmentedScrollViewDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 62 | BF3EC4104A7C9509D702B17BD1B48567 /* SJSegmentedScrollView.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; path = SJSegmentedScrollView.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 63 | C847B6BF293B2511091E214700C3F12C /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-SJSegmentedScrollViewDemo.debug.xcconfig"; sourceTree = ""; }; 64 | D13036BDF1EA17CC8C04350BB9CC520B /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | E1D7DB9D40BD01F225B389D15370B926 /* Pods-SJSegmentedScrollViewDemo-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-SJSegmentedScrollViewDemo-dummy.m"; sourceTree = ""; }; 66 | E5B5322712D02EC60034C4D1A1D2B192 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 67 | EC62BA8D4EEDCDFFF1AEA3765480414B /* SJContentView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SJContentView.swift; path = SJSegmentedScrollView/Classes/SJContentView.swift; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 2E40E82D9DA3B9421948807BC911BE94 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | EE6CE46D29E6143B789762C825990123 /* Foundation.framework in Frameworks */, 76 | 6192ABC2AF56D3697C236E19E65EA4D3 /* UIKit.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | C41970D98DAD34D1F6928DF51E3C697F /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | 50E2ECE61460C2CB9C0ECA3655ACDAE8 /* Foundation.framework in Frameworks */, 85 | ); 86 | runOnlyForDeploymentPostprocessing = 0; 87 | }; 88 | /* End PBXFrameworksBuildPhase section */ 89 | 90 | /* Begin PBXGroup section */ 91 | 0BC3F1DE11517BC4A32BC6163E488945 /* Pods-SJSegmentedScrollViewDemo */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 664217D3E7C2BAAB0A5E9883587ADF82 /* Info.plist */, 95 | AE398EE0044A53DB8F88F472A46E2F6E /* Pods-SJSegmentedScrollViewDemo.modulemap */, 96 | 5E72248195D35929900357670CAFC7ED /* Pods-SJSegmentedScrollViewDemo-acknowledgements.markdown */, 97 | 9C575CDEE6CDB2FC70CEFCC5AAE08804 /* Pods-SJSegmentedScrollViewDemo-acknowledgements.plist */, 98 | E1D7DB9D40BD01F225B389D15370B926 /* Pods-SJSegmentedScrollViewDemo-dummy.m */, 99 | 4873FC594543922C47486996F28797FF /* Pods-SJSegmentedScrollViewDemo-frameworks.sh */, 100 | 06822C469AB3304A139C07650CF16A84 /* Pods-SJSegmentedScrollViewDemo-resources.sh */, 101 | 6C032181D786A5454895B11840213900 /* Pods-SJSegmentedScrollViewDemo-umbrella.h */, 102 | C847B6BF293B2511091E214700C3F12C /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */, 103 | 689BE07B6372BC44585327709184FA60 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */, 104 | ); 105 | name = "Pods-SJSegmentedScrollViewDemo"; 106 | path = "Target Support Files/Pods-SJSegmentedScrollViewDemo"; 107 | sourceTree = ""; 108 | }; 109 | 10DEDCB394BAA0C7FEDEBE330207B074 /* iOS */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 908E902E026C5C22904CF9014A5604AD /* Foundation.framework */, 113 | BC2C02191C153C1554B35DEE8B2D09D4 /* UIKit.framework */, 114 | ); 115 | name = iOS; 116 | sourceTree = ""; 117 | }; 118 | 3CE64127FEC9FD85DA3A70D6CFCCAE72 /* Development Pods */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | D49309E7FB36FCB14E9423BE3D70EA84 /* SJSegmentedScrollView */, 122 | ); 123 | name = "Development Pods"; 124 | sourceTree = ""; 125 | }; 126 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 10DEDCB394BAA0C7FEDEBE330207B074 /* iOS */, 130 | ); 131 | name = Frameworks; 132 | sourceTree = ""; 133 | }; 134 | 7DB346D0F39D3F0E887471402A8071AB = { 135 | isa = PBXGroup; 136 | children = ( 137 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 138 | 3CE64127FEC9FD85DA3A70D6CFCCAE72 /* Development Pods */, 139 | 433CD3331B6C3787F473C941B61FC68F /* Frameworks */, 140 | 9CE4359DC1FB686C8A8D48C36D58BBCA /* Products */, 141 | F8AEBD3231AF04A6FFCA35C07B6518D4 /* Targets Support Files */, 142 | ); 143 | sourceTree = ""; 144 | }; 145 | 9CE4359DC1FB686C8A8D48C36D58BBCA /* Products */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | BCE501D5824E669B724DA0EBBE228CC0 /* Pods_SJSegmentedScrollViewDemo.framework */, 149 | 54FE8A96D7B23300DCB655442C934F84 /* SJSegmentedScrollView.framework */, 150 | ); 151 | name = Products; 152 | sourceTree = ""; 153 | }; 154 | B8DDCCAAB25CD4DBC75013B7D697C874 /* Support Files */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | D13036BDF1EA17CC8C04350BB9CC520B /* Info.plist */, 158 | 36C8B1870E66131248D723B98F6A2686 /* SJSegmentedScrollView.modulemap */, 159 | 7A74F88D1FA8D7128A8A9020F2A97144 /* SJSegmentedScrollView.xcconfig */, 160 | 6B1C79664797D2604112C74DFC0BE7E0 /* SJSegmentedScrollView-dummy.m */, 161 | A62CA11EEE751578E483C5EA6E94C648 /* SJSegmentedScrollView-prefix.pch */, 162 | 83C3C7280DE7C4E7705D14406BAD78B0 /* SJSegmentedScrollView-umbrella.h */, 163 | ); 164 | name = "Support Files"; 165 | path = "Example/Pods/Target Support Files/SJSegmentedScrollView"; 166 | sourceTree = ""; 167 | }; 168 | D49309E7FB36FCB14E9423BE3D70EA84 /* SJSegmentedScrollView */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | EC62BA8D4EEDCDFFF1AEA3765480414B /* SJContentView.swift */, 172 | 1E9C0FC47F377BCF1FDF048D0ECFA5EA /* SJSegmentedScrollView.swift */, 173 | 35343CAAE2AC757A2DDF5B28DE0FA109 /* SJSegmentedViewController.swift */, 174 | 120C27CBA23CF7DE1B9269CA5BB705CB /* SJSegmentTab.swift */, 175 | 6FC89E51D581D024CB216CAD730B64A8 /* SJSegmentView.swift */, 176 | 09A8A08F3D48D990D2147F29BE7C992E /* SJShadow.swift */, 177 | 334DBBC57FA135A655045BAAC8C09DFE /* SJUtil.swift */, 178 | D81A905681BC1BF8088DCF8AE04B71D5 /* Pod */, 179 | B8DDCCAAB25CD4DBC75013B7D697C874 /* Support Files */, 180 | ); 181 | name = SJSegmentedScrollView; 182 | path = ../..; 183 | sourceTree = ""; 184 | }; 185 | D81A905681BC1BF8088DCF8AE04B71D5 /* Pod */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 9D9C68CF80C40B2232CF212705E41E61 /* LICENSE */, 189 | E5B5322712D02EC60034C4D1A1D2B192 /* README.md */, 190 | BF3EC4104A7C9509D702B17BD1B48567 /* SJSegmentedScrollView.podspec */, 191 | ); 192 | name = Pod; 193 | sourceTree = ""; 194 | }; 195 | F8AEBD3231AF04A6FFCA35C07B6518D4 /* Targets Support Files */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | 0BC3F1DE11517BC4A32BC6163E488945 /* Pods-SJSegmentedScrollViewDemo */, 199 | ); 200 | name = "Targets Support Files"; 201 | sourceTree = ""; 202 | }; 203 | /* End PBXGroup section */ 204 | 205 | /* Begin PBXHeadersBuildPhase section */ 206 | AA413D4FFB9B54B1A4BDB603F8394035 /* Headers */ = { 207 | isa = PBXHeadersBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | D266C8A8756942CDEFE9AE4A9F4E5565 /* SJSegmentedScrollView-umbrella.h in Headers */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | F394D453AA3A121BADDECA215B0AC8BF /* Headers */ = { 215 | isa = PBXHeadersBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | AC1161EB456643BB60DA9BB69425596E /* Pods-SJSegmentedScrollViewDemo-umbrella.h in Headers */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXHeadersBuildPhase section */ 223 | 224 | /* Begin PBXNativeTarget section */ 225 | 0B1DF6C0DAA79E0D6231559CFB39CB8D /* Pods-SJSegmentedScrollViewDemo */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 5B9E3EF0C9635DE53B49DC02C5C7A7D7 /* Build configuration list for PBXNativeTarget "Pods-SJSegmentedScrollViewDemo" */; 228 | buildPhases = ( 229 | 9A31CAFD700D7A0748AA4E37F235A536 /* Sources */, 230 | C41970D98DAD34D1F6928DF51E3C697F /* Frameworks */, 231 | F394D453AA3A121BADDECA215B0AC8BF /* Headers */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | A49CCF577959CF062D641DE4D7A21DF6 /* PBXTargetDependency */, 237 | ); 238 | name = "Pods-SJSegmentedScrollViewDemo"; 239 | productName = "Pods-SJSegmentedScrollViewDemo"; 240 | productReference = BCE501D5824E669B724DA0EBBE228CC0 /* Pods_SJSegmentedScrollViewDemo.framework */; 241 | productType = "com.apple.product-type.framework"; 242 | }; 243 | 33F3826C7F86DF5250ACD6ABEDD18C3F /* SJSegmentedScrollView */ = { 244 | isa = PBXNativeTarget; 245 | buildConfigurationList = 39B4CF3A48901F3BAF54A1799FFE5B49 /* Build configuration list for PBXNativeTarget "SJSegmentedScrollView" */; 246 | buildPhases = ( 247 | 8E4B03A65F39B9A3BDE2AB55BD465392 /* Sources */, 248 | 2E40E82D9DA3B9421948807BC911BE94 /* Frameworks */, 249 | AA413D4FFB9B54B1A4BDB603F8394035 /* Headers */, 250 | ); 251 | buildRules = ( 252 | ); 253 | dependencies = ( 254 | ); 255 | name = SJSegmentedScrollView; 256 | productName = SJSegmentedScrollView; 257 | productReference = 54FE8A96D7B23300DCB655442C934F84 /* SJSegmentedScrollView.framework */; 258 | productType = "com.apple.product-type.framework"; 259 | }; 260 | /* End PBXNativeTarget section */ 261 | 262 | /* Begin PBXProject section */ 263 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 264 | isa = PBXProject; 265 | attributes = { 266 | LastSwiftUpdateCheck = 0930; 267 | LastUpgradeCheck = 0930; 268 | TargetAttributes = { 269 | 33F3826C7F86DF5250ACD6ABEDD18C3F = { 270 | LastSwiftMigration = 1010; 271 | }; 272 | }; 273 | }; 274 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 275 | compatibilityVersion = "Xcode 3.2"; 276 | developmentRegion = English; 277 | hasScannedForEncodings = 0; 278 | knownRegions = ( 279 | en, 280 | ); 281 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 282 | productRefGroup = 9CE4359DC1FB686C8A8D48C36D58BBCA /* Products */; 283 | projectDirPath = ""; 284 | projectRoot = ""; 285 | targets = ( 286 | 0B1DF6C0DAA79E0D6231559CFB39CB8D /* Pods-SJSegmentedScrollViewDemo */, 287 | 33F3826C7F86DF5250ACD6ABEDD18C3F /* SJSegmentedScrollView */, 288 | ); 289 | }; 290 | /* End PBXProject section */ 291 | 292 | /* Begin PBXSourcesBuildPhase section */ 293 | 8E4B03A65F39B9A3BDE2AB55BD465392 /* Sources */ = { 294 | isa = PBXSourcesBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | 557818CB88EC38ACBFC35EEDC19FCBE4 /* SJContentView.swift in Sources */, 298 | 181D595350D2975D3FC271E89978EC1E /* SJSegmentedScrollView-dummy.m in Sources */, 299 | 42BD38DD4F8BF48F094C7759FCED9EB3 /* SJSegmentedScrollView.swift in Sources */, 300 | 9545E1BA43722E514650364870CC4E38 /* SJSegmentedViewController.swift in Sources */, 301 | EED10265998E1D26D80C17779B32645A /* SJSegmentTab.swift in Sources */, 302 | A309D53B5E9A344A0F602F51F3491B08 /* SJSegmentView.swift in Sources */, 303 | 6C309369D7E7362853343E04762EDFE4 /* SJShadow.swift in Sources */, 304 | 2C7919367FE13478901C76F2CB888417 /* SJUtil.swift in Sources */, 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | }; 308 | 9A31CAFD700D7A0748AA4E37F235A536 /* Sources */ = { 309 | isa = PBXSourcesBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | 744ABA1746C52B67CAD57B6646E9C4EB /* Pods-SJSegmentedScrollViewDemo-dummy.m in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXSourcesBuildPhase section */ 317 | 318 | /* Begin PBXTargetDependency section */ 319 | A49CCF577959CF062D641DE4D7A21DF6 /* PBXTargetDependency */ = { 320 | isa = PBXTargetDependency; 321 | name = SJSegmentedScrollView; 322 | target = 33F3826C7F86DF5250ACD6ABEDD18C3F /* SJSegmentedScrollView */; 323 | targetProxy = 1544CB80828654963C075F2360F4637C /* PBXContainerItemProxy */; 324 | }; 325 | /* End PBXTargetDependency section */ 326 | 327 | /* Begin XCBuildConfiguration section */ 328 | 28EB6E24FF156419625652F26BC24BF8 /* Debug */ = { 329 | isa = XCBuildConfiguration; 330 | baseConfigurationReference = 7A74F88D1FA8D7128A8A9020F2A97144 /* SJSegmentedScrollView.xcconfig */; 331 | buildSettings = { 332 | CODE_SIGN_IDENTITY = ""; 333 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 334 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 335 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 336 | CURRENT_PROJECT_VERSION = 1; 337 | DEFINES_MODULE = YES; 338 | DYLIB_COMPATIBILITY_VERSION = 1; 339 | DYLIB_CURRENT_VERSION = 1; 340 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 341 | GCC_PREFIX_HEADER = "Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView-prefix.pch"; 342 | INFOPLIST_FILE = "Target Support Files/SJSegmentedScrollView/Info.plist"; 343 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 344 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 345 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 346 | MODULEMAP_FILE = "Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView.modulemap"; 347 | PRODUCT_MODULE_NAME = SJSegmentedScrollView; 348 | PRODUCT_NAME = SJSegmentedScrollView; 349 | SDKROOT = iphoneos; 350 | SKIP_INSTALL = YES; 351 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 352 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 353 | SWIFT_VERSION = 4.2; 354 | TARGETED_DEVICE_FAMILY = "1,2"; 355 | VERSIONING_SYSTEM = "apple-generic"; 356 | VERSION_INFO_PREFIX = ""; 357 | }; 358 | name = Debug; 359 | }; 360 | 488C41A1EC527E5D0412527143D7C421 /* Release */ = { 361 | isa = XCBuildConfiguration; 362 | baseConfigurationReference = 7A74F88D1FA8D7128A8A9020F2A97144 /* SJSegmentedScrollView.xcconfig */; 363 | buildSettings = { 364 | CODE_SIGN_IDENTITY = ""; 365 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 366 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 367 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 368 | CURRENT_PROJECT_VERSION = 1; 369 | DEFINES_MODULE = YES; 370 | DYLIB_COMPATIBILITY_VERSION = 1; 371 | DYLIB_CURRENT_VERSION = 1; 372 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 373 | GCC_PREFIX_HEADER = "Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView-prefix.pch"; 374 | INFOPLIST_FILE = "Target Support Files/SJSegmentedScrollView/Info.plist"; 375 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 376 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 377 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 378 | MODULEMAP_FILE = "Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView.modulemap"; 379 | PRODUCT_MODULE_NAME = SJSegmentedScrollView; 380 | PRODUCT_NAME = SJSegmentedScrollView; 381 | SDKROOT = iphoneos; 382 | SKIP_INSTALL = YES; 383 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 384 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 385 | SWIFT_VERSION = 4.2; 386 | TARGETED_DEVICE_FAMILY = "1,2"; 387 | VALIDATE_PRODUCT = YES; 388 | VERSIONING_SYSTEM = "apple-generic"; 389 | VERSION_INFO_PREFIX = ""; 390 | }; 391 | name = Release; 392 | }; 393 | 553022A828EE1991F07D2D73F565AEF8 /* Debug */ = { 394 | isa = XCBuildConfiguration; 395 | buildSettings = { 396 | ALWAYS_SEARCH_USER_PATHS = NO; 397 | CLANG_ANALYZER_NONNULL = YES; 398 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 400 | CLANG_CXX_LIBRARY = "libc++"; 401 | CLANG_ENABLE_MODULES = YES; 402 | CLANG_ENABLE_OBJC_ARC = YES; 403 | CLANG_ENABLE_OBJC_WEAK = YES; 404 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 405 | CLANG_WARN_BOOL_CONVERSION = YES; 406 | CLANG_WARN_COMMA = YES; 407 | CLANG_WARN_CONSTANT_CONVERSION = YES; 408 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 409 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 410 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 411 | CLANG_WARN_EMPTY_BODY = YES; 412 | CLANG_WARN_ENUM_CONVERSION = YES; 413 | CLANG_WARN_INFINITE_RECURSION = YES; 414 | CLANG_WARN_INT_CONVERSION = YES; 415 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 417 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 419 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 420 | CLANG_WARN_STRICT_PROTOTYPES = YES; 421 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 422 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 423 | CLANG_WARN_UNREACHABLE_CODE = YES; 424 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 425 | CODE_SIGNING_ALLOWED = NO; 426 | CODE_SIGNING_REQUIRED = NO; 427 | COPY_PHASE_STRIP = NO; 428 | DEBUG_INFORMATION_FORMAT = dwarf; 429 | ENABLE_STRICT_OBJC_MSGSEND = YES; 430 | ENABLE_TESTABILITY = YES; 431 | GCC_C_LANGUAGE_STANDARD = gnu11; 432 | GCC_DYNAMIC_NO_PIC = NO; 433 | GCC_NO_COMMON_BLOCKS = YES; 434 | GCC_OPTIMIZATION_LEVEL = 0; 435 | GCC_PREPROCESSOR_DEFINITIONS = ( 436 | "POD_CONFIGURATION_DEBUG=1", 437 | "DEBUG=1", 438 | "$(inherited)", 439 | ); 440 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 441 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 442 | GCC_WARN_UNDECLARED_SELECTOR = YES; 443 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 444 | GCC_WARN_UNUSED_FUNCTION = YES; 445 | GCC_WARN_UNUSED_VARIABLE = YES; 446 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 447 | MTL_ENABLE_DEBUG_INFO = YES; 448 | ONLY_ACTIVE_ARCH = YES; 449 | PRODUCT_NAME = "$(TARGET_NAME)"; 450 | STRIP_INSTALLED_PRODUCT = NO; 451 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 452 | SYMROOT = "${SRCROOT}/../build"; 453 | }; 454 | name = Debug; 455 | }; 456 | 58CE816B060A41D32CEC095441D0E3E0 /* Release */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | ALWAYS_SEARCH_USER_PATHS = NO; 460 | CLANG_ANALYZER_NONNULL = YES; 461 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 462 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 463 | CLANG_CXX_LIBRARY = "libc++"; 464 | CLANG_ENABLE_MODULES = YES; 465 | CLANG_ENABLE_OBJC_ARC = YES; 466 | CLANG_ENABLE_OBJC_WEAK = YES; 467 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 468 | CLANG_WARN_BOOL_CONVERSION = YES; 469 | CLANG_WARN_COMMA = YES; 470 | CLANG_WARN_CONSTANT_CONVERSION = YES; 471 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 472 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 473 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 474 | CLANG_WARN_EMPTY_BODY = YES; 475 | CLANG_WARN_ENUM_CONVERSION = YES; 476 | CLANG_WARN_INFINITE_RECURSION = YES; 477 | CLANG_WARN_INT_CONVERSION = YES; 478 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 479 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 480 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 481 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 482 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 483 | CLANG_WARN_STRICT_PROTOTYPES = YES; 484 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 485 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 486 | CLANG_WARN_UNREACHABLE_CODE = YES; 487 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 488 | CODE_SIGNING_ALLOWED = NO; 489 | CODE_SIGNING_REQUIRED = NO; 490 | COPY_PHASE_STRIP = NO; 491 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 492 | ENABLE_NS_ASSERTIONS = NO; 493 | ENABLE_STRICT_OBJC_MSGSEND = YES; 494 | GCC_C_LANGUAGE_STANDARD = gnu11; 495 | GCC_NO_COMMON_BLOCKS = YES; 496 | GCC_PREPROCESSOR_DEFINITIONS = ( 497 | "POD_CONFIGURATION_RELEASE=1", 498 | "$(inherited)", 499 | ); 500 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 501 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 502 | GCC_WARN_UNDECLARED_SELECTOR = YES; 503 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 504 | GCC_WARN_UNUSED_FUNCTION = YES; 505 | GCC_WARN_UNUSED_VARIABLE = YES; 506 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 507 | MTL_ENABLE_DEBUG_INFO = NO; 508 | PRODUCT_NAME = "$(TARGET_NAME)"; 509 | STRIP_INSTALLED_PRODUCT = NO; 510 | SYMROOT = "${SRCROOT}/../build"; 511 | }; 512 | name = Release; 513 | }; 514 | 662956281D3B83AE098C6297A62BE8E1 /* Debug */ = { 515 | isa = XCBuildConfiguration; 516 | baseConfigurationReference = C847B6BF293B2511091E214700C3F12C /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */; 517 | buildSettings = { 518 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 519 | CLANG_ENABLE_OBJC_WEAK = NO; 520 | CODE_SIGN_IDENTITY = ""; 521 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 522 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 523 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 524 | CURRENT_PROJECT_VERSION = 1; 525 | DEFINES_MODULE = YES; 526 | DYLIB_COMPATIBILITY_VERSION = 1; 527 | DYLIB_CURRENT_VERSION = 1; 528 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 529 | INFOPLIST_FILE = "Target Support Files/Pods-SJSegmentedScrollViewDemo/Info.plist"; 530 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 531 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 532 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 533 | MACH_O_TYPE = staticlib; 534 | MODULEMAP_FILE = "Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.modulemap"; 535 | OTHER_LDFLAGS = ""; 536 | OTHER_LIBTOOLFLAGS = ""; 537 | PODS_ROOT = "$(SRCROOT)"; 538 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 539 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 540 | SDKROOT = iphoneos; 541 | SKIP_INSTALL = YES; 542 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 543 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 544 | TARGETED_DEVICE_FAMILY = "1,2"; 545 | VERSIONING_SYSTEM = "apple-generic"; 546 | VERSION_INFO_PREFIX = ""; 547 | }; 548 | name = Debug; 549 | }; 550 | ADC6ED2CD71561D4692AE23358DE7831 /* Release */ = { 551 | isa = XCBuildConfiguration; 552 | baseConfigurationReference = 689BE07B6372BC44585327709184FA60 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */; 553 | buildSettings = { 554 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 555 | CLANG_ENABLE_OBJC_WEAK = NO; 556 | CODE_SIGN_IDENTITY = ""; 557 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 558 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 559 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 560 | CURRENT_PROJECT_VERSION = 1; 561 | DEFINES_MODULE = YES; 562 | DYLIB_COMPATIBILITY_VERSION = 1; 563 | DYLIB_CURRENT_VERSION = 1; 564 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 565 | INFOPLIST_FILE = "Target Support Files/Pods-SJSegmentedScrollViewDemo/Info.plist"; 566 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 567 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 568 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 569 | MACH_O_TYPE = staticlib; 570 | MODULEMAP_FILE = "Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.modulemap"; 571 | OTHER_LDFLAGS = ""; 572 | OTHER_LIBTOOLFLAGS = ""; 573 | PODS_ROOT = "$(SRCROOT)"; 574 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 575 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 576 | SDKROOT = iphoneos; 577 | SKIP_INSTALL = YES; 578 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 579 | TARGETED_DEVICE_FAMILY = "1,2"; 580 | VALIDATE_PRODUCT = YES; 581 | VERSIONING_SYSTEM = "apple-generic"; 582 | VERSION_INFO_PREFIX = ""; 583 | }; 584 | name = Release; 585 | }; 586 | /* End XCBuildConfiguration section */ 587 | 588 | /* Begin XCConfigurationList section */ 589 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 590 | isa = XCConfigurationList; 591 | buildConfigurations = ( 592 | 553022A828EE1991F07D2D73F565AEF8 /* Debug */, 593 | 58CE816B060A41D32CEC095441D0E3E0 /* Release */, 594 | ); 595 | defaultConfigurationIsVisible = 0; 596 | defaultConfigurationName = Release; 597 | }; 598 | 39B4CF3A48901F3BAF54A1799FFE5B49 /* Build configuration list for PBXNativeTarget "SJSegmentedScrollView" */ = { 599 | isa = XCConfigurationList; 600 | buildConfigurations = ( 601 | 28EB6E24FF156419625652F26BC24BF8 /* Debug */, 602 | 488C41A1EC527E5D0412527143D7C421 /* Release */, 603 | ); 604 | defaultConfigurationIsVisible = 0; 605 | defaultConfigurationName = Release; 606 | }; 607 | 5B9E3EF0C9635DE53B49DC02C5C7A7D7 /* Build configuration list for PBXNativeTarget "Pods-SJSegmentedScrollViewDemo" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | 662956281D3B83AE098C6297A62BE8E1 /* Debug */, 611 | ADC6ED2CD71561D4692AE23358DE7831 /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | /* End XCConfigurationList section */ 617 | }; 618 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 619 | } 620 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/SJSegmentedScrollView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SJSegmentedScrollView 5 | 6 | Copyright (c) 2017 Subins Jose 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2017 Subins Jose <subinsjose@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | SJSegmentedScrollView 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SJSegmentedScrollViewDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SJSegmentedScrollViewDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | 145 | if [[ "$CONFIGURATION" == "Debug" ]]; then 146 | install_framework "${BUILT_PRODUCTS_DIR}/SJSegmentedScrollView/SJSegmentedScrollView.framework" 147 | fi 148 | if [[ "$CONFIGURATION" == "Release" ]]; then 149 | install_framework "${BUILT_PRODUCTS_DIR}/SJSegmentedScrollView/SJSegmentedScrollView.framework" 150 | fi 151 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 152 | wait 153 | fi 154 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_SJSegmentedScrollViewDemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SJSegmentedScrollViewDemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SJSegmentedScrollView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SJSegmentedScrollView/SJSegmentedScrollView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SJSegmentedScrollView" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SJSegmentedScrollViewDemo { 2 | umbrella header "Pods-SJSegmentedScrollViewDemo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SJSegmentedScrollView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SJSegmentedScrollView/SJSegmentedScrollView.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "SJSegmentedScrollView" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.3.9 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SJSegmentedScrollView : NSObject 3 | @end 4 | @implementation PodsDummy_SJSegmentedScrollView 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double SJSegmentedScrollViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SJSegmentedScrollViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView.modulemap: -------------------------------------------------------------------------------- 1 | framework module SJSegmentedScrollView { 2 | umbrella header "SJSegmentedScrollView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SJSegmentedScrollView/SJSegmentedScrollView.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SJSegmentedScrollView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = -framework "UIKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 648742301DAE2D8100E76916 /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6487422F1DAE2D8100E76916 /* CollectionViewController.swift */; }; 11 | 64A421681D3D4543009BFBFE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A4215A1D3D4543009BFBFE /* AppDelegate.swift */; }; 12 | 64A421691D3D4543009BFBFE /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 64A4215B1D3D4543009BFBFE /* LaunchScreen.xib */; }; 13 | 64A4216A1D3D4543009BFBFE /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 64A4215D1D3D4543009BFBFE /* Main.storyboard */; }; 14 | 64A4216C1D3D4543009BFBFE /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 64A421601D3D4543009BFBFE /* Images.xcassets */; }; 15 | 64A4216E1D3D4543009BFBFE /* FirstTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A421631D3D4543009BFBFE /* FirstTableViewController.swift */; }; 16 | 64A4216F1D3D4543009BFBFE /* HeaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A421641D3D4543009BFBFE /* HeaderViewController.swift */; }; 17 | 64A421701D3D4543009BFBFE /* SecondViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A421651D3D4543009BFBFE /* SecondViewController.swift */; }; 18 | 64A421711D3D4543009BFBFE /* ThirdViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A421661D3D4543009BFBFE /* ThirdViewController.swift */; }; 19 | 64A421721D3D4543009BFBFE /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64A421671D3D4543009BFBFE /* ViewController.swift */; }; 20 | 64EE32D81DE839340003EA2A /* PresentHeaderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64EE32D71DE839340003EA2A /* PresentHeaderViewController.swift */; }; 21 | 64EE32DA1DE83EB40003EA2A /* ExamplePresentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64EE32D91DE83EB40003EA2A /* ExamplePresentViewController.swift */; }; 22 | 64EE32DC1DE840440003EA2A /* ExamplePushViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64EE32DB1DE840440003EA2A /* ExamplePushViewController.swift */; }; 23 | 65ED4A0F1D6FF8B900B2EE28 /* SJSegmentedScrollView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65ED4A0E1D6FF8B900B2EE28 /* SJSegmentedScrollView.framework */; }; 24 | 65ED4A151D70043600B2EE28 /* image3.JPG in Resources */ = {isa = PBXBuildFile; fileRef = 65ED4A141D70043600B2EE28 /* image3.JPG */; }; 25 | F2438B1AEF5EEE18592D14BD /* Pods_SJSegmentedScrollViewDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 220B06FF892F6EAAE77A7744 /* Pods_SJSegmentedScrollViewDemo.framework */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 0B0C4A782283DF9D00D8749A /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/LaunchScreen.strings; sourceTree = ""; }; 30 | 0B0C4A792283DF9D00D8749A /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Main.strings; sourceTree = ""; }; 31 | 220B06FF892F6EAAE77A7744 /* Pods_SJSegmentedScrollViewDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SJSegmentedScrollViewDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 46468A5FF1343D6897EF4F74 /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SJSegmentedScrollViewDemo.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.debug.xcconfig"; sourceTree = ""; }; 33 | 607FACD01AFB9204008FA782 /* SJSegmentedScrollViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SJSegmentedScrollViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 6487422F1DAE2D8100E76916 /* CollectionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewController.swift; sourceTree = ""; }; 35 | 64A0353E1D4893620068BE28 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = ""; }; 36 | 64A4215A1D3D4543009BFBFE /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 64A4215C1D3D4543009BFBFE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 38 | 64A4215E1D3D4543009BFBFE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | 64A421601D3D4543009BFBFE /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 40 | 64A421611D3D4543009BFBFE /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 64A421631D3D4543009BFBFE /* FirstTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FirstTableViewController.swift; sourceTree = ""; }; 42 | 64A421641D3D4543009BFBFE /* HeaderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderViewController.swift; sourceTree = ""; }; 43 | 64A421651D3D4543009BFBFE /* SecondViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SecondViewController.swift; sourceTree = ""; }; 44 | 64A421661D3D4543009BFBFE /* ThirdViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThirdViewController.swift; sourceTree = ""; }; 45 | 64A421671D3D4543009BFBFE /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 46 | 64EE32D71DE839340003EA2A /* PresentHeaderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PresentHeaderViewController.swift; sourceTree = ""; }; 47 | 64EE32D91DE83EB40003EA2A /* ExamplePresentViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplePresentViewController.swift; sourceTree = ""; }; 48 | 64EE32DB1DE840440003EA2A /* ExamplePushViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExamplePushViewController.swift; sourceTree = ""; }; 49 | 65D108D5120DF23EBFD42193 /* SJSegmentedScrollView.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = SJSegmentedScrollView.podspec; path = ../SJSegmentedScrollView.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 50 | 65ED4A0E1D6FF8B900B2EE28 /* SJSegmentedScrollView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SJSegmentedScrollView.framework; path = "../../../../Library/Developer/Xcode/DerivedData/SJSegmentedScrollViewDemo-bcsxqnqsrcwiyabnptjxeyzbzldf/Build/Products/Debug-iphonesimulator/SJSegmentedScrollView/SJSegmentedScrollView.framework"; sourceTree = ""; }; 51 | 65ED4A141D70043600B2EE28 /* image3.JPG */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = image3.JPG; sourceTree = ""; }; 52 | 81D33DFEACCD76037A928394 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SJSegmentedScrollViewDemo.release.xcconfig"; path = "Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo.release.xcconfig"; sourceTree = ""; }; 53 | BFD50314B40DA82219AAC1C3 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 54 | C05021CD10857241E6264427 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | 65ED4A0F1D6FF8B900B2EE28 /* SJSegmentedScrollView.framework in Frameworks */, 63 | F2438B1AEF5EEE18592D14BD /* Pods_SJSegmentedScrollViewDemo.framework in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | 566D9E804771E7D0235444FE /* Frameworks */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 65ED4A0E1D6FF8B900B2EE28 /* SJSegmentedScrollView.framework */, 74 | 220B06FF892F6EAAE77A7744 /* Pods_SJSegmentedScrollViewDemo.framework */, 75 | ); 76 | name = Frameworks; 77 | sourceTree = ""; 78 | }; 79 | 607FACC71AFB9204008FA782 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 83 | 64A421591D3D4543009BFBFE /* SJSegmentedScrollViewDemo */, 84 | 607FACD11AFB9204008FA782 /* Products */, 85 | C8A978C4EAAE6070D1942368 /* Pods */, 86 | 566D9E804771E7D0235444FE /* Frameworks */, 87 | ); 88 | sourceTree = ""; 89 | }; 90 | 607FACD11AFB9204008FA782 /* Products */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 607FACD01AFB9204008FA782 /* SJSegmentedScrollViewDemo.app */, 94 | ); 95 | name = Products; 96 | sourceTree = ""; 97 | }; 98 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 65D108D5120DF23EBFD42193 /* SJSegmentedScrollView.podspec */, 102 | BFD50314B40DA82219AAC1C3 /* README.md */, 103 | 64A0353E1D4893620068BE28 /* CHANGELOG.md */, 104 | C05021CD10857241E6264427 /* LICENSE */, 105 | ); 106 | name = "Podspec Metadata"; 107 | sourceTree = ""; 108 | }; 109 | 64A421591D3D4543009BFBFE /* SJSegmentedScrollViewDemo */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 64A4215A1D3D4543009BFBFE /* AppDelegate.swift */, 113 | 64A4215B1D3D4543009BFBFE /* LaunchScreen.xib */, 114 | 64A4215D1D3D4543009BFBFE /* Main.storyboard */, 115 | 65ED4A141D70043600B2EE28 /* image3.JPG */, 116 | 64A421601D3D4543009BFBFE /* Images.xcassets */, 117 | 64A421611D3D4543009BFBFE /* Info.plist */, 118 | 64A421621D3D4543009BFBFE /* ViewControllers */, 119 | ); 120 | path = SJSegmentedScrollViewDemo; 121 | sourceTree = ""; 122 | }; 123 | 64A421621D3D4543009BFBFE /* ViewControllers */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | 64A421631D3D4543009BFBFE /* FirstTableViewController.swift */, 127 | 64A421641D3D4543009BFBFE /* HeaderViewController.swift */, 128 | 64A421651D3D4543009BFBFE /* SecondViewController.swift */, 129 | 64A421661D3D4543009BFBFE /* ThirdViewController.swift */, 130 | 64A421671D3D4543009BFBFE /* ViewController.swift */, 131 | 6487422F1DAE2D8100E76916 /* CollectionViewController.swift */, 132 | 64EE32D71DE839340003EA2A /* PresentHeaderViewController.swift */, 133 | 64EE32D91DE83EB40003EA2A /* ExamplePresentViewController.swift */, 134 | 64EE32DB1DE840440003EA2A /* ExamplePushViewController.swift */, 135 | ); 136 | path = ViewControllers; 137 | sourceTree = ""; 138 | }; 139 | C8A978C4EAAE6070D1942368 /* Pods */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 46468A5FF1343D6897EF4F74 /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */, 143 | 81D33DFEACCD76037A928394 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */, 144 | ); 145 | name = Pods; 146 | sourceTree = ""; 147 | }; 148 | /* End PBXGroup section */ 149 | 150 | /* Begin PBXNativeTarget section */ 151 | 607FACCF1AFB9204008FA782 /* SJSegmentedScrollViewDemo */ = { 152 | isa = PBXNativeTarget; 153 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SJSegmentedScrollViewDemo" */; 154 | buildPhases = ( 155 | 16B400BC8D79C6EAC9076D7A /* [CP] Check Pods Manifest.lock */, 156 | 607FACCC1AFB9204008FA782 /* Sources */, 157 | 607FACCD1AFB9204008FA782 /* Frameworks */, 158 | 607FACCE1AFB9204008FA782 /* Resources */, 159 | B6C75E8006EC9F6B81B5FDB0 /* [CP] Embed Pods Frameworks */, 160 | ); 161 | buildRules = ( 162 | ); 163 | dependencies = ( 164 | ); 165 | name = SJSegmentedScrollViewDemo; 166 | productName = SJSegmentedScrollView; 167 | productReference = 607FACD01AFB9204008FA782 /* SJSegmentedScrollViewDemo.app */; 168 | productType = "com.apple.product-type.application"; 169 | }; 170 | /* End PBXNativeTarget section */ 171 | 172 | /* Begin PBXProject section */ 173 | 607FACC81AFB9204008FA782 /* Project object */ = { 174 | isa = PBXProject; 175 | attributes = { 176 | LastSwiftUpdateCheck = 0730; 177 | LastUpgradeCheck = 1000; 178 | ORGANIZATIONNAME = CocoaPods; 179 | TargetAttributes = { 180 | 607FACCF1AFB9204008FA782 = { 181 | CreatedOnToolsVersion = 6.3.1; 182 | DevelopmentTeam = 5DYFD9UMYF; 183 | LastSwiftMigration = 1010; 184 | }; 185 | }; 186 | }; 187 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SJSegmentedScrollViewDemo" */; 188 | compatibilityVersion = "Xcode 9.3"; 189 | developmentRegion = English; 190 | hasScannedForEncodings = 0; 191 | knownRegions = ( 192 | en, 193 | Base, 194 | ); 195 | mainGroup = 607FACC71AFB9204008FA782; 196 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 197 | projectDirPath = ""; 198 | projectRoot = ""; 199 | targets = ( 200 | 607FACCF1AFB9204008FA782 /* SJSegmentedScrollViewDemo */, 201 | ); 202 | }; 203 | /* End PBXProject section */ 204 | 205 | /* Begin PBXResourcesBuildPhase section */ 206 | 607FACCE1AFB9204008FA782 /* Resources */ = { 207 | isa = PBXResourcesBuildPhase; 208 | buildActionMask = 2147483647; 209 | files = ( 210 | 64A421691D3D4543009BFBFE /* LaunchScreen.xib in Resources */, 211 | 64A4216C1D3D4543009BFBFE /* Images.xcassets in Resources */, 212 | 65ED4A151D70043600B2EE28 /* image3.JPG in Resources */, 213 | 64A4216A1D3D4543009BFBFE /* Main.storyboard in Resources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXResourcesBuildPhase section */ 218 | 219 | /* Begin PBXShellScriptBuildPhase section */ 220 | 16B400BC8D79C6EAC9076D7A /* [CP] Check Pods Manifest.lock */ = { 221 | isa = PBXShellScriptBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | inputPaths = ( 226 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 227 | "${PODS_ROOT}/Manifest.lock", 228 | ); 229 | name = "[CP] Check Pods Manifest.lock"; 230 | outputPaths = ( 231 | "$(DERIVED_FILE_DIR)/Pods-SJSegmentedScrollViewDemo-checkManifestLockResult.txt", 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | shellPath = /bin/sh; 235 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 236 | showEnvVarsInLog = 0; 237 | }; 238 | B6C75E8006EC9F6B81B5FDB0 /* [CP] Embed Pods Frameworks */ = { 239 | isa = PBXShellScriptBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | ); 243 | inputPaths = ( 244 | "${SRCROOT}/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-frameworks.sh", 245 | "${BUILT_PRODUCTS_DIR}/SJSegmentedScrollView/SJSegmentedScrollView.framework", 246 | ); 247 | name = "[CP] Embed Pods Frameworks"; 248 | outputPaths = ( 249 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SJSegmentedScrollView.framework", 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | shellPath = /bin/sh; 253 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SJSegmentedScrollViewDemo/Pods-SJSegmentedScrollViewDemo-frameworks.sh\"\n"; 254 | showEnvVarsInLog = 0; 255 | }; 256 | /* End PBXShellScriptBuildPhase section */ 257 | 258 | /* Begin PBXSourcesBuildPhase section */ 259 | 607FACCC1AFB9204008FA782 /* Sources */ = { 260 | isa = PBXSourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | 64A421721D3D4543009BFBFE /* ViewController.swift in Sources */, 264 | 64EE32D81DE839340003EA2A /* PresentHeaderViewController.swift in Sources */, 265 | 64A421701D3D4543009BFBFE /* SecondViewController.swift in Sources */, 266 | 64A4216E1D3D4543009BFBFE /* FirstTableViewController.swift in Sources */, 267 | 64A421711D3D4543009BFBFE /* ThirdViewController.swift in Sources */, 268 | 648742301DAE2D8100E76916 /* CollectionViewController.swift in Sources */, 269 | 64EE32DA1DE83EB40003EA2A /* ExamplePresentViewController.swift in Sources */, 270 | 64A421681D3D4543009BFBFE /* AppDelegate.swift in Sources */, 271 | 64A4216F1D3D4543009BFBFE /* HeaderViewController.swift in Sources */, 272 | 64EE32DC1DE840440003EA2A /* ExamplePushViewController.swift in Sources */, 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin PBXVariantGroup section */ 279 | 64A4215B1D3D4543009BFBFE /* LaunchScreen.xib */ = { 280 | isa = PBXVariantGroup; 281 | children = ( 282 | 64A4215C1D3D4543009BFBFE /* Base */, 283 | 0B0C4A782283DF9D00D8749A /* ar */, 284 | ); 285 | name = LaunchScreen.xib; 286 | sourceTree = ""; 287 | }; 288 | 64A4215D1D3D4543009BFBFE /* Main.storyboard */ = { 289 | isa = PBXVariantGroup; 290 | children = ( 291 | 64A4215E1D3D4543009BFBFE /* Base */, 292 | 0B0C4A792283DF9D00D8749A /* ar */, 293 | ); 294 | name = Main.storyboard; 295 | sourceTree = ""; 296 | }; 297 | /* End PBXVariantGroup section */ 298 | 299 | /* Begin XCBuildConfiguration section */ 300 | 607FACED1AFB9204008FA782 /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ALWAYS_SEARCH_USER_PATHS = NO; 304 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_MODULES = YES; 308 | CLANG_ENABLE_OBJC_ARC = YES; 309 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 310 | CLANG_WARN_BOOL_CONVERSION = YES; 311 | CLANG_WARN_COMMA = YES; 312 | CLANG_WARN_CONSTANT_CONVERSION = YES; 313 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 314 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 315 | CLANG_WARN_EMPTY_BODY = YES; 316 | CLANG_WARN_ENUM_CONVERSION = YES; 317 | CLANG_WARN_INFINITE_RECURSION = YES; 318 | CLANG_WARN_INT_CONVERSION = YES; 319 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 320 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 321 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 323 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 324 | CLANG_WARN_STRICT_PROTOTYPES = YES; 325 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 326 | CLANG_WARN_UNREACHABLE_CODE = YES; 327 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 328 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 329 | COPY_PHASE_STRIP = NO; 330 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 331 | ENABLE_STRICT_OBJC_MSGSEND = YES; 332 | ENABLE_TESTABILITY = YES; 333 | GCC_C_LANGUAGE_STANDARD = gnu99; 334 | GCC_DYNAMIC_NO_PIC = NO; 335 | GCC_NO_COMMON_BLOCKS = YES; 336 | GCC_OPTIMIZATION_LEVEL = 0; 337 | GCC_PREPROCESSOR_DEFINITIONS = ( 338 | "DEBUG=1", 339 | "$(inherited)", 340 | ); 341 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNDECLARED_SELECTOR = YES; 345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 346 | GCC_WARN_UNUSED_FUNCTION = YES; 347 | GCC_WARN_UNUSED_VARIABLE = YES; 348 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 349 | MTL_ENABLE_DEBUG_INFO = YES; 350 | ONLY_ACTIVE_ARCH = YES; 351 | SDKROOT = iphoneos; 352 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 353 | }; 354 | name = Debug; 355 | }; 356 | 607FACEE1AFB9204008FA782 /* Release */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALWAYS_SEARCH_USER_PATHS = NO; 360 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 361 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 362 | CLANG_CXX_LIBRARY = "libc++"; 363 | CLANG_ENABLE_MODULES = YES; 364 | CLANG_ENABLE_OBJC_ARC = YES; 365 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 366 | CLANG_WARN_BOOL_CONVERSION = YES; 367 | CLANG_WARN_COMMA = YES; 368 | CLANG_WARN_CONSTANT_CONVERSION = YES; 369 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 371 | CLANG_WARN_EMPTY_BODY = YES; 372 | CLANG_WARN_ENUM_CONVERSION = YES; 373 | CLANG_WARN_INFINITE_RECURSION = YES; 374 | CLANG_WARN_INT_CONVERSION = YES; 375 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 376 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 377 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 379 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 380 | CLANG_WARN_STRICT_PROTOTYPES = YES; 381 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 382 | CLANG_WARN_UNREACHABLE_CODE = YES; 383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 384 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 385 | COPY_PHASE_STRIP = NO; 386 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 387 | ENABLE_NS_ASSERTIONS = NO; 388 | ENABLE_STRICT_OBJC_MSGSEND = YES; 389 | GCC_C_LANGUAGE_STANDARD = gnu99; 390 | GCC_NO_COMMON_BLOCKS = YES; 391 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 392 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 393 | GCC_WARN_UNDECLARED_SELECTOR = YES; 394 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 395 | GCC_WARN_UNUSED_FUNCTION = YES; 396 | GCC_WARN_UNUSED_VARIABLE = YES; 397 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 398 | MTL_ENABLE_DEBUG_INFO = NO; 399 | SDKROOT = iphoneos; 400 | VALIDATE_PRODUCT = YES; 401 | }; 402 | name = Release; 403 | }; 404 | 607FACF01AFB9204008FA782 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | baseConfigurationReference = 46468A5FF1343D6897EF4F74 /* Pods-SJSegmentedScrollViewDemo.debug.xcconfig */; 407 | buildSettings = { 408 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 409 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 410 | DEVELOPMENT_TEAM = 5DYFD9UMYF; 411 | INFOPLIST_FILE = SJSegmentedScrollViewDemo/Info.plist; 412 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 413 | LD_RUNPATH_SEARCH_PATHS = ( 414 | "$(inherited)", 415 | "@executable_path/Frameworks", 416 | ); 417 | MODULE_NAME = ExampleApp; 418 | PRODUCT_BUNDLE_IDENTIFIER = com.qburst.SJSegmentedScrollViewDemo; 419 | PRODUCT_NAME = SJSegmentedScrollViewDemo; 420 | PROVISIONING_PROFILE = ""; 421 | SWIFT_VERSION = 4.2; 422 | TARGETED_DEVICE_FAMILY = "1,2"; 423 | }; 424 | name = Debug; 425 | }; 426 | 607FACF11AFB9204008FA782 /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | baseConfigurationReference = 81D33DFEACCD76037A928394 /* Pods-SJSegmentedScrollViewDemo.release.xcconfig */; 429 | buildSettings = { 430 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | DEVELOPMENT_TEAM = 5DYFD9UMYF; 433 | INFOPLIST_FILE = SJSegmentedScrollViewDemo/Info.plist; 434 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 435 | LD_RUNPATH_SEARCH_PATHS = ( 436 | "$(inherited)", 437 | "@executable_path/Frameworks", 438 | ); 439 | MODULE_NAME = ExampleApp; 440 | PRODUCT_BUNDLE_IDENTIFIER = com.qburst.SJSegmentedScrollViewDemo; 441 | PRODUCT_NAME = SJSegmentedScrollViewDemo; 442 | PROVISIONING_PROFILE = ""; 443 | SWIFT_COMPILATION_MODE = wholemodule; 444 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 445 | SWIFT_VERSION = 4.2; 446 | TARGETED_DEVICE_FAMILY = "1,2"; 447 | }; 448 | name = Release; 449 | }; 450 | /* End XCBuildConfiguration section */ 451 | 452 | /* Begin XCConfigurationList section */ 453 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "SJSegmentedScrollViewDemo" */ = { 454 | isa = XCConfigurationList; 455 | buildConfigurations = ( 456 | 607FACED1AFB9204008FA782 /* Debug */, 457 | 607FACEE1AFB9204008FA782 /* Release */, 458 | ); 459 | defaultConfigurationIsVisible = 0; 460 | defaultConfigurationName = Release; 461 | }; 462 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "SJSegmentedScrollViewDemo" */ = { 463 | isa = XCConfigurationList; 464 | buildConfigurations = ( 465 | 607FACF01AFB9204008FA782 /* Debug */, 466 | 607FACF11AFB9204008FA782 /* Release */, 467 | ); 468 | defaultConfigurationIsVisible = 0; 469 | defaultConfigurationName = Release; 470 | }; 471 | /* End XCConfigurationList section */ 472 | }; 473 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 474 | } 475 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcodeproj/xcshareddata/xcschemes/SJSegmentedScrollViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 55 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 76 | 82 | 83 | 84 | 85 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 06/10/2016. 6 | // Copyright (c) 2016 Subins Jose. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | fileprivate func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [AnyHashable: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/CollectionViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionViewController.swift 3 | // SJSegmentedScrollViewDemo 4 | // 5 | // Created by Subins on 12/10/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SJSegmentedScrollView 11 | 12 | private let reuseIdentifier = "CollectionCellIdentifier" 13 | 14 | class CollectionViewController: UICollectionViewController { 15 | 16 | let colors = [UIColor.red, UIColor.gray, 17 | UIColor.green, 18 | UIColor.yellow, 19 | UIColor.orange, 20 | UIColor.brown, 21 | UIColor.purple] 22 | 23 | override func viewDidLoad() { 24 | super.viewDidLoad() 25 | 26 | // Register cell classes 27 | self.collectionView!.register(UICollectionViewCell.self, 28 | forCellWithReuseIdentifier: reuseIdentifier) 29 | } 30 | 31 | override func collectionView(_ collectionView: UICollectionView, 32 | numberOfItemsInSection section: Int) -> Int { 33 | return 25 34 | } 35 | 36 | override func collectionView(_ collectionView: UICollectionView, 37 | cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 38 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, 39 | for: indexPath) 40 | 41 | let colorIndex = indexPath.row % colors.count 42 | let color = colors[colorIndex] 43 | cell.backgroundColor = color 44 | 45 | return cell 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/ExamplePresentViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExamplePresentViewController.swift 3 | // SJSegmentedScrollViewDemo 4 | // 5 | // Created by Subins on 25/11/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SJSegmentedScrollView 11 | 12 | class ExamplePresentViewController: UIViewController { 13 | 14 | @IBAction func present(_ sender: AnyObject) { 15 | 16 | if let storyboard = self.storyboard { 17 | 18 | let headerViewController = storyboard 19 | .instantiateViewController(withIdentifier: "PresentHeader") 20 | 21 | let firstViewController = storyboard 22 | .instantiateViewController(withIdentifier: "FirstTableViewController") 23 | firstViewController.title = "First" 24 | 25 | let secondViewController = storyboard 26 | .instantiateViewController(withIdentifier: "SecondViewController") 27 | secondViewController.title = "Second" 28 | 29 | let segmentController = SJSegmentedViewController() 30 | segmentController.headerViewController = headerViewController 31 | segmentController.segmentControllers = [firstViewController, 32 | secondViewController] 33 | segmentController.headerViewHeight = 200.0 34 | segmentController.headerViewOffsetHeight = 31.0 35 | segmentController.segmentTitleColor = .lightGray 36 | segmentController.segmentSelectedTitleColor = .black 37 | 38 | present(segmentController, animated: true, completion: nil) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/ExamplePushViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExamplePushViewController.swift 3 | // SJSegmentedScrollViewDemo 4 | // 5 | // Created by Subins on 25/11/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SJSegmentedScrollView 11 | 12 | class ExamplePushViewController: UIViewController { 13 | 14 | @IBAction func push(_ sender: AnyObject) { 15 | 16 | if let storyboard = self.storyboard { 17 | 18 | let headerViewController = storyboard 19 | .instantiateViewController(withIdentifier: "HeaderViewController1") 20 | 21 | let firstViewController = storyboard 22 | .instantiateViewController(withIdentifier: "FirstTableViewController") 23 | firstViewController.title = "First" 24 | 25 | let secondViewController = storyboard 26 | .instantiateViewController(withIdentifier: "SecondViewController") 27 | secondViewController.title = "Second" 28 | 29 | let segmentController = SJSegmentedViewController() 30 | segmentController.headerViewController = headerViewController 31 | segmentController.segmentControllers = [firstViewController, 32 | secondViewController] 33 | segmentController.headerViewHeight = 200.0 34 | navigationController?.pushViewController(segmentController, animated: true) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/FirstTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstTableViewController.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 13/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class FirstTableViewController: UITableViewController { 12 | 13 | // MARK: - Table view data source 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | refreshControl?.addTarget(self, 19 | action: #selector(handleRefresh(_:)), 20 | for: UIControl.Event.valueChanged) 21 | } 22 | 23 | @objc func handleRefresh(_ refreshControl: UIRefreshControl) { 24 | 25 | self.perform(#selector(self.endRefresh), with: nil, afterDelay: 1.0) 26 | } 27 | 28 | @objc func endRefresh() { 29 | 30 | refreshControl?.endRefreshing() 31 | } 32 | 33 | override func numberOfSections(in tableView: UITableView) -> Int { 34 | return 1 35 | } 36 | 37 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 38 | return 25 39 | } 40 | 41 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 42 | let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) 43 | 44 | cell.textLabel?.text = "Row " + String((indexPath as NSIndexPath).row) 45 | 46 | return cell 47 | } 48 | 49 | func viewForObserve() -> UIView{ 50 | 51 | return self.tableView 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/HeaderViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderViewController.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 13/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class HeaderViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | // Do any additional setup after loading the view. 17 | } 18 | 19 | override func didReceiveMemoryWarning() { 20 | super.didReceiveMemoryWarning() 21 | // Dispose of any resources that can be recreated. 22 | } 23 | 24 | @IBAction func headerViewAction(_ sender: AnyObject) { 25 | 26 | if navigationController?.isNavigationBarHidden == false { 27 | let viewController = self.storyboard? 28 | .instantiateViewController(withIdentifier: "HeaderDetailViewController") 29 | self.parent?.navigationController?.pushViewController(viewController!, 30 | animated: true) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/PresentHeaderViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PresentHeaderViewController.swift 3 | // SJSegmentedScrollViewDemo 4 | // 5 | // Created by Subins on 25/11/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class PresentHeaderViewController: UIViewController { 12 | 13 | @IBAction func cancel(_ sender: AnyObject) { 14 | dismiss(animated: true, completion: nil) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // SecondViewController.swift 4 | // SJSegmentedScrollView 5 | // 6 | // Created by Subins Jose on 13/06/16. 7 | // Copyright © 2016 Subins Jose. All rights reserved. 8 | // 9 | 10 | import UIKit 11 | import SJSegmentedScrollView 12 | 13 | class SecondViewController: UIViewController { 14 | 15 | @IBOutlet weak var customTableView: UITableView! 16 | } 17 | 18 | extension SecondViewController: UITableViewDataSource { 19 | 20 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 21 | 22 | return 20 23 | } 24 | 25 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 26 | let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier", for: indexPath) 27 | 28 | cell.textLabel?.text = "Second View Row " + String((indexPath as NSIndexPath).row) 29 | 30 | return cell 31 | } 32 | } 33 | 34 | extension SecondViewController: SJSegmentedViewControllerViewSource { 35 | 36 | func viewForSegmentControllerToObserveContentOffsetChange() -> UIView { 37 | 38 | return customTableView 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/ThirdViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins on 13/07/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SJSegmentedScrollView 11 | 12 | class ThirdViewController: UIViewController { 13 | 14 | var loadViewController: ((_ index: Int) -> Void)? 15 | 16 | @IBAction func loadSegment(_ sender: Any) { 17 | 18 | if loadViewController != nil { 19 | loadViewController!(0) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ViewControllers/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 06/10/2016. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SJSegmentedScrollView 11 | 12 | class ViewController: SJSegmentedViewController { 13 | 14 | var selectedSegment: SJSegmentTab? 15 | 16 | override func viewDidLoad() { 17 | if let storyboard = self.storyboard { 18 | 19 | let headerController = storyboard 20 | .instantiateViewController(withIdentifier: "HeaderViewController1") 21 | 22 | let firstViewController = storyboard 23 | .instantiateViewController(withIdentifier: "FirstTableViewController") 24 | firstViewController.title = "First" 25 | 26 | let secondViewController = storyboard 27 | .instantiateViewController(withIdentifier: "SecondViewController") 28 | secondViewController.title = "Second" 29 | 30 | let thirdViewController = storyboard 31 | .instantiateViewController(withIdentifier: "ThirdViewController") as? ThirdViewController 32 | thirdViewController?.title = "Third" 33 | thirdViewController?.loadViewController = { (index) in 34 | self.setSelectedSegmentAt(index, animated: true) 35 | } 36 | 37 | let fourthViewController = storyboard 38 | .instantiateViewController(withIdentifier: "CollectionViewIdentifier") 39 | fourthViewController.title = "Fourth" 40 | 41 | headerViewController = headerController 42 | segmentControllers = [firstViewController, 43 | secondViewController, 44 | thirdViewController!, 45 | fourthViewController] 46 | headerViewHeight = 200 47 | selectedSegmentViewHeight = 5.0 48 | headerViewOffsetHeight = 31.0 49 | segmentTitleColor = .gray 50 | selectedSegmentViewColor = .red 51 | segmentShadow = SJShadow.light() 52 | showsHorizontalScrollIndicator = false 53 | showsVerticalScrollIndicator = false 54 | segmentBounces = false 55 | delegate = self 56 | } 57 | 58 | title = "Segment" 59 | super.viewDidLoad() 60 | } 61 | 62 | func getSegmentTabWithImage(_ imageName: String) -> UIView { 63 | 64 | let view = UIImageView() 65 | view.frame.size.width = 100 66 | view.image = UIImage(named: imageName) 67 | view.contentMode = .scaleAspectFit 68 | view.backgroundColor = .white 69 | return view 70 | } 71 | } 72 | 73 | extension ViewController: SJSegmentedViewControllerDelegate { 74 | 75 | func didMoveToPage(_ controller: UIViewController, segment: SJSegmentTab?, index: Int) { 76 | 77 | if selectedSegment != nil { 78 | selectedSegment?.titleColor(.lightGray) 79 | } 80 | 81 | if segments.count > 0 { 82 | 83 | selectedSegment = segments[index] 84 | selectedSegment?.titleColor(.red) 85 | } 86 | } 87 | } 88 | 89 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ar.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UILabel"; text = "Copyright © 2017 Subins Jose. All rights reserved."; ObjectID = "8ie-xW-0ye"; */ 3 | "8ie-xW-0ye.text" = "Copyright © 2017 Subins Jose. All rights reserved."; 4 | 5 | /* Class = "UILabel"; text = "SJSegmentedScrollViewDemo"; ObjectID = "kId-c2-rCX"; */ 6 | "kId-c2-rCX.text" = "SJSegmentedScrollViewDemo"; 7 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/ar.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UISegmentedControl"; 9mf-u0-OpS.segmentTitles[0] = "First"; ObjectID = "9mf-u0-OpS"; */ 3 | "9mf-u0-OpS.segmentTitles[0]" = "First"; 4 | 5 | /* Class = "UISegmentedControl"; 9mf-u0-OpS.segmentTitles[1] = "Second"; ObjectID = "9mf-u0-OpS"; */ 6 | "9mf-u0-OpS.segmentTitles[1]" = "Second"; 7 | 8 | /* Class = "UILabel"; text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; ObjectID = "BUI-bM-XCd"; */ 9 | "BUI-bM-XCd.text" = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; 10 | 11 | /* Class = "UIButton"; normalTitle = "Cancel"; ObjectID = "C97-f0-B42"; */ 12 | "C97-f0-B42.normalTitle" = "Cancel"; 13 | 14 | /* Class = "UIButton"; normalTitle = "Push"; ObjectID = "CpQ-4E-sGP"; */ 15 | "CpQ-4E-sGP.normalTitle" = "Push"; 16 | 17 | /* Class = "UITabBarItem"; title = "Push"; ObjectID = "EC0-ms-bJ7"; */ 18 | "EC0-ms-bJ7.title" = "Push"; 19 | 20 | /* Class = "UIButton"; normalTitle = "Present"; ObjectID = "H55-lF-ie4"; */ 21 | "H55-lF-ie4.normalTitle" = "Present"; 22 | 23 | /* Class = "UITabBarItem"; title = "SJSegment"; ObjectID = "I96-gV-iSQ"; */ 24 | "I96-gV-iSQ.title" = "SJSegment"; 25 | 26 | /* Class = "UIButton"; normalTitle = "Load First"; ObjectID = "hDS-kp-3Ss"; */ 27 | "hDS-kp-3Ss.normalTitle" = "Load First"; 28 | 29 | /* Class = "UITabBarItem"; title = "Present"; ObjectID = "plf-fs-OkD"; */ 30 | "plf-fs-OkD.title" = "Present"; 31 | -------------------------------------------------------------------------------- /Example/SJSegmentedScrollViewDemo/image3.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subinspathilettu/SJSegmentedViewController/0aeb563c79266f39d0464dc90906b1d31d669f2c/Example/SJSegmentedScrollViewDemo/image3.JPG -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Subins Jose 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SJSegmentedScrollView 2 | 3 | [![CI Status](https://img.shields.io/travis/subinspathilettu/SJSegmentedViewController.svg?style=flat)](https://travis-ci.org/subinspathilettu/SJSegmentedViewController) 4 | [![Version](https://img.shields.io/cocoapods/v/SJSegmentedScrollView.svg?style=flat)](http://cocoapods.org/pods/SJSegmentedScrollView) 5 | [![License](https://img.shields.io/cocoapods/l/SJSegmentedScrollView.svg?style=flat)](http://cocoapods.org/pods/SJSegmentedScrollView) 6 | [![Platform](https://img.shields.io/cocoapods/p/SJSegmentedScrollView.svg?style=flat)](http://cocoapods.org/pods/SJSegmentedScrollView) 7 | 8 | SJSegmentedScrollView is a light weight generic controller written in Swift. Its a simple customizable controller were you can integrate any number of ViewControllers into a segmented controller with a header view controller. 9 | 10 | ![demo](https://github.com/subinspathilettu/SJSegmentedViewController/blob/master/new_demo.gif) 11 | 12 | #### Highlights 13 | 14 | - [x] Horizontal scrolling for switching from segment to segment. 15 | - [x] Vertical scrolling for contents. 16 | - [x] Single header view for all segments. 17 | - [x] Title, segment selection color, header size, segment height etc can be customized accordingly. 18 | - [x] Supports Swift and Objective-C. 19 | - [x] Supports multitasking. 20 | - [x] Supports Refreshcontrol and custom pull to refresh libs. 21 | 22 | ## Installation 23 | 24 | ### CocoaPods: 25 | 26 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: 27 | 28 | ```bash 29 | $ gem install cocoapods 30 | ``` 31 | 32 | To integrate `SJSegmentedViewController` into your Xcode project using CocoaPods, specify it in your Podfile: 33 | ```ruby 34 | 35 | source 'https://github.com/CocoaPods/Specs.git' 36 | platform :ios, '9.0' 37 | use_frameworks! 38 | 39 | target '' do 40 | pod ’SJSegmentedScrollView’, ‘1.3.8' 41 | end 42 | ``` 43 | 44 | Then, run the following command: 45 | 46 | ```bash 47 | $ pod install 48 | ``` 49 | 50 | ### Manually: 51 | 52 | * Download SJSegmentedViewController. 53 | * Drag and drop SJSegmentedViewController directory to your project 54 | 55 | ## Requirements 56 | 57 | - Xcode 7.3+ 58 | - iOS 9.0+ 59 | - Swift 2.3+ 60 | 61 | ## Communication 62 | 63 | - If you **found a bug**, open an issue. 64 | - If you **have a feature request**, open an issue. 65 | - If you **want to contribute**, submit a pull request. 66 | 67 | ## Donation 68 | 69 | If this project help you reduce time to develop, you can give me a beer 🍺 :) 70 | 71 | [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.me/SubinsJose) 72 | 73 | ## Usage 74 | 75 | Here is how you can use `SJSegmentedViewController`. 76 | 77 | Import SJSegmentedScrollView to your viewcontroller, 78 | 79 | ```swift 80 | import SJSegmentedScrollView 81 | ``` 82 | 83 | Then add any number of ViewControllers into `SJSegmentedViewController`. All you have to do is as follows. 84 | 85 | ```swift 86 | if let storyboard = self.storyboard { 87 | 88 | let headerViewController = storyboard 89 | .instantiateViewControllerWithIdentifier("HeaderViewController") 90 | 91 | let firstViewController = storyboard 92 | .instantiateViewControllerWithIdentifier("FirstTableViewController") 93 | firstViewController.title = "First" 94 | 95 | let secondViewController = storyboard 96 | .instantiateViewControllerWithIdentifier("SecondTableViewController") 97 | secondViewController.title = "Second" 98 | 99 | let thirdViewController = storyboard 100 | .instantiateViewControllerWithIdentifier("ThirdTableViewController") 101 | thirdViewController.title = "Third" 102 | 103 | let segmentedViewController = SJSegmentedViewController(headerViewController: headerViewController, 104 | segmentControllers: [firstViewController, 105 | secondViewController, 106 | thirdViewController]) 107 | ``` 108 | 109 | * Present ViewController 110 | ```swift 111 | self.presentViewController(segmentedViewController, animated: false, completion: nil) 112 | ``` 113 | 114 | * Push ViewController 115 | ```swift 116 | self.navigationController?.pushViewController(segmentedViewController, 117 | animated: true) 118 | ``` 119 | 120 | * Add Child ViewController 121 | ```swift 122 | addChildViewController(segmentedViewController) 123 | self.view.addSubview(segmentedViewController.view) 124 | segmentedViewController.view.frame = self.view.bounds 125 | segmentedViewController.didMoveToParentViewController(self) 126 | ``` 127 | 128 | ## We upgraded to `Swift 4`. For those who want to use older version, 129 | 130 | `Swift 3`: ``` pod ’SJSegmentedScrollView’, ‘1.3.6' ``` 131 | 132 | `Swift 2.3`: ``` pod ’SJSegmentedScrollView’, ‘1.3.6' ``` OR 133 | 134 | ```ruby 135 | pod 'SJSegmentedScrollView', :git => 'https://github.com/subinspathilettu/SJSegmentedViewController.git', :tag => 'v1.1.1' 136 | ``` 137 | #### Customize Segement Tab 138 | Defaultly, SJSegmentedScrollView shows the `controller.title` as segments tab. 139 | 140 | ```swift 141 | firstViewController.title = "First" 142 | ``` 143 | 144 | You can customize the segment tab view by providing `controller.navigationItem.titleView`. 145 | 146 | ```swift 147 | // Custom ImageView 148 | let view = UIImageView() 149 | view.frame.size.width = 100 150 | view.image = UIImage(named: imageName) 151 | view.contentMode = .scaleAspectFit 152 | view.backgroundColor = .white 153 | 154 | firstViewController.navigationItem.titleView = view 155 | ``` 156 | 157 | #### Customize your view 158 | By default, SJSegmentedScrollView will observe the default view of viewcontroller for content 159 | changes and makes the scroll effect. If you want to change the default view, implement 160 | `SJSegmentedViewControllerViewSource` and pass your custom view. 161 | 162 | ```swift 163 | func viewForSegmentControllerToObserveContentOffsetChange() -> UIView { 164 | return view 165 | } 166 | ``` 167 | 168 | `SJSegmentedViewControllerDelegate` delegate method which helps to customize segment view by accessing the current segment, index, 169 | etc. 170 | 171 | Note: if there is only one content controller then the segment will be empty. 172 | 173 | ```swift 174 | 175 | segmentedViewController.delegate = self 176 | 177 | extension ViewController: SJSegmentedViewControllerDelegate { 178 | 179 | func didMoveToPage(controller: UIViewController, segment: SJSegmentTab?, index: Int) { 180 | if segmentedViewController.segments.count > 0 { 181 | 182 | let segmentTab = segmentedViewController.segments[index] 183 | segmentTab.titleColor = .yellow 184 | } 185 | } 186 | } 187 | ``` 188 | 189 | You can also customize your controllers by using following properties in `SJSegmentedViewController`. 190 | 191 | ```swift 192 | let segmentedViewController = SJSegmentedViewController() 193 | 194 | //Set height for headerview. 195 | segmentedViewController.headerViewHeight = 250.0 196 | 197 | //Set height for segmentview. 198 | segmentedViewController.segmentViewHeight = 60.0 199 | 200 | //Set color for selected segment. 201 | segmentedViewController.selectedSegmentViewColor = UIColor.redColor() 202 | 203 | //Set color for segment title. 204 | segmentedViewController.segmentTitleColor = UIColor.blackColor() 205 | 206 | //Set background color for segmentview. 207 | segmentedViewController.segmentBackgroundColor = UIColor.whiteColor() 208 | 209 | //Set shadow for segmentview. 210 | segmentedViewController.segmentShadow = SJShadow.light() 211 | 212 | //Set bounce for segmentview. 213 | segmentedViewController.segmentBounces = true 214 | 215 | //Set font for segmentview titles. 216 | segmentedViewController.segmentTitleFont = UIFont.systemFontOfSize(14.0) 217 | 218 | //Set height for selected segmentview. 219 | segmentedViewController.selectedSegmentViewHeight = 5.0 220 | 221 | //Set height for headerview to visible after scrolling 222 | segmentedViewController. headerViewOffsetHeight = 10.0 223 | ``` 224 | 225 | #### Change Segment Programmatically 226 | 227 | 228 | To change segment programmatically, use `SJSegmentedViewController` `func setSelectedSegmentAt(_ index: Int, animated: Bool)`. 229 | 230 | ```swift 231 | segmentControl.setSelectedSegmentAt(index, animated: true) 232 | ``` 233 | 234 | ## Author 235 | 236 | Subins Jose, subinsjose@gmail.com 237 | 238 | ## License 239 | 240 | SJSegmentedScrollView is available under the MIT license. See the LICENSE file for more info. 241 | -------------------------------------------------------------------------------- /SJSegmentedScrollView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.platform = :ios 3 | spec.ios.deployment_target = '10.0' 4 | spec.name = 'SJSegmentedScrollView' 5 | spec.summary = 'Custom segmented header scrollview controller.' 6 | spec.requires_arc = true 7 | spec.version = '1.5.0' 8 | spec.license = { :type => 'MIT', :file => 'LICENSE' } 9 | spec.homepage = 'https://github.com/subinspathilettu/SJSegmentedViewController' 10 | spec.author = { 'Subins Jose' => 'subinsjose@gmail.com' } 11 | spec.source = { :git => 'https://github.com/subinspathilettu/SJSegmentedViewController.git', :tag => 'v1.5.0' } 12 | spec.source_files = 'SJSegmentedScrollView/Classes/*.{swift}' 13 | spec.social_media_url = 'https://twitter.com/subinsjose' 14 | spec.framework = "UIKit" 15 | end 16 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subinspathilettu/SJSegmentedViewController/0aeb563c79266f39d0464dc90906b1d31d669f2c/SJSegmentedScrollView/Classes/.gitkeep -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJContentView.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 10/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SJContentView: UIScrollView { 26 | 27 | var pageIndex = 0 28 | var contentViews = [UIView]() 29 | var contentView: UIView! 30 | var contentViewWidthConstraint: NSLayoutConstraint! 31 | var contentSubViewWidthConstraints = [NSLayoutConstraint]() 32 | let animationDuration = 0.3 33 | var didSelectSegmentAtIndex: DidSelectSegmentAtIndex? 34 | 35 | override init(frame: CGRect) { 36 | super.init(frame: frame) 37 | 38 | delegate = self 39 | isPagingEnabled = true 40 | 41 | contentView = UIView() 42 | contentView.translatesAutoresizingMaskIntoConstraints = false 43 | addSubview(contentView) 44 | 45 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[contentView]|", 46 | options: [], 47 | metrics: nil, 48 | views: ["contentView": contentView, "mainView": self]) 49 | addConstraints(horizontalConstraints) 50 | 51 | contentViewWidthConstraint = NSLayoutConstraint(item: contentView, 52 | attribute: .width, 53 | relatedBy: .equal, 54 | toItem: nil, 55 | attribute: .notAnAttribute, 56 | multiplier: 1.0, 57 | constant: 0) 58 | addConstraint(contentViewWidthConstraint) 59 | 60 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[contentView(==mainView)]|", 61 | options: [], 62 | metrics: nil, 63 | views: ["contentView": contentView, "mainView": self]) 64 | addConstraints(verticalConstraints) 65 | } 66 | 67 | func addContentView(_ view: UIView, frame: CGRect) { 68 | 69 | view.translatesAutoresizingMaskIntoConstraints = false 70 | contentView.addSubview(view) 71 | 72 | let width = Int(frame.size.width) 73 | if contentViews.count > 0 { 74 | 75 | let previousView = contentViews.last 76 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[previousView]-0-[view]", 77 | options: [], 78 | metrics: ["xPos": (contentViews.count * width)], 79 | views: ["view": view, "previousView": previousView!]) 80 | contentView.addConstraints(horizontalConstraints) 81 | } else { 82 | 83 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]", 84 | options: [], 85 | metrics: ["xPos": (contentViews.count * width)], 86 | views: ["view": view]) 87 | contentView.addConstraints(horizontalConstraints) 88 | } 89 | 90 | let widthConstraint = NSLayoutConstraint(item: view, 91 | attribute: .width, 92 | relatedBy: .equal, 93 | toItem: nil, 94 | attribute: .notAnAttribute, 95 | multiplier: 1.0, 96 | constant: CGFloat(width)) 97 | contentView.addConstraint(widthConstraint) 98 | contentSubViewWidthConstraints.append(widthConstraint) 99 | 100 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[view]-0-|", 101 | options: [], 102 | metrics: nil, 103 | views: ["view": view]) 104 | contentView.addConstraints(verticalConstraints) 105 | contentViews.append(view) 106 | 107 | contentViewWidthConstraint.constant = CGFloat(contentViews.count) * bounds.width 108 | } 109 | 110 | func updateContentControllersFrame(_ frame: CGRect) { 111 | 112 | let width = frame.size.width 113 | contentViewWidthConstraint.constant = CGFloat(contentViews.count) * width 114 | 115 | for constraint in contentSubViewWidthConstraints { 116 | constraint.constant = width 117 | } 118 | 119 | layoutIfNeeded() 120 | var point = contentOffset 121 | if UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute) == .rightToLeft { 122 | let newIndex = (contentViews.count - pageIndex) - 1 123 | point.x = CGFloat(newIndex) * width 124 | } else { 125 | point.x = CGFloat(pageIndex) * width 126 | } 127 | 128 | setContentOffset(point, animated: true) 129 | } 130 | 131 | required init?(coder aDecoder: NSCoder) { 132 | fatalError("init(coder:) has not been implemented") 133 | } 134 | 135 | func movePageToIndex(_ index: Int, animated: Bool) { 136 | 137 | pageIndex = index 138 | var point = CGPoint.zero 139 | if UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute) == .rightToLeft { 140 | let newIndex = (contentViews.count - index) - 1 141 | point = CGPoint(x: (newIndex * Int(bounds.size.width)), y: 0) 142 | } else { 143 | point = CGPoint(x: (index * Int(bounds.size.width)), y: 0) 144 | } 145 | 146 | if animated == true { 147 | UIView.animate(withDuration: animationDuration) { 148 | self.contentOffset = point 149 | } 150 | } else { 151 | contentOffset = point 152 | } 153 | } 154 | } 155 | 156 | extension SJContentView: UIScrollViewDelegate { 157 | 158 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 159 | pageIndex = Int(contentOffset.x / bounds.size.width) 160 | if UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute) == .rightToLeft { 161 | pageIndex = (contentViews.count - 1) - pageIndex 162 | } 163 | didSelectSegmentAtIndex?(nil, pageIndex, true) 164 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DidChangeSegmentIndex"), 165 | object: pageIndex) 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJSegmentTab.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJSegmentTab.swift 3 | // Pods 4 | // 5 | // Created by Subins on 22/11/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import Foundation 24 | 25 | typealias DidSelectSegmentAtIndex = (_ segment: SJSegmentTab?,_ index: Int,_ animated: Bool) -> Void 26 | 27 | open class SJSegmentTab: UIView { 28 | 29 | let kSegmentViewTagOffset = 100 30 | let button = UIButton(type: .custom) 31 | 32 | var didSelectSegmentAtIndex: DidSelectSegmentAtIndex? 33 | var isSelected = false { 34 | didSet { 35 | button.isSelected = isSelected 36 | } 37 | } 38 | 39 | convenience init(title: String) { 40 | self.init(frame: CGRect.zero) 41 | setTitle(title) 42 | } 43 | 44 | convenience init(view: UIView) { 45 | self.init(frame: CGRect.zero) 46 | 47 | insertSubview(view, at: 0) 48 | view.removeConstraints(view.constraints) 49 | addConstraintsToView(view) 50 | } 51 | 52 | required override public init(frame: CGRect) { 53 | super.init(frame: frame) 54 | 55 | translatesAutoresizingMaskIntoConstraints = false 56 | button.frame = bounds 57 | button.addTarget(self, action: #selector(SJSegmentTab.onSegmentButtonPress(_:)), 58 | for: .touchUpInside) 59 | addSubview(button) 60 | addConstraintsToView(button) 61 | } 62 | 63 | func addConstraintsToView(_ view: UIView) { 64 | 65 | view.translatesAutoresizingMaskIntoConstraints = false 66 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", 67 | options: [], 68 | metrics: nil, 69 | views: ["view": view]) 70 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|", 71 | options: [], 72 | metrics: nil, 73 | views: ["view": view]) 74 | addConstraints(verticalConstraints) 75 | addConstraints(horizontalConstraints) 76 | } 77 | 78 | required public init?(coder aDecoder: NSCoder) { 79 | fatalError("init(coder:) has not been implemented") 80 | } 81 | 82 | open func setTitle(_ title: String) { 83 | 84 | button.setTitle(title, for: .normal) 85 | } 86 | 87 | open func titleColor(_ color: UIColor) { 88 | 89 | button.setTitleColor(color, for: .normal) 90 | } 91 | 92 | open func selectedTitleColor(_ color: UIColor?) { 93 | 94 | button.setTitleColor(color, for: .selected) 95 | } 96 | 97 | open func titleFont(_ font: UIFont) { 98 | 99 | button.titleLabel?.font = font 100 | } 101 | 102 | @objc func onSegmentButtonPress(_ sender: AnyObject) { 103 | let index = tag - kSegmentViewTagOffset 104 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DidChangeSegmentIndex"), 105 | object: index) 106 | didSelectSegmentAtIndex?(self, index, true) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJSegmentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJSegmentView.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 10/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SJSegmentView: UIScrollView { 26 | 27 | var selectedSegmentViewColor: UIColor? { 28 | didSet { 29 | selectedSegmentView?.backgroundColor = selectedSegmentViewColor 30 | } 31 | } 32 | 33 | var titleColor: UIColor? { 34 | didSet { 35 | for segment in segments { 36 | segment.titleColor(titleColor!) 37 | } 38 | } 39 | } 40 | 41 | var selectedTitleColor: UIColor? { 42 | didSet { 43 | for segment in segments { 44 | segment.selectedTitleColor(selectedTitleColor) 45 | } 46 | } 47 | } 48 | 49 | var segmentBackgroundColor: UIColor? { 50 | didSet { 51 | for segment in segments { 52 | segment.backgroundColor = segmentBackgroundColor 53 | } 54 | } 55 | } 56 | 57 | var shadow: SJShadow? { 58 | didSet { 59 | if let shadow = shadow { 60 | layer.shadowOffset = shadow.offset 61 | layer.shadowColor = shadow.color.cgColor 62 | layer.shadowRadius = shadow.radius 63 | layer.shadowOpacity = shadow.opacity 64 | layer.masksToBounds = false; 65 | } 66 | } 67 | } 68 | 69 | var font: UIFont? 70 | var selectedSegmentViewHeight: CGFloat? 71 | let kSegmentViewTagOffset = 100 72 | var segmentViewOffsetWidth: CGFloat = 10.0 73 | var segments = [SJSegmentTab]() 74 | var segmentContentView: UIView? 75 | var didSelectSegmentAtIndex: DidSelectSegmentAtIndex? 76 | var selectedSegmentView: UIView? 77 | var xPosConstraints: NSLayoutConstraint? 78 | var contentViewWidthConstraint: NSLayoutConstraint? 79 | var selectedSegmentViewWidthConstraint: NSLayoutConstraint? 80 | var contentSubViewWidthConstraints = [NSLayoutConstraint]() 81 | var controllers: [UIViewController]? 82 | 83 | var contentView: SJContentView? { 84 | didSet { 85 | contentView!.addObserver(self, 86 | forKeyPath: "contentOffset", 87 | options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old], 88 | context: nil) 89 | } 90 | } 91 | 92 | required override init(frame: CGRect) { 93 | super.init(frame: frame) 94 | 95 | showsHorizontalScrollIndicator = false 96 | showsVerticalScrollIndicator = false 97 | bounces = false 98 | 99 | 100 | NotificationCenter.default.addObserver(self, 101 | selector: #selector(SJSegmentView.didChangeSegmentIndex(_:)), 102 | name: NSNotification.Name("DidChangeSegmentIndex"), 103 | object: nil) 104 | } 105 | 106 | required init?(coder aDecoder: NSCoder) { 107 | fatalError("init(coder:) has not been implemented") 108 | } 109 | 110 | deinit { 111 | contentView!.removeObserver(self, 112 | forKeyPath: "contentOffset", 113 | context: nil) 114 | 115 | NotificationCenter.default.removeObserver(self, 116 | name:NSNotification.Name("DidChangeSegmentIndex"), 117 | object: nil) 118 | } 119 | 120 | @objc func didChangeSegmentIndex(_ notification: Notification) { 121 | 122 | //deselect previous buttons 123 | for button in segments { 124 | button.isSelected = false 125 | } 126 | 127 | // select current button 128 | let index = notification.object as? Int 129 | 130 | if index! < segments.count { 131 | let button = segments[index!] 132 | button.isSelected = true 133 | } 134 | } 135 | 136 | func setSegmentsView(_ frame: CGRect) { 137 | 138 | let segmentWidth = widthForSegment(frame) 139 | createSegmentContentView(segmentWidth) 140 | 141 | var index = 0 142 | for controller in controllers! { 143 | 144 | createSegmentFor(controller, width: segmentWidth, index: index) 145 | index += 1 146 | } 147 | 148 | createSelectedSegmentView(segmentWidth) 149 | 150 | //Set first button as selected 151 | let button = segments.first! 152 | button.isSelected = true 153 | } 154 | 155 | func createSegmentContentView(_ titleWidth: CGFloat) { 156 | 157 | segmentContentView = UIView(frame: CGRect.zero) 158 | segmentContentView!.translatesAutoresizingMaskIntoConstraints = false 159 | addSubview(segmentContentView!) 160 | 161 | let contentViewWidth = titleWidth * CGFloat((controllers?.count)!) 162 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[contentView]|", 163 | options: [], 164 | metrics: nil, 165 | views: ["contentView": segmentContentView!, 166 | "mainView": self]) 167 | addConstraints(horizontalConstraints) 168 | 169 | contentViewWidthConstraint = NSLayoutConstraint(item: segmentContentView!, 170 | attribute: .width, 171 | relatedBy: .equal, 172 | toItem: nil, 173 | attribute: .notAnAttribute, 174 | multiplier: 1.0, 175 | constant: contentViewWidth) 176 | addConstraint(contentViewWidthConstraint!) 177 | 178 | 179 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[contentView(==mainView)]|", 180 | options: [], 181 | metrics: nil, 182 | views: ["contentView": segmentContentView!, 183 | "mainView": self]) 184 | addConstraints(verticalConstraints) 185 | } 186 | 187 | func createSegmentFor(_ controller: UIViewController, width: CGFloat, index: Int) { 188 | 189 | let segmentView = getSegmentTabForController(controller) 190 | segmentView.tag = (index + kSegmentViewTagOffset) 191 | segmentView.translatesAutoresizingMaskIntoConstraints = false 192 | segmentContentView!.addSubview(segmentView) 193 | 194 | if segments.count == 0 { 195 | 196 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]", 197 | options: [], 198 | metrics: nil, 199 | views: ["view": segmentView]) 200 | segmentContentView!.addConstraints(horizontalConstraints) 201 | 202 | } else { 203 | 204 | let previousView = segments.last 205 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[previousView]-0-[view]", 206 | options: [], 207 | metrics: nil, 208 | views: ["view": segmentView, 209 | "previousView": previousView!]) 210 | segmentContentView!.addConstraints(horizontalConstraints) 211 | } 212 | 213 | let widthConstraint = NSLayoutConstraint(item: segmentView, 214 | attribute: .width, 215 | relatedBy: .equal, 216 | toItem: nil, 217 | attribute: .notAnAttribute, 218 | multiplier: 1.0, 219 | constant: width) 220 | segmentContentView!.addConstraint(widthConstraint) 221 | contentSubViewWidthConstraints.append(widthConstraint) 222 | 223 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|", 224 | options: [], 225 | metrics: nil, 226 | views: ["view": segmentView]) 227 | segmentContentView!.addConstraints(verticalConstraints) 228 | segments.append(segmentView) 229 | } 230 | 231 | func createSelectedSegmentView(_ width: CGFloat) { 232 | 233 | let segmentView = UIView() 234 | segmentView.backgroundColor = selectedSegmentViewColor 235 | segmentView.translatesAutoresizingMaskIntoConstraints = false 236 | segmentContentView!.addSubview(segmentView) 237 | selectedSegmentView = segmentView 238 | 239 | xPosConstraints = NSLayoutConstraint(item: segmentView, 240 | attribute: .leading, 241 | relatedBy: .equal, 242 | toItem: segmentContentView!, 243 | attribute: .leading, 244 | multiplier: 1.0, 245 | constant: 0.0) 246 | segmentContentView!.addConstraint(xPosConstraints!) 247 | 248 | let segment = segments.first 249 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:[view(==segment)]", 250 | options: [], 251 | metrics: nil, 252 | views: ["view": segmentView, 253 | "segment": segment!]) 254 | segmentContentView!.addConstraints(horizontalConstraints) 255 | 256 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[view(height)]|", 257 | options: [], 258 | metrics: ["height": selectedSegmentViewHeight!], 259 | views: ["view": segmentView]) 260 | segmentContentView!.addConstraints(verticalConstraints) 261 | } 262 | 263 | func getSegmentTabForController(_ controller: UIViewController) -> SJSegmentTab { 264 | 265 | var segmentTab: SJSegmentTab? 266 | 267 | if controller.navigationItem.titleView != nil { 268 | segmentTab = SJSegmentTab.init(view: controller.navigationItem.titleView!) 269 | } else { 270 | 271 | if let title = controller.title { 272 | segmentTab = SJSegmentTab.init(title: title) 273 | } else { 274 | segmentTab = SJSegmentTab.init(title: "") 275 | } 276 | 277 | segmentTab?.backgroundColor = segmentBackgroundColor 278 | segmentTab?.titleColor(titleColor!) 279 | segmentTab?.selectedTitleColor(selectedTitleColor!) 280 | segmentTab?.titleFont(font!) 281 | } 282 | 283 | segmentTab?.didSelectSegmentAtIndex = didSelectSegmentAtIndex 284 | 285 | return segmentTab! 286 | } 287 | 288 | func widthForSegment(_ frame: CGRect) -> CGFloat { 289 | 290 | var maxWidth: CGFloat = 0 291 | for controller in controllers! { 292 | 293 | var width: CGFloat = 0.0 294 | if let view = controller.navigationItem.titleView { 295 | width = view.bounds.width 296 | } else if let title = controller.title { 297 | 298 | width = title.widthWithConstrainedWidth(.greatestFiniteMagnitude, 299 | font: font!) 300 | } 301 | 302 | if width > maxWidth { 303 | maxWidth = width 304 | } 305 | } 306 | 307 | let width = Int(maxWidth + segmentViewOffsetWidth) 308 | let totalWidth = width * (controllers?.count)! 309 | if totalWidth < Int(frame.size.width) { 310 | maxWidth = frame.size.width / CGFloat((controllers?.count)!) 311 | } else { 312 | maxWidth = CGFloat(width) 313 | } 314 | 315 | return maxWidth 316 | } 317 | 318 | override func observeValue(forKeyPath keyPath: String?, 319 | of object: Any?, 320 | change: [NSKeyValueChangeKey : Any]?, 321 | context: UnsafeMutableRawPointer?) { 322 | 323 | if let change = change as [NSKeyValueChangeKey : AnyObject]? { 324 | if let old = change[NSKeyValueChangeKey.oldKey], let new = change[NSKeyValueChangeKey.newKey] { 325 | if !(old.isEqual(new)) { 326 | //update selected segment view x position 327 | let scrollView = object as? UIScrollView 328 | var changeOffset = (scrollView?.contentSize.width)! / contentSize.width 329 | let value = (scrollView?.contentOffset.x)! / changeOffset 330 | 331 | if !value.isNaN { 332 | selectedSegmentView?.frame.origin.x = (scrollView?.contentOffset.x)! / changeOffset 333 | } 334 | 335 | //update segment offset x position 336 | let segmentScrollWidth = contentSize.width - bounds.width 337 | let contentScrollWidth = scrollView!.contentSize.width - scrollView!.bounds.width 338 | changeOffset = segmentScrollWidth / contentScrollWidth 339 | contentOffset.x = (scrollView?.contentOffset.x)! * changeOffset 340 | } 341 | } 342 | } 343 | } 344 | 345 | func didChangeParentViewFrame(_ frame: CGRect) { 346 | 347 | let segmentWidth = widthForSegment(frame) 348 | let contentViewWidth = segmentWidth * CGFloat((controllers?.count)!) 349 | contentViewWidthConstraint?.constant = contentViewWidth 350 | 351 | for constraint in contentSubViewWidthConstraints { 352 | constraint.constant = segmentWidth 353 | } 354 | 355 | let changeOffset = (contentView?.contentSize.width)! / contentSize.width 356 | let value = (contentView?.contentOffset.x)! / changeOffset 357 | 358 | if !value.isNaN { 359 | if UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute) == .rightToLeft { 360 | let newIndex = contentView?.pageIndex ?? 0 361 | xPosConstraints!.constant = CGFloat(newIndex) * segmentWidth 362 | } else { 363 | xPosConstraints!.constant = (selectedSegmentView?.frame.origin.x)! 364 | } 365 | 366 | layoutIfNeeded() 367 | } 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJSegmentedScrollView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJSegmentedScrollView.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Subins Jose on 10/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SJSegmentedScrollView: UIScrollView { 26 | 27 | var segmentView: SJSegmentView? 28 | 29 | var headerViewHeight: CGFloat! = 0 { 30 | didSet { 31 | headerHeightConstraint?.constant = headerViewHeight 32 | } 33 | } 34 | 35 | var segmentViewHeight: CGFloat! = 0 { 36 | didSet { 37 | segmentViewHeightConstraint?.constant = segmentViewHeight 38 | } 39 | } 40 | 41 | var headerViewOffsetHeight: CGFloat! = 0 42 | 43 | var selectedSegmentViewColor: UIColor! = UIColor.red { 44 | didSet { 45 | segmentView?.selectedSegmentViewColor = selectedSegmentViewColor 46 | } 47 | } 48 | 49 | var selectedSegmentViewHeight: CGFloat! = 0 50 | 51 | var segmentBounces = false 52 | 53 | var segmentTitleColor: UIColor! = UIColor.red { 54 | didSet { 55 | segmentView?.titleColor = segmentTitleColor 56 | } 57 | } 58 | 59 | var segmentSelectedTitleColor: UIColor? { 60 | didSet { 61 | segmentView?.selectedTitleColor = segmentSelectedTitleColor 62 | } 63 | } 64 | 65 | var segmentBackgroundColor: UIColor? { 66 | didSet { 67 | segmentView?.segmentBackgroundColor = segmentBackgroundColor 68 | } 69 | } 70 | 71 | var segmentShadow: SJShadow? { 72 | didSet { 73 | segmentView?.shadow = segmentShadow 74 | } 75 | } 76 | 77 | var segmentTitleFont: UIFont! = UIFont.systemFont(ofSize: 12) { 78 | didSet { 79 | segmentView?.font = segmentTitleFont 80 | } 81 | } 82 | 83 | var topSpacing: CGFloat? 84 | 85 | var bottomSpacing: CGFloat? 86 | 87 | var observing = true 88 | 89 | var headerView: UIView? 90 | 91 | var contentControllers: [UIViewController]? 92 | 93 | var contentViews = [UIView]() 94 | 95 | var contentView: SJContentView? 96 | 97 | var scrollContentView: UIView! 98 | 99 | var contentViewHeightConstraint: NSLayoutConstraint! 100 | 101 | var didSelectSegmentAtIndex: DidSelectSegmentAtIndex? 102 | 103 | var sjShowsVerticalScrollIndicator: Bool = false { 104 | didSet { 105 | showsVerticalScrollIndicator = sjShowsVerticalScrollIndicator 106 | contentView?.showsVerticalScrollIndicator = sjShowsVerticalScrollIndicator 107 | } 108 | } 109 | 110 | var sjShowsHorizontalScrollIndicator: Bool = false { 111 | didSet { 112 | showsHorizontalScrollIndicator = sjShowsHorizontalScrollIndicator 113 | contentView?.showsHorizontalScrollIndicator = sjShowsHorizontalScrollIndicator 114 | } 115 | } 116 | 117 | private var viewObservers = [UIView]() 118 | var sjDisableScrollOnContentView: Bool = false { 119 | didSet { 120 | contentView?.isScrollEnabled = !sjDisableScrollOnContentView 121 | } 122 | } 123 | 124 | override init(frame: CGRect) { 125 | super.init(frame: frame) 126 | 127 | sizeToFit() 128 | translatesAutoresizingMaskIntoConstraints = false 129 | showsHorizontalScrollIndicator = sjShowsHorizontalScrollIndicator 130 | showsVerticalScrollIndicator = sjShowsVerticalScrollIndicator 131 | decelerationRate = .fast 132 | bounces = false 133 | 134 | addObserver(self, forKeyPath: "contentOffset", 135 | options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old], 136 | context: nil) 137 | 138 | 139 | } 140 | 141 | required init?(coder aDecoder: NSCoder) { 142 | fatalError("init(coder:) has not been implemented") 143 | } 144 | 145 | deinit { 146 | removeObserver(self, 147 | forKeyPath: "contentOffset", 148 | context: nil) 149 | 150 | for view in viewObservers { 151 | view.removeObserver(self, 152 | forKeyPath: "contentOffset", 153 | context: nil) 154 | } 155 | } 156 | 157 | func setContentView() { 158 | 159 | if scrollContentView == nil { 160 | 161 | scrollContentView = UIView() 162 | scrollContentView.translatesAutoresizingMaskIntoConstraints = false 163 | addSubview(scrollContentView) 164 | 165 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[contentView(==mainView)]|", 166 | options: [], 167 | metrics: nil, 168 | views: ["contentView": scrollContentView, "mainView": self]) 169 | addConstraints(horizontalConstraints) 170 | 171 | let contentHeight = getContentHeight() 172 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[contentView]|", 173 | options: [], 174 | metrics: nil, 175 | views: ["contentView": scrollContentView]) 176 | addConstraints(verticalConstraints) 177 | 178 | contentViewHeightConstraint = NSLayoutConstraint(item: scrollContentView, 179 | attribute: .height, 180 | relatedBy: .equal, 181 | toItem: nil, 182 | attribute: .notAnAttribute, 183 | multiplier: 1.0, 184 | constant: contentHeight) 185 | addConstraint(contentViewHeightConstraint) 186 | } 187 | } 188 | 189 | private var headerHeightConstraint: NSLayoutConstraint? 190 | 191 | func addHeaderView(_ headerView: UIView?) { 192 | 193 | if headerView != nil { 194 | 195 | self.headerView = headerView 196 | headerView?.translatesAutoresizingMaskIntoConstraints = false 197 | scrollContentView.addSubview(headerView!) 198 | 199 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[headerView]-0-|", 200 | options: [], 201 | metrics: nil, 202 | views: ["headerView": headerView!]) 203 | scrollContentView.addConstraints(horizontalConstraints) 204 | 205 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[headerView(\(headerViewHeight!))]", 206 | options: [], 207 | metrics: nil, 208 | views: ["headerView": headerView!]) 209 | scrollContentView.addConstraints(verticalConstraints) 210 | 211 | headerHeightConstraint = verticalConstraints[1] 212 | } else { 213 | 214 | headerViewHeight = headerViewOffsetHeight 215 | } 216 | } 217 | 218 | func addObserverFor(_ view: UIView) { 219 | viewObservers.append(view) 220 | view.addObserver(self, forKeyPath: "contentOffset", 221 | options: [NSKeyValueObservingOptions.new, NSKeyValueObservingOptions.old], 222 | context: nil) 223 | } 224 | 225 | func addContentView(_ contentView: UIView, frame: CGRect) { 226 | 227 | if self.contentView == nil { 228 | self.contentView = createContentView() 229 | } 230 | 231 | contentViews.append(contentView) 232 | self.contentView?.addContentView(contentView, frame: frame) 233 | self.contentView!.didSelectSegmentAtIndex = {[unowned self] 234 | (segment, index, animated) in 235 | self.didSelectSegmentAtIndex?(self.segmentView!.segments[index], index, animated) 236 | } 237 | } 238 | 239 | func updateSubviewsFrame(_ frame: CGRect) { 240 | 241 | contentViewHeightConstraint.constant = getContentHeight() 242 | contentView?.layoutIfNeeded() 243 | 244 | segmentView?.didChangeParentViewFrame(frame) 245 | contentView?.updateContentControllersFrame(frame) 246 | } 247 | 248 | //MARK: Private Functions 249 | func getContentHeight() -> CGFloat { 250 | 251 | var contentHeight = (superview?.bounds.height)! + headerViewHeight! 252 | contentHeight -= (topSpacing! + bottomSpacing! + headerViewOffsetHeight!) 253 | return contentHeight 254 | } 255 | 256 | private var segmentViewHeightConstraint: NSLayoutConstraint? 257 | 258 | func addSegmentView(_ controllers: [UIViewController], frame: CGRect) { 259 | 260 | if controllers.count > 1 { 261 | 262 | segmentView = SJSegmentView(frame: CGRect.zero) 263 | segmentView?.controllers = controllers 264 | segmentView?.selectedSegmentViewColor = selectedSegmentViewColor 265 | segmentView?.selectedSegmentViewHeight = selectedSegmentViewHeight! 266 | segmentView?.titleColor = segmentTitleColor 267 | segmentView?.selectedTitleColor = segmentSelectedTitleColor 268 | segmentView?.segmentBackgroundColor = segmentBackgroundColor 269 | segmentView?.font = segmentTitleFont! 270 | segmentView?.shadow = segmentShadow 271 | segmentView?.font = segmentTitleFont! 272 | segmentView?.bounces = false 273 | segmentView!.translatesAutoresizingMaskIntoConstraints = false 274 | segmentView!.didSelectSegmentAtIndex = {[unowned self] 275 | (segment, index, animated) in 276 | self.contentView?.movePageToIndex(index, animated: animated) 277 | self.didSelectSegmentAtIndex?(segment, index, animated) 278 | } 279 | 280 | segmentView?.setSegmentsView(frame) 281 | addSubview(segmentView!) 282 | 283 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[segmentView]-0-|", 284 | options: [], 285 | metrics: nil, 286 | views: ["segmentView": segmentView!]) 287 | addConstraints(horizontalConstraints) 288 | 289 | let view = headerView == nil ? self : headerView 290 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[headerView]-0-[segmentView(\(segmentViewHeight!))]", 291 | options: [], 292 | metrics: nil, 293 | views: ["headerView": view!, 294 | "segmentView": segmentView!]) 295 | addConstraints(verticalConstraints) 296 | 297 | segmentViewHeightConstraint = verticalConstraints[1] 298 | } else { 299 | 300 | segmentViewHeight = 0.0 301 | } 302 | } 303 | 304 | func addSegmentsForContentViews(_ titles: [String]) { 305 | 306 | let frame = CGRect(x: 0, y: headerViewHeight!, 307 | width: bounds.size.width, height: segmentViewHeight!) 308 | segmentView = SJSegmentView(frame: frame) 309 | segmentView!.didSelectSegmentAtIndex = { 310 | [unowned self] (segment, index, animated) in 311 | self.contentView?.movePageToIndex(index, animated: animated) 312 | } 313 | addSubview(segmentView!) 314 | } 315 | 316 | func createContentView() -> SJContentView { 317 | 318 | let contentView = SJContentView(frame: CGRect.zero) 319 | contentView.showsVerticalScrollIndicator = sjShowsVerticalScrollIndicator 320 | contentView.showsHorizontalScrollIndicator = sjShowsHorizontalScrollIndicator 321 | contentView.isScrollEnabled = !sjDisableScrollOnContentView 322 | contentView.translatesAutoresizingMaskIntoConstraints = false 323 | contentView.bounces = segmentBounces 324 | scrollContentView.addSubview(contentView) 325 | 326 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[contentView]-0-|", 327 | options: [], 328 | metrics: nil, 329 | views: ["contentView": contentView]) 330 | scrollContentView.addConstraints(horizontalConstraints) 331 | 332 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[headerView]-\(segmentViewHeight!)-[contentView]-0-|", 333 | options: [], 334 | metrics: nil, 335 | views: ["headerView": headerView!, 336 | "contentView": contentView]) 337 | 338 | 339 | scrollContentView.addConstraints(verticalConstraints) 340 | return contentView 341 | } 342 | 343 | func handleScrollUp(_ scrollView: UIScrollView, 344 | change: CGFloat, 345 | oldPosition: CGPoint) { 346 | 347 | if headerViewHeight != 0.0 && contentOffset.y != 0.0 { 348 | if scrollView.contentOffset.y < 0.0 { 349 | if contentOffset.y >= 0.0 { 350 | 351 | var yPos = contentOffset.y - change 352 | yPos = yPos < 0 ? 0 : yPos 353 | let updatedPos = CGPoint(x: contentOffset.x, y: yPos) 354 | setContentOffset(self, point: updatedPos) 355 | setContentOffset(scrollView, point: oldPosition) 356 | } 357 | } 358 | } 359 | } 360 | 361 | func handleScrollDown(_ scrollView: UIScrollView, 362 | change: CGFloat, 363 | oldPosition: CGPoint) { 364 | 365 | let offset = (headerViewHeight! - headerViewOffsetHeight!) 366 | 367 | if contentOffset.y < offset { 368 | 369 | if scrollView.contentOffset.y >= 0.0 { 370 | 371 | var yPos = contentOffset.y - change 372 | yPos = yPos > offset ? offset : yPos 373 | let updatedPos = CGPoint(x: contentOffset.x, y: yPos) 374 | setContentOffset(self, point: updatedPos) 375 | setContentOffset(scrollView, point: oldPosition) 376 | } 377 | } 378 | } 379 | 380 | override func observeValue(forKeyPath keyPath: String?, 381 | of object: Any?, 382 | change: [NSKeyValueChangeKey : Any]?, 383 | context: UnsafeMutableRawPointer?) { 384 | if !observing { return } 385 | 386 | let scrollView = object as? UIScrollView 387 | if scrollView == nil { return } 388 | if scrollView == self { return } 389 | 390 | let changeValues = change! as [NSKeyValueChangeKey: AnyObject] 391 | 392 | if let new = changeValues[NSKeyValueChangeKey.newKey]?.cgPointValue, 393 | let old = changeValues[NSKeyValueChangeKey.oldKey]?.cgPointValue { 394 | 395 | let diff = old.y - new.y 396 | 397 | if diff > 0.0 { 398 | 399 | handleScrollUp(scrollView!, 400 | change: diff, 401 | oldPosition: old) 402 | } else { 403 | 404 | handleScrollDown(scrollView!, 405 | change: diff, 406 | oldPosition: old) 407 | } 408 | } 409 | } 410 | 411 | func setContentOffset(_ scrollView: UIScrollView, point: CGPoint) { 412 | observing = false 413 | scrollView.contentOffset = point 414 | observing = true 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJSegmentedViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJSegmentedViewController.swift 3 | // Pods 4 | // 5 | // Created by Subins Jose on 20/06/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | @objc public protocol SJSegmentedViewControllerDelegate { 26 | 27 | @objc optional func didSelectSegmentAtIndex(_ index:Int) 28 | 29 | /** 30 | Method to identify the current controller and segment of contentview 31 | 32 | - parameter controller: Current controller 33 | - parameter segment: selected segment 34 | - parameter index: index of selected segment. 35 | */ 36 | @objc optional func didMoveToPage(_ controller: UIViewController, segment: SJSegmentTab?, index: Int) 37 | } 38 | 39 | /** 40 | * Public protocol of SJSegmentedViewController for content changes and makes the scroll effect. 41 | */ 42 | @objc public protocol SJSegmentedViewControllerViewSource { 43 | 44 | /** 45 | By default, SJSegmentedScrollView will observe the default view of viewcontroller for content 46 | changes and makes the scroll effect. If you want to change the default view, implement 47 | SJSegmentedViewControllerViewSource and pass your custom view. 48 | 49 | - returns: observe view 50 | */ 51 | @objc optional func viewForSegmentControllerToObserveContentOffsetChange() -> UIView 52 | } 53 | 54 | /** 55 | * Public class for customizing and setting our segmented scroll view 56 | */ 57 | @objc open class SJSegmentedViewController: UIViewController { 58 | 59 | /** 60 | * The headerview height for 'Header'. 61 | * 62 | * By default the height will be 0.0 63 | * 64 | * segmentedViewController.headerViewHeight = 200.0 65 | */ 66 | open var headerViewHeight: CGFloat = 0.0 { 67 | didSet { 68 | segmentedScrollView.headerViewHeight = headerViewHeight 69 | } 70 | } 71 | 72 | /** 73 | * Set height for segment view. 74 | * 75 | * By default the height is 40.0 76 | * 77 | * segmentedViewController.segmentViewHeight = 60.0 78 | */ 79 | open var segmentViewHeight: CGFloat = 40.0 { 80 | didSet { 81 | segmentedScrollView.segmentViewHeight = segmentViewHeight 82 | } 83 | } 84 | 85 | /** 86 | * Set headerview offset height. 87 | * 88 | * By default the height is 0.0 89 | * 90 | * segmentedViewController. headerViewOffsetHeight = 10.0 91 | */ 92 | open var headerViewOffsetHeight: CGFloat = 0.0 { 93 | didSet { 94 | segmentedScrollView.headerViewOffsetHeight = headerViewOffsetHeight 95 | } 96 | } 97 | 98 | /** 99 | * Set color for selected segment. 100 | * 101 | * By default the color is light gray. 102 | * 103 | * segmentedViewController.selectedSegmentViewColor = UIColor.redColor() 104 | */ 105 | open var selectedSegmentViewColor = UIColor.lightGray { 106 | didSet { 107 | segmentedScrollView.selectedSegmentViewColor = selectedSegmentViewColor 108 | } 109 | } 110 | 111 | /** 112 | * Set height for selected segment view. 113 | * 114 | * By default the height is 5.0 115 | * 116 | * segmentedViewController.selectedSegmentViewHeight = 5.0 117 | */ 118 | open var selectedSegmentViewHeight: CGFloat = 5.0 { 119 | didSet { 120 | segmentedScrollView.selectedSegmentViewHeight = selectedSegmentViewHeight 121 | } 122 | } 123 | 124 | /** 125 | * Set color for segment title. 126 | * 127 | * By default the color is black. 128 | * 129 | * segmentedViewController.segmentTitleColor = UIColor.redColor() 130 | */ 131 | open var segmentTitleColor = UIColor.black { 132 | didSet { 133 | segmentedScrollView.segmentTitleColor = segmentTitleColor 134 | } 135 | } 136 | 137 | /** 138 | * Set color for segment title. 139 | * 140 | * By default the color is black. 141 | * 142 | * segmentedViewController.segmentTitleColor = UIColor.redColor() 143 | */ 144 | open var segmentSelectedTitleColor = UIColor.black { 145 | didSet { 146 | segmentedScrollView.segmentSelectedTitleColor = segmentSelectedTitleColor 147 | } 148 | } 149 | 150 | /** 151 | * Set color for segment background. 152 | * 153 | * By default the color is white. 154 | * 155 | * segmentedViewController.segmentBackgroundColor = UIColor.whiteColor() 156 | */ 157 | open var segmentBackgroundColor = UIColor.white { 158 | didSet { 159 | segmentedScrollView.segmentBackgroundColor = segmentBackgroundColor 160 | } 161 | } 162 | 163 | /** 164 | * Set shadow for segment. 165 | * 166 | * By default the color is light gray. 167 | * 168 | * segmentedViewController.segmentShadow = SJShadow.light() 169 | */ 170 | open var segmentShadow = SJShadow() { 171 | didSet { 172 | segmentedScrollView.segmentShadow = segmentShadow 173 | } 174 | } 175 | 176 | /** 177 | * Set font for segment title. 178 | * 179 | * segmentedViewController.segmentTitleFont = UIFont.systemFontOfSize(14.0) 180 | */ 181 | open var segmentTitleFont = UIFont.systemFont(ofSize: 14.0) { 182 | didSet { 183 | segmentedScrollView.segmentTitleFont = segmentTitleFont 184 | } 185 | } 186 | 187 | /** 188 | * Set bounce for segment. 189 | * 190 | * By default it is set to true. 191 | * 192 | * segmentedViewController.segmentBounces = false 193 | */ 194 | open var segmentBounces = true { 195 | didSet { 196 | segmentedScrollView.segmentBounces = segmentBounces 197 | } 198 | } 199 | 200 | /** 201 | * Set ViewController for header view. 202 | */ 203 | open var headerViewController: UIViewController? { 204 | didSet { 205 | setDefaultValuesToSegmentedScrollView() 206 | } 207 | } 208 | 209 | /** 210 | * Array of ViewControllers for segments. 211 | */ 212 | open var segmentControllers = [UIViewController]() { 213 | didSet { 214 | setDefaultValuesToSegmentedScrollView() 215 | } 216 | } 217 | 218 | /** 219 | * Array of segments. For single view controller segments will be empty. 220 | */ 221 | open var segments: [SJSegmentTab] { 222 | get { 223 | 224 | if let segmentView = segmentedScrollView.segmentView { 225 | return segmentView.segments 226 | } 227 | 228 | return [SJSegmentTab]() 229 | } 230 | } 231 | 232 | /** 233 | * Set color of SegmentedScrollView. 234 | * 235 | * By default it is set to white. 236 | * 237 | * segmentedScrollView.backgroundColor = UIColor.white 238 | */ 239 | open var segmentedScrollViewColor = UIColor.white { 240 | didSet { 241 | segmentedScrollView.backgroundColor = segmentedScrollViewColor 242 | } 243 | } 244 | 245 | /** 246 | * Set vertical scroll indicator. 247 | * 248 | * By default true. 249 | * 250 | * segmentedScrollView.showsVerticalScrollIndicator = false 251 | */ 252 | open var showsVerticalScrollIndicator = true { 253 | didSet { 254 | segmentedScrollView.sjShowsVerticalScrollIndicator = showsVerticalScrollIndicator 255 | } 256 | } 257 | 258 | /** 259 | * Set horizontal scroll indicator. 260 | * 261 | * By default true. 262 | * 263 | * segmentedScrollView.showsHorizontalScrollIndicator = false 264 | */ 265 | open var showsHorizontalScrollIndicator = true { 266 | didSet { 267 | segmentedScrollView.sjShowsHorizontalScrollIndicator = showsHorizontalScrollIndicator 268 | } 269 | } 270 | 271 | /** 272 | * Disable scroll on contentView. 273 | * 274 | * By default false. 275 | * 276 | * segmentedScrollView.disableScrollOnContentView = true 277 | */ 278 | open var disableScrollOnContentView: Bool = false { 279 | didSet { 280 | segmentedScrollView.sjDisableScrollOnContentView = disableScrollOnContentView 281 | } 282 | } 283 | 284 | open weak var delegate:SJSegmentedViewControllerDelegate? 285 | var segmentedScrollView = SJSegmentedScrollView(frame: CGRect.zero) 286 | var segmentScrollViewTopConstraint: NSLayoutConstraint? 287 | 288 | 289 | /** 290 | Custom initializer for SJSegmentedViewController. 291 | 292 | - parameter headerViewController: A UIViewController 293 | - parameter segmentControllers: Array of UIViewControllers for segments. 294 | 295 | */ 296 | required public init(headerViewController: UIViewController?, 297 | segmentControllers: [UIViewController]) { 298 | super.init(nibName: nil, bundle: nil) 299 | self.headerViewController = headerViewController 300 | self.segmentControllers = segmentControllers 301 | setDefaultValuesToSegmentedScrollView() 302 | } 303 | 304 | override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 305 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 306 | } 307 | 308 | required public init?(coder aDecoder: NSCoder) { 309 | super.init(coder: aDecoder) 310 | } 311 | 312 | override open func loadView() { 313 | super.loadView() 314 | addSegmentedScrollView() 315 | } 316 | 317 | override open func viewDidLoad() { 318 | super.viewDidLoad() 319 | 320 | view.backgroundColor = UIColor.white 321 | loadControllers() 322 | if #available(iOS 11, *) { 323 | segmentedScrollView.contentInsetAdjustmentBehavior = .never 324 | } else { 325 | automaticallyAdjustsScrollViewInsets = false 326 | } 327 | } 328 | 329 | /** 330 | * Update view as per the current layout 331 | */ 332 | override open func viewDidLayoutSubviews() { 333 | super.viewDidLayoutSubviews() 334 | 335 | let topSpacing = SJUtil.getTopSpacing(self) 336 | segmentedScrollView.topSpacing = topSpacing 337 | segmentedScrollView.bottomSpacing = SJUtil.getBottomSpacing(self) 338 | segmentScrollViewTopConstraint?.constant = topSpacing 339 | segmentedScrollView.updateSubviewsFrame(view.bounds) 340 | } 341 | 342 | /** 343 | * To select segment programmatically 344 | * - parameter index Int Segment index 345 | * - parameter animated Bool Move with an animation or not. 346 | */ 347 | open func setSelectedSegmentAt(_ index: Int, animated: Bool) { 348 | 349 | if index >= 0 && index < segmentControllers.count { 350 | segmentedScrollView.segmentView?.didSelectSegmentAtIndex!(segments[index], 351 | index, 352 | animated) 353 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DidChangeSegmentIndex"), 354 | object: index) 355 | } 356 | } 357 | 358 | /** 359 | * Set the default values for the segmented scroll view. 360 | */ 361 | func setDefaultValuesToSegmentedScrollView() { 362 | 363 | segmentedScrollView.selectedSegmentViewColor = selectedSegmentViewColor 364 | segmentedScrollView.selectedSegmentViewHeight = selectedSegmentViewHeight 365 | segmentedScrollView.segmentTitleColor = segmentTitleColor 366 | segmentedScrollView.segmentSelectedTitleColor = segmentSelectedTitleColor 367 | segmentedScrollView.segmentBackgroundColor = segmentBackgroundColor 368 | segmentedScrollView.segmentShadow = segmentShadow 369 | segmentedScrollView.segmentTitleFont = segmentTitleFont 370 | segmentedScrollView.segmentBounces = segmentBounces 371 | segmentedScrollView.headerViewHeight = headerViewHeight 372 | segmentedScrollView.headerViewOffsetHeight = headerViewOffsetHeight 373 | segmentedScrollView.segmentViewHeight = segmentViewHeight 374 | segmentedScrollView.backgroundColor = segmentedScrollViewColor 375 | segmentedScrollView.sjDisableScrollOnContentView = disableScrollOnContentView 376 | } 377 | 378 | /** 379 | * Private method for adding the segmented scroll view. 380 | */ 381 | func addSegmentedScrollView() { 382 | 383 | let topSpacing = SJUtil.getTopSpacing(self) 384 | segmentedScrollView.topSpacing = topSpacing 385 | 386 | let bottomSpacing = SJUtil.getBottomSpacing(self) 387 | segmentedScrollView.bottomSpacing = bottomSpacing 388 | 389 | view.addSubview(segmentedScrollView) 390 | 391 | let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[scrollView]-0-|", 392 | options: [], 393 | metrics: nil, 394 | views: ["scrollView": segmentedScrollView]) 395 | view.addConstraints(horizontalConstraints) 396 | 397 | let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:[scrollView]-bp-|", 398 | options: [], 399 | metrics: ["tp": topSpacing, 400 | "bp": bottomSpacing], 401 | views: ["scrollView": segmentedScrollView]) 402 | view.addConstraints(verticalConstraints) 403 | 404 | segmentScrollViewTopConstraint = NSLayoutConstraint(item: segmentedScrollView, 405 | attribute: .top, 406 | relatedBy: .equal, 407 | toItem: view, 408 | attribute: .top, 409 | multiplier: 1.0, 410 | constant: topSpacing) 411 | view.addConstraint(segmentScrollViewTopConstraint!) 412 | 413 | segmentedScrollView.setContentView() 414 | 415 | // selected segment at index 416 | segmentedScrollView.didSelectSegmentAtIndex = {[unowned self] (segment, index, animated) in 417 | 418 | let selectedController = self.segmentControllers[index] 419 | self.delegate?.didMoveToPage?(selectedController, segment: segment!, index: index) 420 | } 421 | } 422 | 423 | /** 424 | Method for adding the HeaderViewController into the container 425 | 426 | - parameter headerViewController: Header ViewController. 427 | */ 428 | func addHeaderViewController(_ headerViewController: UIViewController) { 429 | 430 | addChild(headerViewController) 431 | segmentedScrollView.addHeaderView(headerViewController.view) 432 | headerViewController.didMove(toParent: self) 433 | } 434 | 435 | /** 436 | Method for adding the array of content ViewControllers into the container 437 | 438 | - parameter contentControllers: array of ViewControllers 439 | */ 440 | func addContentControllers(_ contentControllers: [UIViewController]) { 441 | segmentedScrollView.addSegmentView(contentControllers, frame: view.bounds) 442 | 443 | var index = 0 444 | for controller in contentControllers { 445 | 446 | addChild(controller) 447 | segmentedScrollView.addContentView(controller.view, frame: view.bounds) 448 | controller.didMove(toParent: self) 449 | 450 | let delegate = controller as? SJSegmentedViewControllerViewSource 451 | var observeView = controller.view 452 | 453 | if let collectionController = controller as? UICollectionViewController { 454 | observeView = collectionController.collectionView 455 | } 456 | 457 | if let view = delegate?.viewForSegmentControllerToObserveContentOffsetChange?() { 458 | observeView = view 459 | } 460 | 461 | segmentedScrollView.addObserverFor(observeView!) 462 | index += 1 463 | } 464 | 465 | segmentedScrollView.segmentView?.contentView = segmentedScrollView.contentView 466 | } 467 | 468 | /** 469 | * Method for loading content ViewControllers and header ViewController 470 | */ 471 | func loadControllers() { 472 | 473 | if headerViewController == nil { 474 | headerViewController = UIViewController() 475 | headerViewHeight = 0.0 476 | } 477 | 478 | addHeaderViewController(headerViewController!) 479 | addContentControllers(segmentControllers) 480 | 481 | //Delegate call for setting the first view of segments. 482 | var segment: SJSegmentTab? 483 | if segments.count > 0 { 484 | segment = segments[0] 485 | } 486 | 487 | delegate?.didMoveToPage?(segmentControllers[0], 488 | segment: segment, 489 | index: 0) 490 | } 491 | } 492 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJShadow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJShadow.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Radhakrishna Pai on 24/08/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | 24 | import Foundation 25 | import UIKit 26 | 27 | @objc open class SJShadow: NSObject { 28 | var offset = CGSize(width: 0, height: 1) 29 | var color = UIColor.lightGray 30 | var radius: CGFloat = 3.0 31 | var opacity: Float = 0.4 32 | 33 | /** 34 | To create a custom shadow object. 35 | 36 | - parameter offset: CGSize, shadow size 37 | - parameter color: UIColor, shadow color 38 | - parameter radius: CGFloat, shadow radius 39 | - parameter opacity: Float, shadow opacity 40 | 41 | - returns: SJShadow 42 | */ 43 | public convenience init(offset: CGSize, color: UIColor, radius :CGFloat, opacity: Float) { 44 | self.init() 45 | self.offset = offset 46 | self.color = color 47 | self.radius = radius 48 | self.opacity = opacity 49 | } 50 | 51 | /** 52 | Create light shadow 53 | 54 | - returns: light SJShadow object 55 | */ 56 | open class func light() -> SJShadow { 57 | return SJShadow(offset: CGSize(width: 0, height: 1), 58 | color: UIColor.lightGray, 59 | radius: 3.0, 60 | opacity: 0.4) 61 | } 62 | 63 | /** 64 | Create Medium shadow 65 | 66 | - returns: medium SJShadow object 67 | */ 68 | open class func medium() -> SJShadow { 69 | return SJShadow(offset: CGSize(width: 0, height: 1), 70 | color: UIColor.gray, 71 | radius: 3.0, 72 | opacity: 0.4) 73 | } 74 | 75 | /** 76 | Create dark shadow 77 | 78 | - returns: dark SJShadow object 79 | */ 80 | open class func dark() -> SJShadow { 81 | return SJShadow(offset: CGSize(width: 0, height: 1), 82 | color: UIColor.black, 83 | radius: 3.0, 84 | opacity: 0.4) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /SJSegmentedScrollView/Classes/SJUtil.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SJUtil.swift 3 | // SJSegmentedScrollView 4 | // 5 | // Created by Priya on 8/26/16. 6 | // Copyright © 2016 Subins Jose. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 9 | // associated documentation files (the "Software"), to deal in the Software without restriction, 10 | // including without limitation the rights to use, copy, modify, merge, publish, distribute, 11 | // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all copies or 15 | // substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 18 | // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SJUtil { 26 | 27 | /** 28 | * Method to get topspacing of container, 29 | 30 | - returns: topspace in float 31 | */ 32 | static func getTopSpacing(_ viewController: UIViewController) -> CGFloat { 33 | 34 | if let _ = viewController.splitViewController { 35 | return 0 36 | } 37 | 38 | var topSpacing: CGFloat = 0.0 39 | let navigationController = viewController.navigationController 40 | 41 | if navigationController?.children.last == viewController { 42 | 43 | if navigationController?.isNavigationBarHidden == false { 44 | topSpacing = UIApplication.shared.statusBarFrame.height 45 | if !(navigationController?.navigationBar.isOpaque)! { 46 | topSpacing += (navigationController?.navigationBar.bounds.height)! 47 | } 48 | } 49 | } 50 | 51 | return topSpacing 52 | } 53 | 54 | /** 55 | * Method to get bottomspacing of container 56 | 57 | - returns: bottomspace in float 58 | */ 59 | static func getBottomSpacing(_ viewController: UIViewController) -> CGFloat { 60 | 61 | var bottomSpacing: CGFloat = 0.0 62 | 63 | if let tabBarController = viewController.tabBarController { 64 | if !tabBarController.tabBar.isHidden && !tabBarController.tabBar.isOpaque { 65 | bottomSpacing += tabBarController.tabBar.bounds.size.height 66 | } 67 | } 68 | 69 | return bottomSpacing 70 | } 71 | } 72 | 73 | extension String { 74 | 75 | func widthWithConstrainedWidth(_ width: CGFloat, font: UIFont) -> CGFloat { 76 | 77 | let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) 78 | let boundingBox = self.boundingRect(with: constraintRect, 79 | options: .usesLineFragmentOrigin, 80 | attributes: [NSAttributedString.Key.font: font], context: nil) 81 | return boundingBox.width 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /new_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/subinspathilettu/SJSegmentedViewController/0aeb563c79266f39d0464dc90906b1d31d669f2c/new_demo.gif --------------------------------------------------------------------------------