├── .gitignore ├── Example ├── WBSegmentControl-Example.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── WBSegmentControl-Example │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── 1.imageset │ │ │ ├── 1454576025_icon-141-box-filled.png │ │ │ ├── 1454576025_icon-141-box-filled@2x.png │ │ │ ├── 1454576025_icon-141-box-filled@3x.png │ │ │ └── Contents.json │ │ ├── 2.imageset │ │ │ ├── 1454576043_icon-40-clipboard-list.png │ │ │ ├── 1454576043_icon-40-clipboard-list@2x.png │ │ │ ├── 1454576043_icon-40-clipboard-list@3x.png │ │ │ └── Contents.json │ │ ├── 3.imageset │ │ │ ├── 1454576053_icon-114-lock.png │ │ │ ├── 1454576053_icon-114-lock@2x.png │ │ │ ├── 1454576053_icon-114-lock@3x.png │ │ │ └── Contents.json │ │ ├── 4.imageset │ │ │ ├── 1454576060_icon-144-box-bookmark.png │ │ │ ├── 1454576060_icon-144-box-bookmark@2x.png │ │ │ ├── 1454576060_icon-144-box-bookmark@3x.png │ │ │ └── Contents.json │ │ ├── 5.imageset │ │ │ ├── 1454576071_icon-92-inbox-download.png │ │ │ ├── 1454576071_icon-92-inbox-download@2x.png │ │ │ ├── 1454576071_icon-92-inbox-download@3x.png │ │ │ └── Contents.json │ │ ├── 6.imageset │ │ │ ├── 1454576094_icon-115-lock-open.png │ │ │ ├── 1454576094_icon-115-lock-open@2x.png │ │ │ ├── 1454576094_icon-115-lock-open@3x.png │ │ │ └── Contents.json │ │ ├── 7.imageset │ │ │ ├── 1461433662_snow_flake_3.png │ │ │ ├── 1461433662_snow_flake_3@2x.png │ │ │ ├── 1461433662_snow_flake_3@3x.png │ │ │ └── Contents.json │ │ ├── 8.imageset │ │ │ ├── 1461434737_calendar.png │ │ │ ├── 1461434737_calendar@2x.png │ │ │ ├── 1461434737_calendar@3x.png │ │ │ └── Contents.json │ │ ├── 9.imageset │ │ │ ├── 1461434779_82.png │ │ │ ├── 1461434779_82@2x.png │ │ │ ├── 1461434779_82@3x.png │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ └── LaunchScreen.storyboard │ ├── Info.plist │ ├── ViewController1.swift │ └── ViewController2.swift ├── WBSegmentControl-ExampleTests │ ├── Info.plist │ └── WBSegmentControl_ExampleTests.swift └── WBSegmentControl-ExampleUITests │ ├── Info.plist │ └── WBSegmentControl_ExampleUITests.swift ├── Framework ├── ScreenShot │ ├── Simulator Screen Shot 27 Nov 2016, 8.10.29 PM.png │ ├── Simulator Screen Shot 27 Nov 2016, 8.10.29 PM_result1.jpg │ └── WBSegmentControl.gif ├── WBSegmentControl.podspec ├── WBSegmentControl.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── WBSegmentControl.xcscheme ├── WBSegmentControl │ ├── Info.plist │ ├── WBSegmentControl.h │ ├── WBSegmentControl.swift │ ├── WBSegmentControl.swift.orig │ └── WBSegments.swift └── WBSegmentControlTests │ ├── Info.plist │ └── WBSegmentControlTests.swift ├── LICENSE ├── README.md └── WBSegmentControl.xcworkspace └── contents.xcworkspacedata /.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 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 424209281E0CC1790081F7A1 /* WBSegmentControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 424209231E0CC1620081F7A1 /* WBSegmentControl.framework */; }; 11 | 424209291E0CC1860081F7A1 /* WBSegmentControl.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 424209231E0CC1620081F7A1 /* WBSegmentControl.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 12 | 42DDC7C71D8F7022005409EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7C61D8F7022005409EE /* AppDelegate.swift */; }; 13 | 42DDC7C91D8F7022005409EE /* ViewController1.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7C81D8F7022005409EE /* ViewController1.swift */; }; 14 | 42DDC7CE1D8F7022005409EE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 42DDC7CD1D8F7022005409EE /* Assets.xcassets */; }; 15 | 42DDC7D11D8F7022005409EE /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 42DDC7CF1D8F7022005409EE /* LaunchScreen.storyboard */; }; 16 | 42DDC7DC1D8F7022005409EE /* WBSegmentControl_ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7DB1D8F7022005409EE /* WBSegmentControl_ExampleTests.swift */; }; 17 | 42DDC7E71D8F7022005409EE /* WBSegmentControl_ExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7E61D8F7022005409EE /* WBSegmentControl_ExampleUITests.swift */; }; 18 | 42DDC7F81D8F72B4005409EE /* ViewController2.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7F71D8F72B4005409EE /* ViewController2.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 424209221E0CC1620081F7A1 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */; 25 | proxyType = 2; 26 | remoteGlobalIDString = 42DDC79D1D8F6F25005409EE; 27 | remoteInfo = WBSegmentControl; 28 | }; 29 | 424209241E0CC1620081F7A1 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */; 32 | proxyType = 2; 33 | remoteGlobalIDString = 42DDC7A61D8F6F25005409EE; 34 | remoteInfo = WBSegmentControlTests; 35 | }; 36 | 424209261E0CC1700081F7A1 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 42DDC79C1D8F6F25005409EE; 41 | remoteInfo = WBSegmentControl; 42 | }; 43 | 42DDC7D81D8F7022005409EE /* PBXContainerItemProxy */ = { 44 | isa = PBXContainerItemProxy; 45 | containerPortal = 42DDC7BB1D8F7022005409EE /* Project object */; 46 | proxyType = 1; 47 | remoteGlobalIDString = 42DDC7C21D8F7022005409EE; 48 | remoteInfo = "WBSegmentControl-Example"; 49 | }; 50 | 42DDC7E31D8F7022005409EE /* PBXContainerItemProxy */ = { 51 | isa = PBXContainerItemProxy; 52 | containerPortal = 42DDC7BB1D8F7022005409EE /* Project object */; 53 | proxyType = 1; 54 | remoteGlobalIDString = 42DDC7C21D8F7022005409EE; 55 | remoteInfo = "WBSegmentControl-Example"; 56 | }; 57 | /* End PBXContainerItemProxy section */ 58 | 59 | /* Begin PBXCopyFilesBuildPhase section */ 60 | 4294CB6E1DEB075E0053068B /* Embed Frameworks */ = { 61 | isa = PBXCopyFilesBuildPhase; 62 | buildActionMask = 2147483647; 63 | dstPath = ""; 64 | dstSubfolderSpec = 10; 65 | files = ( 66 | 424209291E0CC1860081F7A1 /* WBSegmentControl.framework in Embed Frameworks */, 67 | ); 68 | name = "Embed Frameworks"; 69 | runOnlyForDeploymentPostprocessing = 0; 70 | }; 71 | /* End PBXCopyFilesBuildPhase section */ 72 | 73 | /* Begin PBXFileReference section */ 74 | 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WBSegmentControl.xcodeproj; path = ../Framework/WBSegmentControl.xcodeproj; sourceTree = ""; }; 75 | 42DDC7C31D8F7022005409EE /* WBSegmentControl-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WBSegmentControl-Example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | 42DDC7C61D8F7022005409EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 77 | 42DDC7C81D8F7022005409EE /* ViewController1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController1.swift; sourceTree = ""; }; 78 | 42DDC7CD1D8F7022005409EE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 79 | 42DDC7D01D8F7022005409EE /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 80 | 42DDC7D21D8F7022005409EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 81 | 42DDC7D71D8F7022005409EE /* WBSegmentControl-ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WBSegmentControl-ExampleTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 82 | 42DDC7DB1D8F7022005409EE /* WBSegmentControl_ExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WBSegmentControl_ExampleTests.swift; sourceTree = ""; }; 83 | 42DDC7DD1D8F7022005409EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84 | 42DDC7E21D8F7022005409EE /* WBSegmentControl-ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WBSegmentControl-ExampleUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 85 | 42DDC7E61D8F7022005409EE /* WBSegmentControl_ExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WBSegmentControl_ExampleUITests.swift; sourceTree = ""; }; 86 | 42DDC7E81D8F7022005409EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 87 | 42DDC7F71D8F72B4005409EE /* ViewController2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController2.swift; sourceTree = ""; }; 88 | /* End PBXFileReference section */ 89 | 90 | /* Begin PBXFrameworksBuildPhase section */ 91 | 42A231161DE829C100351DA5 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | 424209281E0CC1790081F7A1 /* WBSegmentControl.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | 42DDC7D41D8F7022005409EE /* Frameworks */ = { 100 | isa = PBXFrameworksBuildPhase; 101 | buildActionMask = 2147483647; 102 | files = ( 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | 42DDC7DF1D8F7022005409EE /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | /* End PBXFrameworksBuildPhase section */ 114 | 115 | /* Begin PBXGroup section */ 116 | 4242091E1E0CC1620081F7A1 /* Products */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 424209231E0CC1620081F7A1 /* WBSegmentControl.framework */, 120 | 424209251E0CC1620081F7A1 /* WBSegmentControlTests.xctest */, 121 | ); 122 | name = Products; 123 | sourceTree = ""; 124 | }; 125 | 42DDC7BA1D8F7022005409EE = { 126 | isa = PBXGroup; 127 | children = ( 128 | 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */, 129 | 42DDC7C51D8F7022005409EE /* WBSegmentControl-Example */, 130 | 42DDC7DA1D8F7022005409EE /* WBSegmentControl-ExampleTests */, 131 | 42DDC7E51D8F7022005409EE /* WBSegmentControl-ExampleUITests */, 132 | 42DDC7C41D8F7022005409EE /* Products */, 133 | 42DDC7F41D8F728F005409EE /* Frameworks */, 134 | ); 135 | sourceTree = ""; 136 | }; 137 | 42DDC7C41D8F7022005409EE /* Products */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 42DDC7C31D8F7022005409EE /* WBSegmentControl-Example.app */, 141 | 42DDC7D71D8F7022005409EE /* WBSegmentControl-ExampleTests.xctest */, 142 | 42DDC7E21D8F7022005409EE /* WBSegmentControl-ExampleUITests.xctest */, 143 | ); 144 | name = Products; 145 | sourceTree = ""; 146 | }; 147 | 42DDC7C51D8F7022005409EE /* WBSegmentControl-Example */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 42DDC7C61D8F7022005409EE /* AppDelegate.swift */, 151 | 42DDC7C81D8F7022005409EE /* ViewController1.swift */, 152 | 42DDC7F71D8F72B4005409EE /* ViewController2.swift */, 153 | 42DDC7CD1D8F7022005409EE /* Assets.xcassets */, 154 | 42DDC7CF1D8F7022005409EE /* LaunchScreen.storyboard */, 155 | 42DDC7D21D8F7022005409EE /* Info.plist */, 156 | ); 157 | path = "WBSegmentControl-Example"; 158 | sourceTree = ""; 159 | }; 160 | 42DDC7DA1D8F7022005409EE /* WBSegmentControl-ExampleTests */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | 42DDC7DB1D8F7022005409EE /* WBSegmentControl_ExampleTests.swift */, 164 | 42DDC7DD1D8F7022005409EE /* Info.plist */, 165 | ); 166 | path = "WBSegmentControl-ExampleTests"; 167 | sourceTree = ""; 168 | }; 169 | 42DDC7E51D8F7022005409EE /* WBSegmentControl-ExampleUITests */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 42DDC7E61D8F7022005409EE /* WBSegmentControl_ExampleUITests.swift */, 173 | 42DDC7E81D8F7022005409EE /* Info.plist */, 174 | ); 175 | path = "WBSegmentControl-ExampleUITests"; 176 | sourceTree = ""; 177 | }; 178 | 42DDC7F41D8F728F005409EE /* Frameworks */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | ); 182 | name = Frameworks; 183 | sourceTree = ""; 184 | }; 185 | /* End PBXGroup section */ 186 | 187 | /* Begin PBXNativeTarget section */ 188 | 42DDC7C21D8F7022005409EE /* WBSegmentControl-Example */ = { 189 | isa = PBXNativeTarget; 190 | buildConfigurationList = 42DDC7EB1D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-Example" */; 191 | buildPhases = ( 192 | 42DDC7BF1D8F7022005409EE /* Sources */, 193 | 42A231161DE829C100351DA5 /* Frameworks */, 194 | 42DDC7C11D8F7022005409EE /* Resources */, 195 | 4294CB6E1DEB075E0053068B /* Embed Frameworks */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | 424209271E0CC1700081F7A1 /* PBXTargetDependency */, 201 | ); 202 | name = "WBSegmentControl-Example"; 203 | productName = "WBSegmentControl-Example"; 204 | productReference = 42DDC7C31D8F7022005409EE /* WBSegmentControl-Example.app */; 205 | productType = "com.apple.product-type.application"; 206 | }; 207 | 42DDC7D61D8F7022005409EE /* WBSegmentControl-ExampleTests */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 42DDC7EE1D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-ExampleTests" */; 210 | buildPhases = ( 211 | 42DDC7D31D8F7022005409EE /* Sources */, 212 | 42DDC7D41D8F7022005409EE /* Frameworks */, 213 | 42DDC7D51D8F7022005409EE /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | 42DDC7D91D8F7022005409EE /* PBXTargetDependency */, 219 | ); 220 | name = "WBSegmentControl-ExampleTests"; 221 | productName = "WBSegmentControl-ExampleTests"; 222 | productReference = 42DDC7D71D8F7022005409EE /* WBSegmentControl-ExampleTests.xctest */; 223 | productType = "com.apple.product-type.bundle.unit-test"; 224 | }; 225 | 42DDC7E11D8F7022005409EE /* WBSegmentControl-ExampleUITests */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = 42DDC7F11D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-ExampleUITests" */; 228 | buildPhases = ( 229 | 42DDC7DE1D8F7022005409EE /* Sources */, 230 | 42DDC7DF1D8F7022005409EE /* Frameworks */, 231 | 42DDC7E01D8F7022005409EE /* Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | 42DDC7E41D8F7022005409EE /* PBXTargetDependency */, 237 | ); 238 | name = "WBSegmentControl-ExampleUITests"; 239 | productName = "WBSegmentControl-ExampleUITests"; 240 | productReference = 42DDC7E21D8F7022005409EE /* WBSegmentControl-ExampleUITests.xctest */; 241 | productType = "com.apple.product-type.bundle.ui-testing"; 242 | }; 243 | /* End PBXNativeTarget section */ 244 | 245 | /* Begin PBXProject section */ 246 | 42DDC7BB1D8F7022005409EE /* Project object */ = { 247 | isa = PBXProject; 248 | attributes = { 249 | LastSwiftUpdateCheck = 0800; 250 | LastUpgradeCheck = 0800; 251 | ORGANIZATIONNAME = snowflyer; 252 | TargetAttributes = { 253 | 42DDC7C21D8F7022005409EE = { 254 | CreatedOnToolsVersion = 8.0; 255 | DevelopmentTeam = M793737CLS; 256 | ProvisioningStyle = Automatic; 257 | }; 258 | 42DDC7D61D8F7022005409EE = { 259 | CreatedOnToolsVersion = 8.0; 260 | ProvisioningStyle = Automatic; 261 | TestTargetID = 42DDC7C21D8F7022005409EE; 262 | }; 263 | 42DDC7E11D8F7022005409EE = { 264 | CreatedOnToolsVersion = 8.0; 265 | ProvisioningStyle = Automatic; 266 | TestTargetID = 42DDC7C21D8F7022005409EE; 267 | }; 268 | }; 269 | }; 270 | buildConfigurationList = 42DDC7BE1D8F7022005409EE /* Build configuration list for PBXProject "WBSegmentControl-Example" */; 271 | compatibilityVersion = "Xcode 3.2"; 272 | developmentRegion = English; 273 | hasScannedForEncodings = 0; 274 | knownRegions = ( 275 | en, 276 | Base, 277 | ); 278 | mainGroup = 42DDC7BA1D8F7022005409EE; 279 | productRefGroup = 42DDC7C41D8F7022005409EE /* Products */; 280 | projectDirPath = ""; 281 | projectReferences = ( 282 | { 283 | ProductGroup = 4242091E1E0CC1620081F7A1 /* Products */; 284 | ProjectRef = 4242091D1E0CC1620081F7A1 /* WBSegmentControl.xcodeproj */; 285 | }, 286 | ); 287 | projectRoot = ""; 288 | targets = ( 289 | 42DDC7C21D8F7022005409EE /* WBSegmentControl-Example */, 290 | 42DDC7D61D8F7022005409EE /* WBSegmentControl-ExampleTests */, 291 | 42DDC7E11D8F7022005409EE /* WBSegmentControl-ExampleUITests */, 292 | ); 293 | }; 294 | /* End PBXProject section */ 295 | 296 | /* Begin PBXReferenceProxy section */ 297 | 424209231E0CC1620081F7A1 /* WBSegmentControl.framework */ = { 298 | isa = PBXReferenceProxy; 299 | fileType = wrapper.framework; 300 | path = WBSegmentControl.framework; 301 | remoteRef = 424209221E0CC1620081F7A1 /* PBXContainerItemProxy */; 302 | sourceTree = BUILT_PRODUCTS_DIR; 303 | }; 304 | 424209251E0CC1620081F7A1 /* WBSegmentControlTests.xctest */ = { 305 | isa = PBXReferenceProxy; 306 | fileType = wrapper.cfbundle; 307 | path = WBSegmentControlTests.xctest; 308 | remoteRef = 424209241E0CC1620081F7A1 /* PBXContainerItemProxy */; 309 | sourceTree = BUILT_PRODUCTS_DIR; 310 | }; 311 | /* End PBXReferenceProxy section */ 312 | 313 | /* Begin PBXResourcesBuildPhase section */ 314 | 42DDC7C11D8F7022005409EE /* Resources */ = { 315 | isa = PBXResourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 42DDC7D11D8F7022005409EE /* LaunchScreen.storyboard in Resources */, 319 | 42DDC7CE1D8F7022005409EE /* Assets.xcassets in Resources */, 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | }; 323 | 42DDC7D51D8F7022005409EE /* Resources */ = { 324 | isa = PBXResourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | 42DDC7E01D8F7022005409EE /* Resources */ = { 331 | isa = PBXResourcesBuildPhase; 332 | buildActionMask = 2147483647; 333 | files = ( 334 | ); 335 | runOnlyForDeploymentPostprocessing = 0; 336 | }; 337 | /* End PBXResourcesBuildPhase section */ 338 | 339 | /* Begin PBXSourcesBuildPhase section */ 340 | 42DDC7BF1D8F7022005409EE /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | 42DDC7C91D8F7022005409EE /* ViewController1.swift in Sources */, 345 | 42DDC7C71D8F7022005409EE /* AppDelegate.swift in Sources */, 346 | 42DDC7F81D8F72B4005409EE /* ViewController2.swift in Sources */, 347 | ); 348 | runOnlyForDeploymentPostprocessing = 0; 349 | }; 350 | 42DDC7D31D8F7022005409EE /* Sources */ = { 351 | isa = PBXSourcesBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | 42DDC7DC1D8F7022005409EE /* WBSegmentControl_ExampleTests.swift in Sources */, 355 | ); 356 | runOnlyForDeploymentPostprocessing = 0; 357 | }; 358 | 42DDC7DE1D8F7022005409EE /* Sources */ = { 359 | isa = PBXSourcesBuildPhase; 360 | buildActionMask = 2147483647; 361 | files = ( 362 | 42DDC7E71D8F7022005409EE /* WBSegmentControl_ExampleUITests.swift in Sources */, 363 | ); 364 | runOnlyForDeploymentPostprocessing = 0; 365 | }; 366 | /* End PBXSourcesBuildPhase section */ 367 | 368 | /* Begin PBXTargetDependency section */ 369 | 424209271E0CC1700081F7A1 /* PBXTargetDependency */ = { 370 | isa = PBXTargetDependency; 371 | name = WBSegmentControl; 372 | targetProxy = 424209261E0CC1700081F7A1 /* PBXContainerItemProxy */; 373 | }; 374 | 42DDC7D91D8F7022005409EE /* PBXTargetDependency */ = { 375 | isa = PBXTargetDependency; 376 | target = 42DDC7C21D8F7022005409EE /* WBSegmentControl-Example */; 377 | targetProxy = 42DDC7D81D8F7022005409EE /* PBXContainerItemProxy */; 378 | }; 379 | 42DDC7E41D8F7022005409EE /* PBXTargetDependency */ = { 380 | isa = PBXTargetDependency; 381 | target = 42DDC7C21D8F7022005409EE /* WBSegmentControl-Example */; 382 | targetProxy = 42DDC7E31D8F7022005409EE /* PBXContainerItemProxy */; 383 | }; 384 | /* End PBXTargetDependency section */ 385 | 386 | /* Begin PBXVariantGroup section */ 387 | 42DDC7CF1D8F7022005409EE /* LaunchScreen.storyboard */ = { 388 | isa = PBXVariantGroup; 389 | children = ( 390 | 42DDC7D01D8F7022005409EE /* Base */, 391 | ); 392 | name = LaunchScreen.storyboard; 393 | sourceTree = ""; 394 | }; 395 | /* End PBXVariantGroup section */ 396 | 397 | /* Begin XCBuildConfiguration section */ 398 | 42DDC7E91D8F7022005409EE /* Debug */ = { 399 | isa = XCBuildConfiguration; 400 | buildSettings = { 401 | ALWAYS_SEARCH_USER_PATHS = NO; 402 | CLANG_ANALYZER_NONNULL = YES; 403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 404 | CLANG_CXX_LIBRARY = "libc++"; 405 | CLANG_ENABLE_MODULES = YES; 406 | CLANG_ENABLE_OBJC_ARC = YES; 407 | CLANG_WARN_BOOL_CONVERSION = YES; 408 | CLANG_WARN_CONSTANT_CONVERSION = 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_OBJC_ROOT_CLASS = YES_ERROR; 416 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 417 | CLANG_WARN_UNREACHABLE_CODE = YES; 418 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 419 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 420 | COPY_PHASE_STRIP = NO; 421 | DEBUG_INFORMATION_FORMAT = dwarf; 422 | ENABLE_STRICT_OBJC_MSGSEND = YES; 423 | ENABLE_TESTABILITY = YES; 424 | GCC_C_LANGUAGE_STANDARD = gnu99; 425 | GCC_DYNAMIC_NO_PIC = NO; 426 | GCC_NO_COMMON_BLOCKS = YES; 427 | GCC_OPTIMIZATION_LEVEL = 0; 428 | GCC_PREPROCESSOR_DEFINITIONS = ( 429 | "DEBUG=1", 430 | "$(inherited)", 431 | ); 432 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 433 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 434 | GCC_WARN_UNDECLARED_SELECTOR = YES; 435 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 436 | GCC_WARN_UNUSED_FUNCTION = YES; 437 | GCC_WARN_UNUSED_VARIABLE = YES; 438 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 439 | MTL_ENABLE_DEBUG_INFO = YES; 440 | ONLY_ACTIVE_ARCH = YES; 441 | SDKROOT = iphoneos; 442 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 443 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 444 | TARGETED_DEVICE_FAMILY = "1,2"; 445 | }; 446 | name = Debug; 447 | }; 448 | 42DDC7EA1D8F7022005409EE /* Release */ = { 449 | isa = XCBuildConfiguration; 450 | buildSettings = { 451 | ALWAYS_SEARCH_USER_PATHS = NO; 452 | CLANG_ANALYZER_NONNULL = YES; 453 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 454 | CLANG_CXX_LIBRARY = "libc++"; 455 | CLANG_ENABLE_MODULES = YES; 456 | CLANG_ENABLE_OBJC_ARC = YES; 457 | CLANG_WARN_BOOL_CONVERSION = YES; 458 | CLANG_WARN_CONSTANT_CONVERSION = YES; 459 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 460 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 461 | CLANG_WARN_EMPTY_BODY = YES; 462 | CLANG_WARN_ENUM_CONVERSION = YES; 463 | CLANG_WARN_INFINITE_RECURSION = YES; 464 | CLANG_WARN_INT_CONVERSION = YES; 465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 466 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 467 | CLANG_WARN_UNREACHABLE_CODE = YES; 468 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 469 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 470 | COPY_PHASE_STRIP = NO; 471 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 472 | ENABLE_NS_ASSERTIONS = NO; 473 | ENABLE_STRICT_OBJC_MSGSEND = YES; 474 | GCC_C_LANGUAGE_STANDARD = gnu99; 475 | GCC_NO_COMMON_BLOCKS = YES; 476 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 477 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 478 | GCC_WARN_UNDECLARED_SELECTOR = YES; 479 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 480 | GCC_WARN_UNUSED_FUNCTION = YES; 481 | GCC_WARN_UNUSED_VARIABLE = YES; 482 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 483 | MTL_ENABLE_DEBUG_INFO = NO; 484 | SDKROOT = iphoneos; 485 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 486 | TARGETED_DEVICE_FAMILY = "1,2"; 487 | VALIDATE_PRODUCT = YES; 488 | }; 489 | name = Release; 490 | }; 491 | 42DDC7EC1D8F7022005409EE /* Debug */ = { 492 | isa = XCBuildConfiguration; 493 | buildSettings = { 494 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 495 | DEVELOPMENT_TEAM = M793737CLS; 496 | FRAMEWORK_SEARCH_PATHS = ( 497 | "$(inherited)", 498 | "$(PROJECT_DIR)/WBSegmentControl-Example", 499 | "$(PROJECT_DIR)", 500 | ); 501 | INFOPLIST_FILE = "WBSegmentControl-Example/Info.plist"; 502 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 503 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-Example"; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | SWIFT_VERSION = 3.0; 506 | }; 507 | name = Debug; 508 | }; 509 | 42DDC7ED1D8F7022005409EE /* Release */ = { 510 | isa = XCBuildConfiguration; 511 | buildSettings = { 512 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 513 | DEVELOPMENT_TEAM = M793737CLS; 514 | FRAMEWORK_SEARCH_PATHS = ( 515 | "$(inherited)", 516 | "$(PROJECT_DIR)/WBSegmentControl-Example", 517 | "$(PROJECT_DIR)", 518 | ); 519 | INFOPLIST_FILE = "WBSegmentControl-Example/Info.plist"; 520 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 521 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-Example"; 522 | PRODUCT_NAME = "$(TARGET_NAME)"; 523 | SWIFT_VERSION = 3.0; 524 | }; 525 | name = Release; 526 | }; 527 | 42DDC7EF1D8F7022005409EE /* Debug */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 531 | BUNDLE_LOADER = "$(TEST_HOST)"; 532 | INFOPLIST_FILE = "WBSegmentControl-ExampleTests/Info.plist"; 533 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 534 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-ExampleTests"; 535 | PRODUCT_NAME = "$(TARGET_NAME)"; 536 | SWIFT_VERSION = 3.0; 537 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WBSegmentControl-Example.app/WBSegmentControl-Example"; 538 | }; 539 | name = Debug; 540 | }; 541 | 42DDC7F01D8F7022005409EE /* Release */ = { 542 | isa = XCBuildConfiguration; 543 | buildSettings = { 544 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 545 | BUNDLE_LOADER = "$(TEST_HOST)"; 546 | INFOPLIST_FILE = "WBSegmentControl-ExampleTests/Info.plist"; 547 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 548 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-ExampleTests"; 549 | PRODUCT_NAME = "$(TARGET_NAME)"; 550 | SWIFT_VERSION = 3.0; 551 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WBSegmentControl-Example.app/WBSegmentControl-Example"; 552 | }; 553 | name = Release; 554 | }; 555 | 42DDC7F21D8F7022005409EE /* Debug */ = { 556 | isa = XCBuildConfiguration; 557 | buildSettings = { 558 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 559 | INFOPLIST_FILE = "WBSegmentControl-ExampleUITests/Info.plist"; 560 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 561 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-ExampleUITests"; 562 | PRODUCT_NAME = "$(TARGET_NAME)"; 563 | SWIFT_VERSION = 3.0; 564 | TEST_TARGET_NAME = "WBSegmentControl-Example"; 565 | }; 566 | name = Debug; 567 | }; 568 | 42DDC7F31D8F7022005409EE /* Release */ = { 569 | isa = XCBuildConfiguration; 570 | buildSettings = { 571 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 572 | INFOPLIST_FILE = "WBSegmentControl-ExampleUITests/Info.plist"; 573 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 574 | PRODUCT_BUNDLE_IDENTIFIER = "com.snowflyer.WBSegmentControl-ExampleUITests"; 575 | PRODUCT_NAME = "$(TARGET_NAME)"; 576 | SWIFT_VERSION = 3.0; 577 | TEST_TARGET_NAME = "WBSegmentControl-Example"; 578 | }; 579 | name = Release; 580 | }; 581 | /* End XCBuildConfiguration section */ 582 | 583 | /* Begin XCConfigurationList section */ 584 | 42DDC7BE1D8F7022005409EE /* Build configuration list for PBXProject "WBSegmentControl-Example" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | 42DDC7E91D8F7022005409EE /* Debug */, 588 | 42DDC7EA1D8F7022005409EE /* Release */, 589 | ); 590 | defaultConfigurationIsVisible = 0; 591 | defaultConfigurationName = Release; 592 | }; 593 | 42DDC7EB1D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-Example" */ = { 594 | isa = XCConfigurationList; 595 | buildConfigurations = ( 596 | 42DDC7EC1D8F7022005409EE /* Debug */, 597 | 42DDC7ED1D8F7022005409EE /* Release */, 598 | ); 599 | defaultConfigurationIsVisible = 0; 600 | defaultConfigurationName = Release; 601 | }; 602 | 42DDC7EE1D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-ExampleTests" */ = { 603 | isa = XCConfigurationList; 604 | buildConfigurations = ( 605 | 42DDC7EF1D8F7022005409EE /* Debug */, 606 | 42DDC7F01D8F7022005409EE /* Release */, 607 | ); 608 | defaultConfigurationIsVisible = 0; 609 | defaultConfigurationName = Release; 610 | }; 611 | 42DDC7F11D8F7022005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl-ExampleUITests" */ = { 612 | isa = XCConfigurationList; 613 | buildConfigurations = ( 614 | 42DDC7F21D8F7022005409EE /* Debug */, 615 | 42DDC7F31D8F7022005409EE /* Release */, 616 | ); 617 | defaultConfigurationIsVisible = 0; 618 | defaultConfigurationName = Release; 619 | }; 620 | /* End XCConfigurationList section */ 621 | }; 622 | rootObject = 42DDC7BB1D8F7022005409EE /* Project object */; 623 | } 624 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // WBSegmentControl 4 | // 5 | // Created by xiongxiong on 04/24/2016. 6 | // Copyright (c) 2016 xiongxiong. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | window = UIWindow() 20 | 21 | let vcRoot = UITabBarController() 22 | let vc1 = ViewController1() 23 | vc1.tabBarItem.title = "item 1" 24 | let vc2 = ViewController2() 25 | vc2.tabBarItem.title = "item 2" 26 | vcRoot.setViewControllers([vc1, vc2], animated: false) 27 | 28 | window?.rootViewController = vcRoot 29 | window?.backgroundColor = UIColor.white 30 | window?.makeKeyAndVisible() 31 | 32 | return true 33 | } 34 | 35 | func applicationWillResignActive(_ application: UIApplication) { 36 | // 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. 37 | // 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. 38 | } 39 | 40 | func applicationDidEnterBackground(_ application: UIApplication) { 41 | // 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. 42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 43 | } 44 | 45 | func applicationWillEnterForeground(_ application: UIApplication) { 46 | // 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. 47 | } 48 | 49 | func applicationDidBecomeActive(_ application: UIApplication) { 50 | // 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. 51 | } 52 | 53 | func applicationWillTerminate(_ application: UIApplication) { 54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 55 | } 56 | 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/1454576025_icon-141-box-filled@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576025_icon-141-box-filled.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576025_icon-141-box-filled@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576025_icon-141-box-filled@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/1454576043_icon-40-clipboard-list@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576043_icon-40-clipboard-list.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576043_icon-40-clipboard-list@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576043_icon-40-clipboard-list@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/1454576053_icon-114-lock@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576053_icon-114-lock.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576053_icon-114-lock@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576053_icon-114-lock@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/1454576060_icon-144-box-bookmark@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576060_icon-144-box-bookmark.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576060_icon-144-box-bookmark@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576060_icon-144-box-bookmark@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/1454576071_icon-92-inbox-download@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576071_icon-92-inbox-download.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576071_icon-92-inbox-download@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576071_icon-92-inbox-download@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/1454576094_icon-115-lock-open@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1454576094_icon-115-lock-open.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1454576094_icon-115-lock-open@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1454576094_icon-115-lock-open@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/1461433662_snow_flake_3@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1461433662_snow_flake_3.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1461433662_snow_flake_3@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1461433662_snow_flake_3@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/1461434737_calendar@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1461434737_calendar.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1461434737_calendar@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1461434737_calendar@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82@2x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/1461434779_82@3x.png -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1461434779_82.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "1461434779_82@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "1461434779_82@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/ViewController1.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController1.swift 3 | // WBSegmentControl 4 | // 5 | // Created by 王继荣 on 7/5/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WBSegmentControl 11 | 12 | class ViewController1: UIViewController { 13 | 14 | var segmentControl: WBSegmentControl! 15 | var viewPages = UIView() 16 | var viewLabel = UILabel() 17 | var pagesController: UIPageViewController! 18 | var pages: [UIViewController] = [] 19 | 20 | override func loadView() { 21 | super.loadView() 22 | 23 | initSegmentControl() 24 | initPagesController() 25 | 26 | view.addSubview(segmentControl) 27 | view.addSubview(viewPages) 28 | viewPages.addSubview(pagesController.view) 29 | view.addSubview(viewLabel) 30 | 31 | segmentControl.translatesAutoresizingMaskIntoConstraints = false 32 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentControl])) 33 | view.addConstraint(NSLayoutConstraint(item: segmentControl, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: 0)) 34 | view.addConstraint(NSLayoutConstraint(item: segmentControl, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 35 | 36 | viewPages.gestureRecognizers = pagesController.gestureRecognizers 37 | viewPages.translatesAutoresizingMaskIntoConstraints = false 38 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[viewPages]|", options: .alignAllLeading, metrics: nil, views: ["viewPages": viewPages])) 39 | view.addConstraint(NSLayoutConstraint(item: viewPages, attribute: .top, relatedBy: .equal, toItem: segmentControl, attribute: .bottom, multiplier: 1, constant: 0)) 40 | view.addConstraint(NSLayoutConstraint(item: viewPages, attribute: .bottom, relatedBy: .equal, toItem: viewLabel, attribute: .top, multiplier: 1, constant: 0)) 41 | 42 | pagesController.view.translatesAutoresizingMaskIntoConstraints = false 43 | viewPages.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[pagesView]|", options: .alignAllLeading, metrics: nil, views: ["pagesView": pagesController.view])) 44 | viewPages.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[pagesView]|", options: .alignAllFirstBaseline, metrics: nil, views: ["pagesView": pagesController.view])) 45 | 46 | viewLabel.translatesAutoresizingMaskIntoConstraints = false 47 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[viewLabel]|", options: .alignAllLeading, metrics: nil, views: ["viewLabel": viewLabel])) 48 | view.addConstraint(NSLayoutConstraint(item: viewLabel, attribute: .top, relatedBy: .equal, toItem: self.bottomLayoutGuide, attribute: .top, multiplier: 1, constant: 0)) 49 | view.addConstraint(NSLayoutConstraint(item: viewLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 50 | 51 | viewLabel.textAlignment = .center 52 | viewLabel.textColor = UIColor.black 53 | viewLabel.backgroundColor = UIColor.white 54 | } 55 | 56 | override func viewDidLoad() { 57 | super.viewDidLoad() 58 | 59 | segmentControl.selectedIndex = 0 60 | } 61 | 62 | override func didReceiveMemoryWarning() { 63 | super.didReceiveMemoryWarning() 64 | // Dispose of any resources that can be recreated. 65 | } 66 | 67 | func initSegmentControl() { 68 | segmentControl = WBSegmentControl() 69 | segmentControl.segments = [ 70 | TextSegment(text: "News China", otherAttr: "News China"), 71 | TextSegment(text: "Breaking News", otherAttr: "Breaking News"), 72 | TextSegment(text: "World", otherAttr: "World"), 73 | TextSegment(text: "Science", otherAttr: "Science"), 74 | TextSegment(text: "Entertainment & Arts", otherAttr: "Entertainment & Arts"), 75 | TextSegment(text: "Finance", otherAttr: "Finance"), 76 | TextSegment(text: "Video", otherAttr: "Video"), 77 | TextSegment(text: "Radio", otherAttr: "Radio"), 78 | TextSegment(text: "Education", otherAttr: "Education"), 79 | TextSegment(text: "Sports", otherAttr: "Sports"), 80 | TextSegment(text: "Weather", otherAttr: "Weather"), 81 | TextSegment(text: "Headlines", otherAttr: "Headlines"), 82 | ] 83 | segmentControl.style = .rainbow 84 | segmentControl.segmentTextBold = false 85 | segmentControl.rainbow_colors = [ 86 | UIColor(red:0.91, green:0.18, blue:0.24, alpha:1.00), 87 | UIColor(red:1.00, green:0.71, blue:0.26, alpha:1.00), 88 | UIColor(red:0.47, green:0.78, blue:0.97, alpha:1.00) 89 | ] 90 | segmentControl.delegate = self 91 | } 92 | 93 | func initPagesController() { 94 | pagesController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil) 95 | pagesController.dataSource = self 96 | pagesController.delegate = self 97 | 98 | segmentControl.segments.enumerated().forEach { (index, _) in 99 | let vc = UIViewController() 100 | vc.view.backgroundColor = [ 101 | UIColor(red:0.91, green:0.18, blue:0.24, alpha:1.00), 102 | UIColor(red:1.00, green:0.71, blue:0.26, alpha:1.00), 103 | UIColor(red:0.47, green:0.78, blue:0.97, alpha:1.00) 104 | ][index % 3] 105 | pages.append(vc) 106 | } 107 | } 108 | 109 | } 110 | 111 | extension ViewController1: WBSegmentControlDelegate { 112 | func segmentControl(_ segmentControl: WBSegmentControl, selectIndex newIndex: Int, oldIndex: Int) { 113 | let targetPages = [pages[newIndex]] 114 | let direction = ((newIndex > oldIndex) ? UIPageViewControllerNavigationDirection.forward : UIPageViewControllerNavigationDirection.reverse) 115 | pagesController.setViewControllers(targetPages, direction: direction, animated: true, completion: nil) 116 | 117 | if let selectedSegment = segmentControl.selectedSegment as? TextSegment { 118 | viewLabel.text = selectedSegment.otherAttr 119 | } 120 | } 121 | } 122 | 123 | extension ViewController1: UIPageViewControllerDataSource { 124 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { 125 | let index = pages.index(of: viewController)! 126 | return index > 0 ? pages[index - 1] : nil 127 | } 128 | 129 | func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { 130 | let index = pages.index(of: viewController)! 131 | return index < pages.count - 1 ? pages[index + 1] : nil 132 | } 133 | 134 | func presentationCount(for pageViewController: UIPageViewController) -> Int { 135 | return pages.count 136 | } 137 | 138 | func presentationIndex(for pageViewController: UIPageViewController) -> Int { 139 | return 0 140 | } 141 | } 142 | 143 | extension ViewController1: UIPageViewControllerDelegate { 144 | func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 145 | if completed == false { 146 | guard let targetPage = previousViewControllers.first else { 147 | return 148 | } 149 | guard let targetIndex = pages.index(of: targetPage) else { 150 | return 151 | } 152 | segmentControl.selectedIndex = targetIndex 153 | pageViewController.setViewControllers(previousViewControllers, direction: .reverse, animated: true, completion: nil) 154 | } 155 | } 156 | 157 | func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { 158 | guard let targetPage = pendingViewControllers.first else { 159 | return 160 | } 161 | guard let targetIndex = pages.index(of: targetPage) else { 162 | return 163 | } 164 | segmentControl.selectedIndex = targetIndex 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-Example/ViewController2.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // WBSegmentControl 4 | // 5 | // Created by xiongxiong on 04/24/2016. 6 | // Copyright (c) 2016 xiongxiong. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import WBSegmentControl 11 | 12 | class ViewController2: UIViewController { 13 | 14 | let segmentCtrl_A = WBSegmentControl() 15 | let segmentCtrl_B = WBSegmentControl() 16 | let segmentCtrl_C = WBSegmentControl() 17 | let segmentCtrl_D = WBSegmentControl() 18 | let segmentCtrl_E = WBSegmentControl() 19 | let segmentCtrl_F = WBSegmentControl() 20 | let segmentCtrl_G = WBSegmentControl() 21 | 22 | override func loadView() { 23 | super.loadView() 24 | 25 | view.addSubview(segmentCtrl_A) 26 | segmentCtrl_A.translatesAutoresizingMaskIntoConstraints = false 27 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_A])) 28 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_A, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: 8)) 29 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_A, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 30 | segmentCtrl_A.segments = [ 31 | TextSegment(text: "News China"), 32 | TextSegment(text: "Breaking News"), 33 | TextSegment(text: "World"), 34 | TextSegment(text: "Science"), 35 | TextSegment(text: "Entertainment & Arts"), 36 | TextSegment(text: "Finance"), 37 | TextSegment(text: "Video"), 38 | TextSegment(text: "Radio"), 39 | TextSegment(text: "Education"), 40 | TextSegment(text: "Sports"), 41 | TextSegment(text: "Weather"), 42 | TextSegment(text: "Headlines"), 43 | ] 44 | segmentCtrl_A.style = .rainbow 45 | segmentCtrl_A.rainbow_colors = [ 46 | UIColor(red:0.91, green:0.18, blue:0.24, alpha:1.00), 47 | UIColor(red:1.00, green:0.71, blue:0.26, alpha:1.00), 48 | UIColor(red:0.47, green:0.78, blue:0.97, alpha:1.00) 49 | ] 50 | 51 | self.view.addSubview(segmentCtrl_B) 52 | segmentCtrl_B.translatesAutoresizingMaskIntoConstraints = false 53 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_B])) 54 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_B, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_A, attribute: .bottom, multiplier: 1, constant: 15)) 55 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_B, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 56 | segmentCtrl_B.segments = [ 57 | IconSegment(icon: UIImage(named: "1")!), 58 | IconSegment(icon: UIImage(named: "2")!), 59 | IconSegment(icon: UIImage(named: "3")!), 60 | IconSegment(icon: UIImage(named: "4")!), 61 | IconSegment(icon: UIImage(named: "5")!), 62 | IconSegment(icon: UIImage(named: "6")!), 63 | IconSegment(icon: UIImage(named: "7")!), 64 | IconSegment(icon: UIImage(named: "8")!), 65 | IconSegment(icon: UIImage(named: "9")!), 66 | ] 67 | segmentCtrl_B.style = .strip 68 | segmentCtrl_B.rainbow_colors = [ 69 | UIColor(red:0.91, green:0.18, blue:0.24, alpha:1.00), 70 | UIColor(red:1.00, green:0.71, blue:0.26, alpha:1.00), 71 | UIColor(red:0.47, green:0.78, blue:0.97, alpha:1.00) 72 | ] 73 | segmentCtrl_B.enableSlideway = false 74 | segmentCtrl_B.strip_range = .segment 75 | 76 | self.view.addSubview(segmentCtrl_C) 77 | segmentCtrl_C.translatesAutoresizingMaskIntoConstraints = false 78 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_C])) 79 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_C, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_B, attribute: .bottom, multiplier: 1, constant: 15)) 80 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_C, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 81 | segmentCtrl_C.segments = [ 82 | TextSegment(text: "News China"), 83 | TextSegment(text: "Breaking News"), 84 | TextSegment(text: "World"), 85 | TextSegment(text: "Science"), 86 | TextSegment(text: "Entertainment & Arts"), 87 | TextSegment(text: "Finance"), 88 | TextSegment(text: "Video"), 89 | TextSegment(text: "Radio"), 90 | TextSegment(text: "Education"), 91 | TextSegment(text: "Sports"), 92 | TextSegment(text: "Weather"), 93 | TextSegment(text: "Headlines"), 94 | ] 95 | segmentCtrl_C.style = .arrow 96 | segmentCtrl_C.enableSlideway = true 97 | segmentCtrl_C.enableSeparator = true 98 | 99 | self.view.addSubview(segmentCtrl_D) 100 | segmentCtrl_D.translatesAutoresizingMaskIntoConstraints = false 101 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_D])) 102 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_D, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_C, attribute: .bottom, multiplier: 1, constant: 15)) 103 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_D, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 104 | segmentCtrl_D.segments = [ 105 | TextSegment(text: "News China"), 106 | TextSegment(text: "Breaking News"), 107 | TextSegment(text: "World"), 108 | TextSegment(text: "Science"), 109 | TextSegment(text: "Entertainment & Arts"), 110 | TextSegment(text: "Finance"), 111 | TextSegment(text: "Video"), 112 | TextSegment(text: "Radio"), 113 | TextSegment(text: "Education"), 114 | TextSegment(text: "Sports"), 115 | TextSegment(text: "Weather"), 116 | TextSegment(text: "Headlines"), 117 | ] 118 | segmentCtrl_D.style = .arrowStrip 119 | 120 | self.view.addSubview(segmentCtrl_E) 121 | segmentCtrl_E.translatesAutoresizingMaskIntoConstraints = false 122 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_E])) 123 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_E, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_D, attribute: .bottom, multiplier: 1, constant: 15)) 124 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_E, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 125 | segmentCtrl_E.segments = [ 126 | TextSegment(text: "News China"), 127 | TextSegment(text: "Breaking News"), 128 | TextSegment(text: "World"), 129 | TextSegment(text: "Science"), 130 | TextSegment(text: "Entertainment & Arts"), 131 | TextSegment(text: "Finance"), 132 | TextSegment(text: "Video"), 133 | TextSegment(text: "Radio"), 134 | TextSegment(text: "Education"), 135 | TextSegment(text: "Sports"), 136 | TextSegment(text: "Weather"), 137 | TextSegment(text: "Headlines"), 138 | ] 139 | segmentCtrl_E.style = .arrowStrip 140 | segmentCtrl_E.enableSlideway = false 141 | 142 | self.view.addSubview(segmentCtrl_F) 143 | segmentCtrl_F.translatesAutoresizingMaskIntoConstraints = false 144 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_F])) 145 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_F, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_E, attribute: .bottom, multiplier: 1, constant: 15)) 146 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_F, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 147 | segmentCtrl_F.segments = [ 148 | TextSegment(text: "News China"), 149 | TextSegment(text: "Breaking News"), 150 | TextSegment(text: "World"), 151 | TextSegment(text: "Science"), 152 | TextSegment(text: "Entertainment & Arts"), 153 | TextSegment(text: "Finance"), 154 | TextSegment(text: "Video"), 155 | TextSegment(text: "Radio"), 156 | TextSegment(text: "Education"), 157 | TextSegment(text: "Sports"), 158 | TextSegment(text: "Weather"), 159 | TextSegment(text: "Headlines"), 160 | ] 161 | segmentCtrl_F.style = .cover 162 | segmentCtrl_F.backgroundColor = UIColor.cyan 163 | 164 | self.view.addSubview(segmentCtrl_G) 165 | segmentCtrl_G.translatesAutoresizingMaskIntoConstraints = false 166 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[segmentControl]|", options: .alignAllLeading, metrics: nil, views: ["segmentControl": segmentCtrl_G])) 167 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_G, attribute: .top, relatedBy: .equal, toItem: segmentCtrl_F, attribute: .bottom, multiplier: 1, constant: 15)) 168 | view.addConstraint(NSLayoutConstraint(item: segmentCtrl_G, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0, constant: 40)) 169 | segmentCtrl_G.segments = [ 170 | TextSegment(text: "News China"), 171 | TextSegment(text: "World"), 172 | TextSegment(text: "Science"), 173 | ] 174 | segmentCtrl_G.style = .strip 175 | segmentCtrl_G.nonScrollDistributionStyle = .center 176 | } 177 | 178 | override func viewDidLoad() { 179 | super.viewDidLoad() 180 | 181 | segmentCtrl_A.selectedIndex = 0 182 | segmentCtrl_B.selectedIndex = 0 183 | segmentCtrl_C.selectedIndex = 0 184 | segmentCtrl_D.selectedIndex = 0 185 | segmentCtrl_E.selectedIndex = 0 186 | segmentCtrl_F.selectedIndex = 0 187 | segmentCtrl_G.selectedIndex = 0 188 | } 189 | } 190 | 191 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-ExampleTests/WBSegmentControl_ExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WBSegmentControl_ExampleTests.swift 3 | // WBSegmentControl-ExampleTests 4 | // 5 | // Created by 王继荣 on 9/19/16. 6 | // Copyright © 2016 snowflyer. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import WBSegmentControl_Example 11 | 12 | class WBSegmentControl_ExampleTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-ExampleUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/WBSegmentControl-ExampleUITests/WBSegmentControl_ExampleUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WBSegmentControl_ExampleUITests.swift 3 | // WBSegmentControl-ExampleUITests 4 | // 5 | // Created by 王继荣 on 9/19/16. 6 | // Copyright © 2016 snowflyer. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class WBSegmentControl_ExampleUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Framework/ScreenShot/Simulator Screen Shot 27 Nov 2016, 8.10.29 PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Framework/ScreenShot/Simulator Screen Shot 27 Nov 2016, 8.10.29 PM.png -------------------------------------------------------------------------------- /Framework/ScreenShot/Simulator Screen Shot 27 Nov 2016, 8.10.29 PM_result1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Framework/ScreenShot/Simulator Screen Shot 27 Nov 2016, 8.10.29 PM_result1.jpg -------------------------------------------------------------------------------- /Framework/ScreenShot/WBSegmentControl.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiongxiong/WBSegmentControl/4fb41ee18b811d4446f680c1549379d89c0bc718/Framework/ScreenShot/WBSegmentControl.gif -------------------------------------------------------------------------------- /Framework/WBSegmentControl.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint WBSegmentControl.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = "WBSegmentControl" 11 | s.version = "0.2.2" 12 | s.summary = "An easy to use, customizable segment control." 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | WBSegmentedControl is an easy to use, customizable segment control, has several effects, can be used to show labels or tabs. 22 | DESC 23 | 24 | s.homepage = "https://github.com/xiongxiong/WBSegmentControl" 25 | # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" 26 | s.license = 'MIT' 27 | s.author = { "xiongxiong" => "ximengwuheng@163.com" } 28 | s.source = { :git => "https://github.com/xiongxiong/WBSegmentControl.git", :tag => s.version.to_s } 29 | # s.social_media_url = 'https://twitter.com/' 30 | 31 | s.ios.deployment_target = '8.0' 32 | 33 | s.source_files = 'Framework/WBSegmentControl/**/*' 34 | # s.resource_bundles = { 35 | # 'WBSegmentControl' => ['WBSegmentControl/Assets/*.png'] 36 | # } 37 | 38 | s.public_header_files = 'Framework/WBSegmentControl/*.h' 39 | s.frameworks = 'UIKit' 40 | # s.dependency 'AFNetworking', '~> 2.3' 41 | end 42 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 42DDC7A71D8F6F25005409EE /* WBSegmentControl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 42DDC79D1D8F6F25005409EE /* WBSegmentControl.framework */; }; 11 | 42DDC7AC1D8F6F25005409EE /* WBSegmentControlTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7AB1D8F6F25005409EE /* WBSegmentControlTests.swift */; }; 12 | 42DDC7AE1D8F6F25005409EE /* WBSegmentControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 42DDC7A01D8F6F25005409EE /* WBSegmentControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 42DDC7B91D8F6FB3005409EE /* WBSegmentControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7B81D8F6FB3005409EE /* WBSegmentControl.swift */; }; 14 | 42DDC7FA1D8F77F7005409EE /* WBSegments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42DDC7F91D8F77F7005409EE /* WBSegments.swift */; }; 15 | /* End PBXBuildFile section */ 16 | 17 | /* Begin PBXContainerItemProxy section */ 18 | 42DDC7A81D8F6F25005409EE /* PBXContainerItemProxy */ = { 19 | isa = PBXContainerItemProxy; 20 | containerPortal = 42DDC7941D8F6F25005409EE /* Project object */; 21 | proxyType = 1; 22 | remoteGlobalIDString = 42DDC79C1D8F6F25005409EE; 23 | remoteInfo = WBSegmentControl; 24 | }; 25 | /* End PBXContainerItemProxy section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 42DDC79D1D8F6F25005409EE /* WBSegmentControl.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WBSegmentControl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 42DDC7A01D8F6F25005409EE /* WBSegmentControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WBSegmentControl.h; sourceTree = ""; }; 30 | 42DDC7A11D8F6F25005409EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 42DDC7A61D8F6F25005409EE /* WBSegmentControlTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WBSegmentControlTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 42DDC7AB1D8F6F25005409EE /* WBSegmentControlTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WBSegmentControlTests.swift; sourceTree = ""; }; 33 | 42DDC7AD1D8F6F25005409EE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | 42DDC7B81D8F6FB3005409EE /* WBSegmentControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WBSegmentControl.swift; sourceTree = ""; }; 35 | 42DDC7F91D8F77F7005409EE /* WBSegments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WBSegments.swift; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 42DDC7991D8F6F25005409EE /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | ); 44 | runOnlyForDeploymentPostprocessing = 0; 45 | }; 46 | 42DDC7A31D8F6F25005409EE /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 42DDC7A71D8F6F25005409EE /* WBSegmentControl.framework in Frameworks */, 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | 42DDC7931D8F6F25005409EE = { 58 | isa = PBXGroup; 59 | children = ( 60 | 42DDC79F1D8F6F25005409EE /* WBSegmentControl */, 61 | 42DDC7AA1D8F6F25005409EE /* WBSegmentControlTests */, 62 | 42DDC79E1D8F6F25005409EE /* Products */, 63 | ); 64 | sourceTree = ""; 65 | }; 66 | 42DDC79E1D8F6F25005409EE /* Products */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 42DDC79D1D8F6F25005409EE /* WBSegmentControl.framework */, 70 | 42DDC7A61D8F6F25005409EE /* WBSegmentControlTests.xctest */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | 42DDC79F1D8F6F25005409EE /* WBSegmentControl */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 42DDC7B81D8F6FB3005409EE /* WBSegmentControl.swift */, 79 | 42DDC7F91D8F77F7005409EE /* WBSegments.swift */, 80 | 42DDC7B71D8F6F3B005409EE /* Support Files */, 81 | ); 82 | path = WBSegmentControl; 83 | sourceTree = ""; 84 | }; 85 | 42DDC7AA1D8F6F25005409EE /* WBSegmentControlTests */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 42DDC7AB1D8F6F25005409EE /* WBSegmentControlTests.swift */, 89 | 42DDC7AD1D8F6F25005409EE /* Info.plist */, 90 | ); 91 | path = WBSegmentControlTests; 92 | sourceTree = ""; 93 | }; 94 | 42DDC7B71D8F6F3B005409EE /* Support Files */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 42DDC7A01D8F6F25005409EE /* WBSegmentControl.h */, 98 | 42DDC7A11D8F6F25005409EE /* Info.plist */, 99 | ); 100 | name = "Support Files"; 101 | sourceTree = ""; 102 | }; 103 | /* End PBXGroup section */ 104 | 105 | /* Begin PBXHeadersBuildPhase section */ 106 | 42DDC79A1D8F6F25005409EE /* Headers */ = { 107 | isa = PBXHeadersBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | 42DDC7AE1D8F6F25005409EE /* WBSegmentControl.h in Headers */, 111 | ); 112 | runOnlyForDeploymentPostprocessing = 0; 113 | }; 114 | /* End PBXHeadersBuildPhase section */ 115 | 116 | /* Begin PBXNativeTarget section */ 117 | 42DDC79C1D8F6F25005409EE /* WBSegmentControl */ = { 118 | isa = PBXNativeTarget; 119 | buildConfigurationList = 42DDC7B11D8F6F25005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl" */; 120 | buildPhases = ( 121 | 42DDC7981D8F6F25005409EE /* Sources */, 122 | 42DDC7991D8F6F25005409EE /* Frameworks */, 123 | 42DDC79A1D8F6F25005409EE /* Headers */, 124 | 42DDC79B1D8F6F25005409EE /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = WBSegmentControl; 131 | productName = WBSegmentControl; 132 | productReference = 42DDC79D1D8F6F25005409EE /* WBSegmentControl.framework */; 133 | productType = "com.apple.product-type.framework"; 134 | }; 135 | 42DDC7A51D8F6F25005409EE /* WBSegmentControlTests */ = { 136 | isa = PBXNativeTarget; 137 | buildConfigurationList = 42DDC7B41D8F6F25005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControlTests" */; 138 | buildPhases = ( 139 | 42DDC7A21D8F6F25005409EE /* Sources */, 140 | 42DDC7A31D8F6F25005409EE /* Frameworks */, 141 | 42DDC7A41D8F6F25005409EE /* Resources */, 142 | ); 143 | buildRules = ( 144 | ); 145 | dependencies = ( 146 | 42DDC7A91D8F6F25005409EE /* PBXTargetDependency */, 147 | ); 148 | name = WBSegmentControlTests; 149 | productName = WBSegmentControlTests; 150 | productReference = 42DDC7A61D8F6F25005409EE /* WBSegmentControlTests.xctest */; 151 | productType = "com.apple.product-type.bundle.unit-test"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 42DDC7941D8F6F25005409EE /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastSwiftUpdateCheck = 0800; 160 | LastUpgradeCheck = 0800; 161 | ORGANIZATIONNAME = snowflyer; 162 | TargetAttributes = { 163 | 42DDC79C1D8F6F25005409EE = { 164 | CreatedOnToolsVersion = 8.0; 165 | LastSwiftMigration = 0800; 166 | ProvisioningStyle = Automatic; 167 | }; 168 | 42DDC7A51D8F6F25005409EE = { 169 | CreatedOnToolsVersion = 8.0; 170 | ProvisioningStyle = Automatic; 171 | }; 172 | }; 173 | }; 174 | buildConfigurationList = 42DDC7971D8F6F25005409EE /* Build configuration list for PBXProject "WBSegmentControl" */; 175 | compatibilityVersion = "Xcode 3.2"; 176 | developmentRegion = English; 177 | hasScannedForEncodings = 0; 178 | knownRegions = ( 179 | en, 180 | ); 181 | mainGroup = 42DDC7931D8F6F25005409EE; 182 | productRefGroup = 42DDC79E1D8F6F25005409EE /* Products */; 183 | projectDirPath = ""; 184 | projectRoot = ""; 185 | targets = ( 186 | 42DDC79C1D8F6F25005409EE /* WBSegmentControl */, 187 | 42DDC7A51D8F6F25005409EE /* WBSegmentControlTests */, 188 | ); 189 | }; 190 | /* End PBXProject section */ 191 | 192 | /* Begin PBXResourcesBuildPhase section */ 193 | 42DDC79B1D8F6F25005409EE /* Resources */ = { 194 | isa = PBXResourcesBuildPhase; 195 | buildActionMask = 2147483647; 196 | files = ( 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | 42DDC7A41D8F6F25005409EE /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXResourcesBuildPhase section */ 208 | 209 | /* Begin PBXSourcesBuildPhase section */ 210 | 42DDC7981D8F6F25005409EE /* Sources */ = { 211 | isa = PBXSourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | 42DDC7FA1D8F77F7005409EE /* WBSegments.swift in Sources */, 215 | 42DDC7B91D8F6FB3005409EE /* WBSegmentControl.swift in Sources */, 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | }; 219 | 42DDC7A21D8F6F25005409EE /* Sources */ = { 220 | isa = PBXSourcesBuildPhase; 221 | buildActionMask = 2147483647; 222 | files = ( 223 | 42DDC7AC1D8F6F25005409EE /* WBSegmentControlTests.swift in Sources */, 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | /* End PBXSourcesBuildPhase section */ 228 | 229 | /* Begin PBXTargetDependency section */ 230 | 42DDC7A91D8F6F25005409EE /* PBXTargetDependency */ = { 231 | isa = PBXTargetDependency; 232 | target = 42DDC79C1D8F6F25005409EE /* WBSegmentControl */; 233 | targetProxy = 42DDC7A81D8F6F25005409EE /* PBXContainerItemProxy */; 234 | }; 235 | /* End PBXTargetDependency section */ 236 | 237 | /* Begin XCBuildConfiguration section */ 238 | 42DDC7AF1D8F6F25005409EE /* Debug */ = { 239 | isa = XCBuildConfiguration; 240 | buildSettings = { 241 | ALWAYS_SEARCH_USER_PATHS = NO; 242 | CLANG_ANALYZER_NONNULL = YES; 243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 244 | CLANG_CXX_LIBRARY = "libc++"; 245 | CLANG_ENABLE_MODULES = YES; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_BOOL_CONVERSION = YES; 248 | CLANG_WARN_CONSTANT_CONVERSION = YES; 249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 251 | CLANG_WARN_EMPTY_BODY = YES; 252 | CLANG_WARN_ENUM_CONVERSION = YES; 253 | CLANG_WARN_INFINITE_RECURSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 256 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 257 | CLANG_WARN_UNREACHABLE_CODE = YES; 258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 259 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 260 | COPY_PHASE_STRIP = NO; 261 | CURRENT_PROJECT_VERSION = 1; 262 | DEBUG_INFORMATION_FORMAT = dwarf; 263 | ENABLE_STRICT_OBJC_MSGSEND = YES; 264 | ENABLE_TESTABILITY = YES; 265 | GCC_C_LANGUAGE_STANDARD = gnu99; 266 | GCC_DYNAMIC_NO_PIC = NO; 267 | GCC_NO_COMMON_BLOCKS = YES; 268 | GCC_OPTIMIZATION_LEVEL = 0; 269 | GCC_PREPROCESSOR_DEFINITIONS = ( 270 | "DEBUG=1", 271 | "$(inherited)", 272 | ); 273 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 274 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 275 | GCC_WARN_UNDECLARED_SELECTOR = YES; 276 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 277 | GCC_WARN_UNUSED_FUNCTION = YES; 278 | GCC_WARN_UNUSED_VARIABLE = YES; 279 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 280 | MTL_ENABLE_DEBUG_INFO = YES; 281 | ONLY_ACTIVE_ARCH = YES; 282 | SDKROOT = iphoneos; 283 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 284 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 285 | TARGETED_DEVICE_FAMILY = "1,2"; 286 | VERSIONING_SYSTEM = "apple-generic"; 287 | VERSION_INFO_PREFIX = ""; 288 | }; 289 | name = Debug; 290 | }; 291 | 42DDC7B01D8F6F25005409EE /* Release */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ALWAYS_SEARCH_USER_PATHS = NO; 295 | CLANG_ANALYZER_NONNULL = YES; 296 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 297 | CLANG_CXX_LIBRARY = "libc++"; 298 | CLANG_ENABLE_MODULES = YES; 299 | CLANG_ENABLE_OBJC_ARC = YES; 300 | CLANG_WARN_BOOL_CONVERSION = YES; 301 | CLANG_WARN_CONSTANT_CONVERSION = YES; 302 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 303 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 304 | CLANG_WARN_EMPTY_BODY = YES; 305 | CLANG_WARN_ENUM_CONVERSION = YES; 306 | CLANG_WARN_INFINITE_RECURSION = YES; 307 | CLANG_WARN_INT_CONVERSION = YES; 308 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 309 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 310 | CLANG_WARN_UNREACHABLE_CODE = YES; 311 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 312 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 313 | COPY_PHASE_STRIP = NO; 314 | CURRENT_PROJECT_VERSION = 1; 315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 316 | ENABLE_NS_ASSERTIONS = NO; 317 | ENABLE_STRICT_OBJC_MSGSEND = YES; 318 | GCC_C_LANGUAGE_STANDARD = gnu99; 319 | GCC_NO_COMMON_BLOCKS = YES; 320 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 321 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 322 | GCC_WARN_UNDECLARED_SELECTOR = YES; 323 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 324 | GCC_WARN_UNUSED_FUNCTION = YES; 325 | GCC_WARN_UNUSED_VARIABLE = YES; 326 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 327 | MTL_ENABLE_DEBUG_INFO = NO; 328 | SDKROOT = iphoneos; 329 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 330 | TARGETED_DEVICE_FAMILY = "1,2"; 331 | VALIDATE_PRODUCT = YES; 332 | VERSIONING_SYSTEM = "apple-generic"; 333 | VERSION_INFO_PREFIX = ""; 334 | }; 335 | name = Release; 336 | }; 337 | 42DDC7B21D8F6F25005409EE /* Debug */ = { 338 | isa = XCBuildConfiguration; 339 | buildSettings = { 340 | CLANG_ENABLE_MODULES = YES; 341 | CODE_SIGN_IDENTITY = ""; 342 | DEFINES_MODULE = YES; 343 | DYLIB_COMPATIBILITY_VERSION = 1; 344 | DYLIB_CURRENT_VERSION = 1; 345 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 346 | INFOPLIST_FILE = WBSegmentControl/Info.plist; 347 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 348 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 349 | PRODUCT_BUNDLE_IDENTIFIER = com.snowflyer.WBSegmentControl; 350 | PRODUCT_NAME = "$(TARGET_NAME)"; 351 | SKIP_INSTALL = YES; 352 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 353 | SWIFT_VERSION = 3.0; 354 | }; 355 | name = Debug; 356 | }; 357 | 42DDC7B31D8F6F25005409EE /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | CLANG_ENABLE_MODULES = YES; 361 | CODE_SIGN_IDENTITY = ""; 362 | DEFINES_MODULE = YES; 363 | DYLIB_COMPATIBILITY_VERSION = 1; 364 | DYLIB_CURRENT_VERSION = 1; 365 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 366 | INFOPLIST_FILE = WBSegmentControl/Info.plist; 367 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 369 | PRODUCT_BUNDLE_IDENTIFIER = com.snowflyer.WBSegmentControl; 370 | PRODUCT_NAME = "$(TARGET_NAME)"; 371 | SKIP_INSTALL = YES; 372 | SWIFT_VERSION = 3.0; 373 | }; 374 | name = Release; 375 | }; 376 | 42DDC7B51D8F6F25005409EE /* Debug */ = { 377 | isa = XCBuildConfiguration; 378 | buildSettings = { 379 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 380 | INFOPLIST_FILE = WBSegmentControlTests/Info.plist; 381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 382 | PRODUCT_BUNDLE_IDENTIFIER = com.snowflyer.WBSegmentControlTests; 383 | PRODUCT_NAME = "$(TARGET_NAME)"; 384 | SWIFT_VERSION = 3.0; 385 | }; 386 | name = Debug; 387 | }; 388 | 42DDC7B61D8F6F25005409EE /* Release */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 392 | INFOPLIST_FILE = WBSegmentControlTests/Info.plist; 393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 394 | PRODUCT_BUNDLE_IDENTIFIER = com.snowflyer.WBSegmentControlTests; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SWIFT_VERSION = 3.0; 397 | }; 398 | name = Release; 399 | }; 400 | /* End XCBuildConfiguration section */ 401 | 402 | /* Begin XCConfigurationList section */ 403 | 42DDC7971D8F6F25005409EE /* Build configuration list for PBXProject "WBSegmentControl" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | 42DDC7AF1D8F6F25005409EE /* Debug */, 407 | 42DDC7B01D8F6F25005409EE /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | 42DDC7B11D8F6F25005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControl" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | 42DDC7B21D8F6F25005409EE /* Debug */, 416 | 42DDC7B31D8F6F25005409EE /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | defaultConfigurationName = Release; 420 | }; 421 | 42DDC7B41D8F6F25005409EE /* Build configuration list for PBXNativeTarget "WBSegmentControlTests" */ = { 422 | isa = XCConfigurationList; 423 | buildConfigurations = ( 424 | 42DDC7B51D8F6F25005409EE /* Debug */, 425 | 42DDC7B61D8F6F25005409EE /* Release */, 426 | ); 427 | defaultConfigurationIsVisible = 0; 428 | defaultConfigurationName = Release; 429 | }; 430 | /* End XCConfigurationList section */ 431 | }; 432 | rootObject = 42DDC7941D8F6F25005409EE /* Project object */; 433 | } 434 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl.xcodeproj/xcshareddata/xcschemes/WBSegmentControl.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl/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 | 0.2.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl/WBSegmentControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // WBSegmentControl.h 3 | // WBSegmentControl 4 | // 5 | // Created by 王继荣 on 9/19/16. 6 | // Copyright © 2016 snowflyer. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for WBSegmentControl. 12 | FOUNDATION_EXPORT double WBSegmentControlVersionNumber; 13 | 14 | //! Project version string for WBSegmentControl. 15 | FOUNDATION_EXPORT const unsigned char WBSegmentControlVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl/WBSegmentControl.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomSegmentControl2.swift 3 | // TrafficSecretary 4 | // 5 | // Created by 王继荣 on 4/9/16. 6 | // Copyright © 2016 wonderbear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol WBSegmentControlDelegate: class { 12 | func segmentControl(_ segmentControl: WBSegmentControl, selectIndex newIndex: Int, oldIndex: Int) 13 | } 14 | 15 | public protocol WBSegmentContentProtocol { 16 | var type: WBSegmentType { get } 17 | } 18 | 19 | public protocol WBTouchViewDelegate { 20 | func didTouch(_ location: CGPoint) 21 | } 22 | 23 | public class WBSegmentControl: UIControl { 24 | 25 | // MARK: Configuration - Content 26 | public var segments: [WBSegmentContentProtocol] = [] { 27 | didSet { 28 | innerSegments = segments.map({ (content) -> WBInnerSegment in 29 | return WBInnerSegment(content: content) 30 | }) 31 | self.setNeedsLayout() 32 | if segments.count == 0 { 33 | selectedIndex = -1 34 | } 35 | } 36 | } 37 | var innerSegments: [WBInnerSegment] = [] 38 | 39 | // MARK: Configuration - Interaction 40 | public weak var delegate: WBSegmentControlDelegate? 41 | public var selectedIndex: Int = -1 { 42 | didSet { 43 | if selectedIndex != oldValue && validIndex(selectedIndex) { 44 | selectedIndexChanged(selectedIndex, oldIndex: oldValue) 45 | delegate?.segmentControl(self, selectIndex: selectedIndex, oldIndex: oldValue) 46 | } 47 | } 48 | } 49 | public var selectedSegment: WBSegmentContentProtocol? { 50 | return validIndex(selectedIndex) ? segments[selectedIndex] : nil 51 | } 52 | 53 | // MARK: Configuration - Appearance 54 | public var style: WBSegmentIndicatorStyle = .rainbow 55 | public var nonScrollDistributionStyle: WBSegmentNonScrollDistributionStyle = .average 56 | public var enableSeparator: Bool = false 57 | public var separatorColor: UIColor = UIColor.black 58 | public var separatorWidth: CGFloat = 9 59 | public var separatorEdgeInsets: UIEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 4) 60 | public var enableSlideway: Bool = false 61 | public var slidewayHeight: CGFloat = 1 62 | public var slidewayColor: UIColor = UIColor.lightGray 63 | public var enableAnimation: Bool = true 64 | public var animationDuration: TimeInterval = 0.15 65 | public var segmentMinWidth: CGFloat = 50 66 | public var segmentEdgeInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) 67 | public var segmentTextBold: Bool = true 68 | public var segmentTextFontSize: CGFloat = 12 69 | public var segmentForegroundColor: UIColor = UIColor.gray 70 | public var segmentForegroundColorSelected: UIColor = UIColor.black 71 | 72 | // Settings - Cover 73 | public typealias CoverRange = WBSegmentIndicatorRange 74 | 75 | public var cover_range: CoverRange = .segment 76 | public var cover_opacity: Float = 0.2 77 | public var cover_color: UIColor = UIColor.black 78 | 79 | // Settings - Strip 80 | public typealias StripRange = WBSegmentIndicatorRange 81 | public typealias StripLocation = WBSegmentIndicatorLocation 82 | 83 | public var strip_range: StripRange = .content 84 | public var strip_location: StripLocation = .down 85 | public var strip_color: UIColor = UIColor.orange 86 | public var strip_height: CGFloat = 3 87 | 88 | // Settings - Rainbow 89 | public typealias RainbowLocation = WBSegmentIndicatorLocation 90 | 91 | public var rainbow_colors: [UIColor] = [] 92 | public var rainbow_height: CGFloat = 3 93 | public var rainbow_roundCornerRadius: CGFloat = 4 94 | public var rainbow_location: RainbowLocation = .down 95 | public var rainbow_outsideColor: UIColor = UIColor.gray 96 | 97 | // Settings - Arrow 98 | public typealias ArrowLocation = WBSegmentIndicatorLocation 99 | 100 | public var arrow_size: CGSize = CGSize(width: 6, height: 6) 101 | public var arrow_location: ArrowLocation = .down 102 | public var arrow_color: UIColor = UIColor.orange 103 | 104 | // Settings - ArrowStrip 105 | public typealias ArrowStripLocation = WBSegmentIndicatorLocation 106 | public typealias ArrowStripRange = WBSegmentIndicatorRange 107 | 108 | public var arrowStrip_location: ArrowStripLocation = .up 109 | public var arrowStrip_color: UIColor = UIColor.orange 110 | public var arrowStrip_arrowSize: CGSize = CGSize(width: 6, height: 6) 111 | public var arrowStrip_stripHeight: CGFloat = 2 112 | public var arrowStrip_stripRange: ArrowStripRange = .content 113 | 114 | // MARK: Inner properties 115 | fileprivate var scrollView: UIScrollView! 116 | fileprivate var touchView: WBTouchView = WBTouchView() 117 | fileprivate var layerContainer: CALayer = CALayer() 118 | fileprivate var layerCover: CALayer = CALayer() 119 | fileprivate var layerStrip: CALayer = CALayer() 120 | fileprivate var layerArrow: CALayer = CALayer() 121 | fileprivate var segmentControlContentWidth: CGFloat { 122 | let sum = self.innerSegments.reduce(0, { (max_x, segment) -> CGFloat in 123 | return max(max_x, segment.segmentFrame.maxX) 124 | }) 125 | return sum + ((self.enableSeparator && self.style != .rainbow) ? self.separatorWidth / 2 : 0) 126 | } 127 | 128 | // MARK: Initialization 129 | override init(frame: CGRect) { 130 | super.init(frame: frame) 131 | 132 | scrollView = UIScrollView() 133 | self.addSubview(scrollView) 134 | scrollView.translatesAutoresizingMaskIntoConstraints = false 135 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0)) 136 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)) 137 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)) 138 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0)) 139 | scrollView.showsHorizontalScrollIndicator = false 140 | scrollView.showsVerticalScrollIndicator = false 141 | scrollView.layer.addSublayer(layerContainer) 142 | 143 | scrollView.addSubview(touchView) 144 | touchView.delegate = self 145 | } 146 | 147 | required public init?(coder aDecoder: NSCoder) { 148 | fatalError("init(coder:) has not been implemented") 149 | } 150 | 151 | // MARK: Override methods 152 | override public func layoutSubviews() { 153 | super.layoutSubviews() 154 | layerContainer.sublayers?.removeAll() 155 | 156 | // Compute Segment Size 157 | for (index, segment) in self.innerSegments.enumerated() { 158 | segment.contentSize = self.segmentContentSize(segment) 159 | segment.segmentWidth = max(segment.contentSize.width + self.segmentEdgeInsets.left + self.segmentEdgeInsets.right, self.segmentMinWidth) 160 | segment.segmentFrame = self.segmentFrame(index) 161 | } 162 | 163 | // Adjust Control Content Size & Segment Size 164 | self.scrollView.contentSize = CGSize(width: self.segmentControlContentWidth, height: self.scrollView.frame.height) 165 | if self.scrollView.contentSize.width < self.scrollView.frame.width { 166 | switch self.nonScrollDistributionStyle { 167 | case .center: 168 | self.scrollView.contentInset = UIEdgeInsets(top: 0, left: (self.scrollView.frame.width - self.scrollView.contentSize.width) / 2, bottom: 0, right: 0) 169 | case .left: 170 | self.scrollView.contentInset = UIEdgeInsets.zero 171 | case .right: 172 | self.scrollView.contentInset = UIEdgeInsets(top: 0, left: self.scrollView.frame.width - self.scrollView.contentSize.width, bottom: 0, right: 0) 173 | case .average: 174 | self.scrollView.contentInset = UIEdgeInsets.zero 175 | self.scrollView.contentSize = self.scrollView.frame.size 176 | var averageWidth: CGFloat = (self.scrollView.frame.width - (self.enableSeparator && self.style != .rainbow ? CGFloat(self.innerSegments.count) * self.separatorWidth : 0)) / CGFloat(self.innerSegments.count) 177 | let largeSegments = self.innerSegments.filter({ (segment) -> Bool in 178 | return segment.segmentWidth >= averageWidth 179 | }) 180 | let smallSegments = self.innerSegments.filter({ (segment) -> Bool in 181 | return segment.segmentWidth < averageWidth 182 | }) 183 | let sumLarge = largeSegments.reduce(0, { (total, segment) -> CGFloat in 184 | return total + segment.segmentWidth 185 | }) 186 | averageWidth = (self.scrollView.frame.width - (self.enableSeparator && self.style != .rainbow ? CGFloat(self.innerSegments.count) * self.separatorWidth : 0) - sumLarge) / CGFloat(smallSegments.count) 187 | for segment in smallSegments { 188 | segment.segmentWidth = averageWidth 189 | } 190 | for (index, segment) in self.innerSegments.enumerated() { 191 | segment.segmentFrame = self.segmentFrame(index) 192 | segment.segmentFrame.origin.x += self.separatorWidth / 2 193 | } 194 | } 195 | } else { 196 | self.scrollView.contentInset = UIEdgeInsets.zero 197 | } 198 | 199 | // Add Touch View 200 | touchView.frame = CGRect(origin: CGPoint.zero, size: self.scrollView.contentSize) 201 | 202 | // Add Segment SubLayers 203 | for (index, segment) in self.innerSegments.enumerated() { 204 | let content_x = segment.segmentFrame.origin.x + (segment.segmentFrame.width - segment.contentSize.width) / 2 205 | let content_y = (self.scrollView.frame.height - segment.contentSize.height) / 2 206 | let content_frame = CGRect(x: content_x, y: content_y, width: segment.contentSize.width, height: segment.contentSize.height) 207 | 208 | // Add Decoration Layer 209 | switch self.style { 210 | case .rainbow: 211 | let layerStrip = CALayer() 212 | layerStrip.frame = CGRect(x: segment.segmentFrame.origin.x, y: index == self.selectedIndex ? 0 : segment.segmentFrame.height - self.rainbow_height, width: segment.segmentFrame.width, height: index == self.selectedIndex ? self.scrollView.frame.height : self.rainbow_height) 213 | if self.rainbow_colors.isEmpty == false { 214 | layerStrip.backgroundColor = self.rainbow_colors[index % self.rainbow_colors.count].cgColor 215 | } 216 | layerContainer.addSublayer(layerStrip) 217 | self.switchRoundCornerForLayer(layerStrip, isRoundCorner: index == self.selectedIndex) 218 | segment.layerStrip = layerStrip 219 | default: 220 | break 221 | } 222 | 223 | // Add Content Layer 224 | switch segment.content.type { 225 | case let .text(text): 226 | let layerText = CATextLayer() 227 | layerText.string = text 228 | let font = segmentTextBold ? UIFont.boldSystemFont(ofSize: self.segmentTextFontSize) : UIFont.systemFont(ofSize: self.segmentTextFontSize) 229 | layerText.font = CGFont(NSString(string:font.fontName)) 230 | layerText.fontSize = font.pointSize 231 | layerText.frame = content_frame 232 | layerText.alignmentMode = kCAAlignmentCenter 233 | layerText.truncationMode = kCATruncationEnd 234 | layerText.contentsScale = UIScreen.main.scale 235 | layerText.foregroundColor = index == self.selectedIndex ? self.segmentForegroundColorSelected.cgColor : self.segmentForegroundColor.cgColor 236 | layerContainer.addSublayer(layerText) 237 | segment.layerText = layerText 238 | case let .icon(icon): 239 | let layerIcon = CALayer() 240 | let image = icon 241 | layerIcon.frame = content_frame 242 | layerIcon.contents = image.cgImage 243 | layerContainer.addSublayer(layerIcon) 244 | segment.layerIcon = layerIcon 245 | } 246 | } 247 | 248 | // Add Indicator Layer 249 | let initLayerSeparator = { [unowned self] in 250 | let layerSeparator = CALayer() 251 | layerSeparator.frame = CGRect(x: 0, y: 0, width: self.scrollView.contentSize.width, height: self.scrollView.contentSize.height) 252 | layerSeparator.backgroundColor = self.separatorColor.cgColor 253 | 254 | let layerMask = CAShapeLayer() 255 | layerMask.fillColor = UIColor.white.cgColor 256 | let maskPath = UIBezierPath() 257 | for (index, segment) in self.innerSegments.enumerated() { 258 | index < self.innerSegments.count - 1 ? maskPath.append(UIBezierPath(rect: CGRect(x: segment.segmentFrame.maxX + self.separatorEdgeInsets.left, y: self.separatorEdgeInsets.top, width: self.separatorWidth - self.separatorEdgeInsets.left - self.separatorEdgeInsets.right, height: self.scrollView.frame.height - self.separatorEdgeInsets.top - self.separatorEdgeInsets.bottom))) : () 259 | } 260 | layerMask.path = maskPath.cgPath 261 | layerSeparator.mask = layerMask 262 | self.layerContainer.addSublayer(layerSeparator) 263 | } 264 | let initLayerCover = { [unowned self] in 265 | self.layerCover.frame = self.indicatorCoverFrame(self.selectedIndex) 266 | self.layerCover.backgroundColor = self.cover_color.cgColor 267 | self.layerCover.opacity = self.cover_opacity 268 | self.layerContainer.addSublayer(self.layerCover) 269 | } 270 | let addLayerOutside = { [unowned self] in 271 | let outsideLayerLeft = CALayer() 272 | outsideLayerLeft.frame = CGRect(x: -1 * self.scrollView.frame.width, y: self.scrollView.frame.height - self.rainbow_height, width: self.scrollView.frame.width, height: self.rainbow_height) 273 | outsideLayerLeft.backgroundColor = self.rainbow_outsideColor.cgColor 274 | self.layerContainer.addSublayer(outsideLayerLeft) 275 | 276 | let outsideLayerRight = CALayer() 277 | outsideLayerRight.frame = CGRect(x: self.scrollView.contentSize.width, y: self.scrollView.frame.height - self.rainbow_height, width: self.scrollView.frame.width, height: self.rainbow_height) 278 | outsideLayerRight.backgroundColor = self.rainbow_outsideColor.cgColor 279 | self.layerContainer.addSublayer(outsideLayerRight) 280 | } 281 | let addLayerSlideway = { [unowned self] (slidewayPosition: CGFloat, slidewayHeight: CGFloat, slidewayColor: UIColor) in 282 | let layerSlideway = CALayer() 283 | layerSlideway.frame = CGRect(x: -1 * self.scrollView.frame.width, y: slidewayPosition - slidewayHeight / 2, width: self.scrollView.contentSize.width + self.scrollView.frame.width * 2, height: slidewayHeight) 284 | layerSlideway.backgroundColor = slidewayColor.cgColor 285 | self.layerContainer.addSublayer(layerSlideway) 286 | } 287 | let initLayerStrip = { [unowned self] (stripFrame: CGRect, stripColor: UIColor) in 288 | self.layerStrip.frame = stripFrame 289 | self.layerStrip.backgroundColor = stripColor.cgColor 290 | self.layerContainer.addSublayer(self.layerStrip) 291 | } 292 | let initLayerArrow = { [unowned self] (arrowFrame: CGRect, arrowLocation: WBSegmentIndicatorLocation, arrowColor: UIColor) in 293 | self.layerArrow.frame = arrowFrame 294 | self.layerArrow.backgroundColor = arrowColor.cgColor 295 | 296 | let layerMask = CAShapeLayer() 297 | layerMask.fillColor = UIColor.white.cgColor 298 | let maskPath = UIBezierPath() 299 | var pointA = CGPoint.zero 300 | var pointB = CGPoint.zero 301 | var pointC = CGPoint.zero 302 | switch arrowLocation { 303 | case .up: 304 | pointA = CGPoint(x: 0, y: 0) 305 | pointB = CGPoint(x: self.layerArrow.bounds.width, y: 0) 306 | pointC = CGPoint(x: self.layerArrow.bounds.width / 2, y: self.layerArrow.bounds.height) 307 | case .down: 308 | pointA = CGPoint(x: 0, y: self.layerArrow.bounds.height) 309 | pointB = CGPoint(x: self.layerArrow.bounds.width, y: self.layerArrow.bounds.height) 310 | pointC = CGPoint(x: self.layerArrow.bounds.width / 2, y: 0) 311 | } 312 | maskPath.move(to: pointA) 313 | maskPath.addLine(to: pointB) 314 | maskPath.addLine(to: pointC) 315 | maskPath.close() 316 | layerMask.path = maskPath.cgPath 317 | self.layerArrow.mask = layerMask 318 | 319 | self.layerContainer.addSublayer(self.layerArrow) 320 | } 321 | switch self.style { 322 | case .cover: 323 | initLayerCover() 324 | self.enableSeparator ? initLayerSeparator() : () 325 | case .strip: 326 | let strip_frame = self.indicatorStripFrame(self.selectedIndex, stripHeight: self.strip_height, stripLocation: self.strip_location, stripRange: self.strip_range) 327 | self.enableSlideway ? addLayerSlideway(strip_frame.midY, self.slidewayHeight, self.slidewayColor) : () 328 | initLayerStrip(strip_frame, self.strip_color) 329 | self.enableSeparator ? initLayerSeparator() : () 330 | case .rainbow: 331 | addLayerOutside() 332 | case .arrow: 333 | let arrow_frame = self.indicatorArrowFrame(self.selectedIndex, arrowLocation: self.arrow_location, arrowSize: self.arrow_size) 334 | var slideway_y: CGFloat = 0 335 | switch self.arrow_location { 336 | case .up: 337 | slideway_y = arrow_frame.origin.y + self.slidewayHeight / 2 338 | case .down: 339 | slideway_y = arrow_frame.maxY - self.slidewayHeight / 2 340 | } 341 | self.enableSlideway ? addLayerSlideway(slideway_y, self.slidewayHeight, self.slidewayColor) : () 342 | initLayerArrow(arrow_frame, self.arrow_location, self.arrow_color) 343 | self.enableSeparator ? initLayerSeparator() : () 344 | case .arrowStrip: 345 | let strip_frame = self.indicatorStripFrame(self.selectedIndex, stripHeight: self.arrowStrip_stripHeight, stripLocation: self.arrowStrip_location, stripRange: self.arrowStrip_stripRange) 346 | self.enableSlideway ? addLayerSlideway(strip_frame.midY, self.slidewayHeight, self.slidewayColor) : () 347 | initLayerStrip(strip_frame, self.arrowStrip_color) 348 | let arrow_frame = self.indicatorArrowFrame(self.selectedIndex, arrowLocation: self.arrowStrip_location, arrowSize: self.arrowStrip_arrowSize) 349 | initLayerArrow(arrow_frame, self.arrowStrip_location, self.arrowStrip_color) 350 | self.enableSeparator ? initLayerSeparator() : () 351 | } 352 | } 353 | 354 | // MARK: Custom methods 355 | func selectedIndexChanged(_ newIndex: Int, oldIndex: Int) { 356 | if self.enableAnimation && validIndex(oldIndex) { 357 | CATransaction.begin() 358 | CATransaction.setAnimationDuration(self.animationDuration) 359 | CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)) 360 | CATransaction.setCompletionBlock({ [unowned self] in 361 | switch self.style { 362 | case .rainbow: 363 | if self.validIndex(oldIndex) { 364 | self.switchRoundCornerForLayer(self.innerSegments[oldIndex].layerStrip!, isRoundCorner: false) 365 | } 366 | default: 367 | break 368 | } 369 | }) 370 | self.scrollView.contentSize.width > self.scrollView.frame.width ? self.scrollToSegment(newIndex) : () 371 | self.didSelectedIndexChanged(newIndex, oldIndex: oldIndex) 372 | CATransaction.commit() 373 | } else { 374 | self.didSelectedIndexChanged(newIndex, oldIndex: oldIndex) 375 | } 376 | 377 | self.sendActions(for: .valueChanged) 378 | } 379 | 380 | func didSelectedIndexChanged(_ newIndex: Int, oldIndex: Int) { 381 | switch style { 382 | case .cover: 383 | self.layerCover.actions = nil 384 | self.layerCover.frame = self.indicatorCoverFrame(newIndex) 385 | case .strip: 386 | self.layerStrip.actions = nil 387 | self.layerStrip.frame = self.indicatorStripFrame(newIndex, stripHeight: self.strip_height, stripLocation: self.strip_location, stripRange: self.strip_range) 388 | case .rainbow: 389 | if validIndex(oldIndex), let old_StripLayer = self.innerSegments[oldIndex].layerStrip { 390 | let old_StripFrame = old_StripLayer.frame 391 | old_StripLayer.frame = CGRect(x: old_StripFrame.origin.x, y: self.scrollView.frame.height - self.strip_height, width: old_StripFrame.width, height: self.strip_height) 392 | } 393 | if let new_StripLayer = self.innerSegments[newIndex].layerStrip { 394 | let new_StripFrame = new_StripLayer.frame 395 | new_StripLayer.frame = CGRect(x: new_StripFrame.origin.x, y: 0, width: new_StripFrame.width, height: self.scrollView.frame.height) 396 | self.switchRoundCornerForLayer(new_StripLayer, isRoundCorner: true) 397 | } 398 | case .arrow: 399 | self.layerArrow.actions = nil 400 | self.layerArrow.frame = self.indicatorArrowFrame(newIndex, arrowLocation: self.arrow_location, arrowSize: self.arrow_size) 401 | case .arrowStrip: 402 | self.layerStrip.actions = nil 403 | self.layerStrip.frame = self.indicatorStripFrame(newIndex, stripHeight: self.arrowStrip_stripHeight, stripLocation: self.arrowStrip_location, stripRange: self.arrowStrip_stripRange) 404 | self.layerArrow.actions = nil 405 | self.layerArrow.frame = self.indicatorArrowFrame(newIndex, arrowLocation: self.arrowStrip_location, arrowSize: self.arrowStrip_arrowSize) 406 | } 407 | 408 | if validIndex(oldIndex) { 409 | switch self.innerSegments[oldIndex].content.type { 410 | case .text: 411 | if let old_contentLayer = self.innerSegments[oldIndex].layerText as? CATextLayer { 412 | old_contentLayer.foregroundColor = self.segmentForegroundColor.cgColor 413 | } 414 | default: 415 | break 416 | } 417 | } 418 | switch self.innerSegments[newIndex].content.type { 419 | case .text: 420 | if let new_contentLayer = self.innerSegments[newIndex].layerText as? CATextLayer { 421 | new_contentLayer.foregroundColor = self.segmentForegroundColorSelected.cgColor 422 | } 423 | default: 424 | break 425 | } 426 | } 427 | 428 | func switchRoundCornerForLayer(_ layer: CALayer, isRoundCorner: Bool) { 429 | if isRoundCorner { 430 | let layerMask = CAShapeLayer() 431 | layerMask.fillColor = UIColor.white.cgColor 432 | layerMask.path = UIBezierPath(roundedRect: CGRect(origin: CGPoint.zero, size: layer.frame.size), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: self.rainbow_roundCornerRadius, height: self.rainbow_roundCornerRadius)).cgPath 433 | layer.mask = layerMask 434 | } else { 435 | layer.mask = nil 436 | } 437 | } 438 | 439 | func scrollToSegment(_ index: Int) { 440 | let segmentFrame = self.innerSegments[index].segmentFrame 441 | let targetRect = CGRect(x: segmentFrame.origin.x - (self.scrollView.frame.width - segmentFrame.width) / 2, y: 0, width: self.scrollView.frame.width, height: self.scrollView.frame.height) 442 | self.scrollView.scrollRectToVisible(targetRect, animated: true) 443 | } 444 | 445 | func segmentContentSize(_ segment: WBInnerSegment) -> CGSize { 446 | var size = CGSize.zero 447 | switch segment.content.type { 448 | case let .text(text): 449 | size = (text as NSString).size(attributes: [ 450 | NSFontAttributeName: segmentTextBold ? UIFont.boldSystemFont(ofSize: self.segmentTextFontSize) : UIFont.systemFont(ofSize: self.segmentTextFontSize) 451 | ]) 452 | case let .icon(icon): 453 | size = icon.size 454 | } 455 | return CGSize(width: ceil(size.width), height: ceil(size.height)) 456 | } 457 | 458 | func segmentFrame(_ index: Int) -> CGRect { 459 | var segmentOffset: CGFloat = (self.enableSeparator && self.style != .rainbow ? self.separatorWidth / 2 : 0) 460 | for (idx, segment) in self.innerSegments.enumerated() { 461 | if idx == index { 462 | break 463 | } else { 464 | segmentOffset += segment.segmentWidth + (self.enableSeparator && self.style != .rainbow ? self.separatorWidth : 0) 465 | } 466 | } 467 | return CGRect(x: segmentOffset , y: 0, width: self.innerSegments[index].segmentWidth, height: self.scrollView.frame.height) 468 | } 469 | 470 | func indicatorCoverFrame(_ index: Int) -> CGRect { 471 | if validIndex(index) { 472 | var box_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x 473 | var box_width: CGFloat = 0 474 | switch self.cover_range { 475 | case .content: 476 | box_x += (self.innerSegments[index].segmentWidth - self.innerSegments[index].contentSize.width) / 2 477 | box_width = self.innerSegments[index].contentSize.width 478 | case .segment: 479 | box_width = self.innerSegments[index].segmentWidth 480 | } 481 | return CGRect(x: box_x, y: 0, width: box_width, height: self.scrollView.frame.height) 482 | } else { 483 | return CGRect.zero 484 | } 485 | } 486 | 487 | func indicatorStripFrame(_ index: Int, stripHeight: CGFloat, stripLocation: WBSegmentIndicatorLocation, stripRange: WBSegmentIndicatorRange) -> CGRect { 488 | if validIndex(index) { 489 | var strip_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x 490 | var strip_y: CGFloat = 0 491 | var strip_width: CGFloat = 0 492 | switch stripLocation { 493 | case .down: 494 | strip_y = self.innerSegments[index].segmentFrame.height - stripHeight 495 | case .up: 496 | strip_y = 0 497 | } 498 | switch stripRange { 499 | case .content: 500 | strip_width = self.innerSegments[index].contentSize.width 501 | strip_x += (self.innerSegments[index].segmentWidth - strip_width) / 2 502 | case .segment: 503 | strip_width = self.innerSegments[index].segmentWidth 504 | } 505 | return CGRect(x: strip_x, y: strip_y, width: strip_width, height: stripHeight) 506 | } else { 507 | return CGRect.zero 508 | } 509 | } 510 | 511 | func indicatorArrowFrame(_ index: Int, arrowLocation: WBSegmentIndicatorLocation, arrowSize: CGSize) -> CGRect { 512 | if validIndex(index) { 513 | let arrow_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x + (self.innerSegments[index].segmentFrame.width - arrowSize.width) / 2 514 | var arrow_y: CGFloat = 0 515 | switch arrowLocation { 516 | case .up: 517 | arrow_y = 0 518 | case .down: 519 | arrow_y = self.innerSegments[index].segmentFrame.height - self.arrow_size.height 520 | } 521 | return CGRect(x: arrow_x, y: arrow_y, width: arrowSize.width, height: arrowSize.height) 522 | } else { 523 | return CGRect.zero 524 | } 525 | } 526 | 527 | func indexForTouch(_ location: CGPoint) -> Int { 528 | var touch_offset_x = location.x 529 | var touch_index = 0 530 | for (index, segment) in self.innerSegments.enumerated() { 531 | touch_offset_x -= segment.segmentWidth + (self.enableSeparator && self.style != .rainbow ? self.separatorWidth : 0) 532 | if touch_offset_x < 0 { 533 | touch_index = index 534 | break 535 | } 536 | } 537 | return touch_index 538 | } 539 | 540 | func validIndex(_ index: Int) -> Bool { 541 | return index >= 0 && index < segments.count 542 | } 543 | } 544 | 545 | extension WBSegmentControl: WBTouchViewDelegate { 546 | public func didTouch(_ location: CGPoint) { 547 | selectedIndex = indexForTouch(location) 548 | } 549 | } 550 | 551 | class WBInnerSegment { 552 | 553 | let content: WBSegmentContentProtocol 554 | 555 | var segmentFrame: CGRect = CGRect.zero 556 | var segmentWidth: CGFloat = 0 557 | var contentSize: CGSize = CGSize.zero 558 | 559 | var layerText: CALayer! 560 | var layerIcon: CALayer! 561 | var layerStrip: CALayer! 562 | 563 | init(content: WBSegmentContentProtocol) { 564 | self.content = content 565 | } 566 | } 567 | 568 | public enum WBSegmentType { 569 | case text(String) 570 | case icon(UIImage) 571 | } 572 | 573 | public enum WBSegmentIndicatorStyle { 574 | case cover, strip, rainbow, arrow, arrowStrip 575 | } 576 | 577 | public enum WBSegmentIndicatorLocation { 578 | case up, down 579 | } 580 | 581 | public enum WBSegmentIndicatorRange { 582 | case content, segment 583 | } 584 | 585 | public enum WBSegmentNonScrollDistributionStyle { 586 | case center, left, right, average 587 | } 588 | 589 | class WBTouchView: UIView { 590 | 591 | var delegate: WBTouchViewDelegate? 592 | 593 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 594 | if let touch = touches.first { 595 | delegate?.didTouch(touch.location(in: self)) 596 | } 597 | } 598 | } 599 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl/WBSegmentControl.swift.orig: -------------------------------------------------------------------------------- 1 | // 2 | // CustomSegmentControl2.swift 3 | // TrafficSecretary 4 | // 5 | // Created by 王继荣 on 4/9/16. 6 | // Copyright © 2016 wonderbear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol WBSegmentControlDelegate: class { 12 | func segmentControl(_ segmentControl: WBSegmentControl, selectIndex newIndex: Int, oldIndex: Int) 13 | } 14 | 15 | public protocol WBSegmentContentProtocol { 16 | var type: WBSegmentType { get } 17 | } 18 | 19 | public protocol WBTouchViewDelegate { 20 | func didTouch(_ location: CGPoint) 21 | } 22 | 23 | public class WBSegmentControl: UIControl { 24 | 25 | // MARK: Configuration - Content 26 | public var segments: [WBSegmentContentProtocol] = [] { 27 | didSet { 28 | innerSegments = segments.map({ (content) -> WBInnerSegment in 29 | return WBInnerSegment(content: content) 30 | }) 31 | self.setNeedsLayout() 32 | if segments.count == 0 { 33 | selectedIndex = -1 34 | } 35 | } 36 | } 37 | var innerSegments: [WBInnerSegment] = [] 38 | 39 | // MARK: Configuration - Interaction 40 | <<<<<<< HEAD 41 | public var delegate: WBSegmentControlDelegate? 42 | public var selectedIndex: Int = -1 { 43 | ======= 44 | public weak var delegate: WBSegmentControlDelegate? 45 | public var selectedIndex: Int = 0 { 46 | >>>>>>> daee6619dc33562f676bb2bd4af3be0204273206 47 | didSet { 48 | if selectedIndex != oldValue && validIndex(selectedIndex) { 49 | selectedIndexChanged(selectedIndex, oldIndex: oldValue) 50 | delegate?.segmentControl(self, selectIndex: selectedIndex, oldIndex: oldValue) 51 | } 52 | } 53 | } 54 | public var selectedSegment: WBSegmentContentProtocol? { 55 | return validIndex(selectedIndex) ? segments[selectedIndex] : nil 56 | } 57 | 58 | // MARK: Configuration - Appearance 59 | public var style: WBSegmentIndicatorStyle = .rainbow 60 | public var nonScrollDistributionStyle: WBSegmentNonScrollDistributionStyle = .average 61 | public var enableSeparator: Bool = false 62 | public var separatorColor: UIColor = UIColor.black 63 | public var separatorWidth: CGFloat = 9 64 | public var separatorEdgeInsets: UIEdgeInsets = UIEdgeInsets(top: 8, left: 4, bottom: 8, right: 4) 65 | public var enableSlideway: Bool = false 66 | public var slidewayHeight: CGFloat = 1 67 | public var slidewayColor: UIColor = UIColor.lightGray 68 | public var enableAnimation: Bool = true 69 | public var animationDuration: TimeInterval = 0.15 70 | public var segmentMinWidth: CGFloat = 50 71 | public var segmentEdgeInsets: UIEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) 72 | public var segmentTextBold: Bool = true 73 | public var segmentTextFontSize: CGFloat = 12 74 | public var segmentForegroundColor: UIColor = UIColor.gray 75 | public var segmentForegroundColorSelected: UIColor = UIColor.black 76 | 77 | // Settings - Cover 78 | public typealias CoverRange = WBSegmentIndicatorRange 79 | 80 | public var cover_range: CoverRange = .segment 81 | public var cover_opacity: Float = 0.2 82 | public var cover_color: UIColor = UIColor.black 83 | 84 | // Settings - Strip 85 | public typealias StripRange = WBSegmentIndicatorRange 86 | public typealias StripLocation = WBSegmentIndicatorLocation 87 | 88 | public var strip_range: StripRange = .content 89 | public var strip_location: StripLocation = .down 90 | public var strip_color: UIColor = UIColor.orange 91 | public var strip_height: CGFloat = 3 92 | 93 | // Settings - Rainbow 94 | public typealias RainbowLocation = WBSegmentIndicatorLocation 95 | 96 | public var rainbow_colors: [UIColor] = [] 97 | public var rainbow_height: CGFloat = 3 98 | public var rainbow_roundCornerRadius: CGFloat = 4 99 | public var rainbow_location: RainbowLocation = .down 100 | public var rainbow_outsideColor: UIColor = UIColor.gray 101 | 102 | // Settings - Arrow 103 | public typealias ArrowLocation = WBSegmentIndicatorLocation 104 | 105 | public var arrow_size: CGSize = CGSize(width: 6, height: 6) 106 | public var arrow_location: ArrowLocation = .down 107 | public var arrow_color: UIColor = UIColor.orange 108 | 109 | // Settings - ArrowStrip 110 | public typealias ArrowStripLocation = WBSegmentIndicatorLocation 111 | public typealias ArrowStripRange = WBSegmentIndicatorRange 112 | 113 | public var arrowStrip_location: ArrowStripLocation = .up 114 | public var arrowStrip_color: UIColor = UIColor.orange 115 | public var arrowStrip_arrowSize: CGSize = CGSize(width: 6, height: 6) 116 | public var arrowStrip_stripHeight: CGFloat = 2 117 | public var arrowStrip_stripRange: ArrowStripRange = .content 118 | 119 | // MARK: Inner properties 120 | fileprivate var scrollView: UIScrollView! 121 | fileprivate var touchView: WBTouchView = WBTouchView() 122 | fileprivate var layerContainer: CALayer = CALayer() 123 | fileprivate var layerCover: CALayer = CALayer() 124 | fileprivate var layerStrip: CALayer = CALayer() 125 | fileprivate var layerArrow: CALayer = CALayer() 126 | fileprivate var segmentControlContentWidth: CGFloat { 127 | let sum = self.innerSegments.reduce(0, { (max_x, segment) -> CGFloat in 128 | return max(max_x, segment.segmentFrame.maxX) 129 | }) 130 | return sum + ((self.enableSeparator && self.style != .rainbow) ? self.separatorWidth / 2 : 0) 131 | } 132 | 133 | // MARK: Initialization 134 | override init(frame: CGRect) { 135 | super.init(frame: frame) 136 | 137 | scrollView = UIScrollView() 138 | self.addSubview(scrollView) 139 | scrollView.translatesAutoresizingMaskIntoConstraints = false 140 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1, constant: 0)) 141 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)) 142 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .left, relatedBy: .equal, toItem: self, attribute: .left, multiplier: 1, constant: 0)) 143 | self.addConstraint(NSLayoutConstraint(item: scrollView, attribute: .right, relatedBy: .equal, toItem: self, attribute: .right, multiplier: 1, constant: 0)) 144 | scrollView.showsHorizontalScrollIndicator = false 145 | scrollView.showsVerticalScrollIndicator = false 146 | scrollView.layer.addSublayer(layerContainer) 147 | 148 | scrollView.addSubview(touchView) 149 | touchView.delegate = self 150 | } 151 | 152 | required public init?(coder aDecoder: NSCoder) { 153 | fatalError("init(coder:) has not been implemented") 154 | } 155 | 156 | // MARK: Override methods 157 | override public func layoutSubviews() { 158 | super.layoutSubviews() 159 | layerContainer.sublayers?.removeAll() 160 | 161 | // Compute Segment Size 162 | for (index, segment) in self.innerSegments.enumerated() { 163 | segment.contentSize = self.segmentContentSize(segment) 164 | segment.segmentWidth = max(segment.contentSize.width + self.segmentEdgeInsets.left + self.segmentEdgeInsets.right, self.segmentMinWidth) 165 | segment.segmentFrame = self.segmentFrame(index) 166 | } 167 | 168 | // Adjust Control Content Size & Segment Size 169 | self.scrollView.contentSize = CGSize(width: self.segmentControlContentWidth, height: self.scrollView.frame.height) 170 | if self.scrollView.contentSize.width < self.scrollView.frame.width { 171 | switch self.nonScrollDistributionStyle { 172 | case .center: 173 | self.scrollView.contentInset = UIEdgeInsets(top: 0, left: (self.scrollView.frame.width - self.scrollView.contentSize.width) / 2, bottom: 0, right: 0) 174 | case .left: 175 | self.scrollView.contentInset = UIEdgeInsets.zero 176 | case .right: 177 | self.scrollView.contentInset = UIEdgeInsets(top: 0, left: self.scrollView.frame.width - self.scrollView.contentSize.width, bottom: 0, right: 0) 178 | case .average: 179 | self.scrollView.contentInset = UIEdgeInsets.zero 180 | self.scrollView.contentSize = self.scrollView.frame.size 181 | var averageWidth: CGFloat = (self.scrollView.frame.width - (self.enableSeparator && self.style != .rainbow ? CGFloat(self.innerSegments.count) * self.separatorWidth : 0)) / CGFloat(self.innerSegments.count) 182 | let largeSegments = self.innerSegments.filter({ (segment) -> Bool in 183 | return segment.segmentWidth >= averageWidth 184 | }) 185 | let smallSegments = self.innerSegments.filter({ (segment) -> Bool in 186 | return segment.segmentWidth < averageWidth 187 | }) 188 | let sumLarge = largeSegments.reduce(0, { (total, segment) -> CGFloat in 189 | return total + segment.segmentWidth 190 | }) 191 | averageWidth = (self.scrollView.frame.width - (self.enableSeparator && self.style != .rainbow ? CGFloat(self.innerSegments.count) * self.separatorWidth : 0) - sumLarge) / CGFloat(smallSegments.count) 192 | for segment in smallSegments { 193 | segment.segmentWidth = averageWidth 194 | } 195 | for (index, segment) in self.innerSegments.enumerated() { 196 | segment.segmentFrame = self.segmentFrame(index) 197 | segment.segmentFrame.origin.x += self.separatorWidth / 2 198 | } 199 | } 200 | } else { 201 | self.scrollView.contentInset = UIEdgeInsets.zero 202 | } 203 | 204 | // Add Touch View 205 | touchView.frame = CGRect(origin: CGPoint.zero, size: self.scrollView.contentSize) 206 | 207 | // Add Segment SubLayers 208 | for (index, segment) in self.innerSegments.enumerated() { 209 | let content_x = segment.segmentFrame.origin.x + (segment.segmentFrame.width - segment.contentSize.width) / 2 210 | let content_y = (self.scrollView.frame.height - segment.contentSize.height) / 2 211 | let content_frame = CGRect(x: content_x, y: content_y, width: segment.contentSize.width, height: segment.contentSize.height) 212 | 213 | // Add Decoration Layer 214 | switch self.style { 215 | case .rainbow: 216 | let layerStrip = CALayer() 217 | layerStrip.frame = CGRect(x: segment.segmentFrame.origin.x, y: index == self.selectedIndex ? 0 : segment.segmentFrame.height - self.rainbow_height, width: segment.segmentFrame.width, height: index == self.selectedIndex ? self.scrollView.frame.height : self.rainbow_height) 218 | if self.rainbow_colors.isEmpty == false { 219 | layerStrip.backgroundColor = self.rainbow_colors[index % self.rainbow_colors.count].cgColor 220 | } 221 | layerContainer.addSublayer(layerStrip) 222 | self.switchRoundCornerForLayer(layerStrip, isRoundCorner: index == self.selectedIndex) 223 | segment.layerStrip = layerStrip 224 | default: 225 | break 226 | } 227 | 228 | // Add Content Layer 229 | switch segment.content.type { 230 | case let .text(text): 231 | let layerText = CATextLayer() 232 | layerText.string = text 233 | let font = segmentTextBold ? UIFont.boldSystemFont(ofSize: self.segmentTextFontSize) : UIFont.systemFont(ofSize: self.segmentTextFontSize) 234 | layerText.font = CGFont(NSString(string:font.fontName)) 235 | layerText.fontSize = font.pointSize 236 | layerText.frame = content_frame 237 | layerText.alignmentMode = kCAAlignmentCenter 238 | layerText.truncationMode = kCATruncationEnd 239 | layerText.contentsScale = UIScreen.main.scale 240 | layerText.foregroundColor = index == self.selectedIndex ? self.segmentForegroundColorSelected.cgColor : self.segmentForegroundColor.cgColor 241 | layerContainer.addSublayer(layerText) 242 | segment.layerText = layerText 243 | case let .icon(icon): 244 | let layerIcon = CALayer() 245 | let image = icon 246 | layerIcon.frame = content_frame 247 | layerIcon.contents = image.cgImage 248 | layerContainer.addSublayer(layerIcon) 249 | segment.layerIcon = layerIcon 250 | } 251 | } 252 | 253 | // Add Indicator Layer 254 | let initLayerSeparator = { [unowned self] in 255 | let layerSeparator = CALayer() 256 | layerSeparator.frame = CGRect(x: 0, y: 0, width: self.scrollView.contentSize.width, height: self.scrollView.contentSize.height) 257 | layerSeparator.backgroundColor = self.separatorColor.cgColor 258 | 259 | let layerMask = CAShapeLayer() 260 | layerMask.fillColor = UIColor.white.cgColor 261 | let maskPath = UIBezierPath() 262 | for (index, segment) in self.innerSegments.enumerated() { 263 | index < self.innerSegments.count - 1 ? maskPath.append(UIBezierPath(rect: CGRect(x: segment.segmentFrame.maxX + self.separatorEdgeInsets.left, y: self.separatorEdgeInsets.top, width: self.separatorWidth - self.separatorEdgeInsets.left - self.separatorEdgeInsets.right, height: self.scrollView.frame.height - self.separatorEdgeInsets.top - self.separatorEdgeInsets.bottom))) : () 264 | } 265 | layerMask.path = maskPath.cgPath 266 | layerSeparator.mask = layerMask 267 | self.layerContainer.addSublayer(layerSeparator) 268 | } 269 | let initLayerCover = { [unowned self] in 270 | self.layerCover.frame = self.indicatorCoverFrame(self.selectedIndex) 271 | self.layerCover.backgroundColor = self.cover_color.cgColor 272 | self.layerCover.opacity = self.cover_opacity 273 | self.layerContainer.addSublayer(self.layerCover) 274 | } 275 | let addLayerOutside = { [unowned self] in 276 | let outsideLayerLeft = CALayer() 277 | outsideLayerLeft.frame = CGRect(x: -1 * self.scrollView.frame.width, y: self.scrollView.frame.height - self.rainbow_height, width: self.scrollView.frame.width, height: self.rainbow_height) 278 | outsideLayerLeft.backgroundColor = self.rainbow_outsideColor.cgColor 279 | self.layerContainer.addSublayer(outsideLayerLeft) 280 | 281 | let outsideLayerRight = CALayer() 282 | outsideLayerRight.frame = CGRect(x: self.scrollView.contentSize.width, y: self.scrollView.frame.height - self.rainbow_height, width: self.scrollView.frame.width, height: self.rainbow_height) 283 | outsideLayerRight.backgroundColor = self.rainbow_outsideColor.cgColor 284 | self.layerContainer.addSublayer(outsideLayerRight) 285 | } 286 | let addLayerSlideway = { [unowned self] (slidewayPosition: CGFloat, slidewayHeight: CGFloat, slidewayColor: UIColor) in 287 | let layerSlideway = CALayer() 288 | layerSlideway.frame = CGRect(x: -1 * self.scrollView.frame.width, y: slidewayPosition - slidewayHeight / 2, width: self.scrollView.contentSize.width + self.scrollView.frame.width * 2, height: slidewayHeight) 289 | layerSlideway.backgroundColor = slidewayColor.cgColor 290 | self.layerContainer.addSublayer(layerSlideway) 291 | } 292 | let initLayerStrip = { [unowned self] (stripFrame: CGRect, stripColor: UIColor) in 293 | self.layerStrip.frame = stripFrame 294 | self.layerStrip.backgroundColor = stripColor.cgColor 295 | self.layerContainer.addSublayer(self.layerStrip) 296 | } 297 | let initLayerArrow = { [unowned self] (arrowFrame: CGRect, arrowLocation: WBSegmentIndicatorLocation, arrowColor: UIColor) in 298 | self.layerArrow.frame = arrowFrame 299 | self.layerArrow.backgroundColor = arrowColor.cgColor 300 | 301 | let layerMask = CAShapeLayer() 302 | layerMask.fillColor = UIColor.white.cgColor 303 | let maskPath = UIBezierPath() 304 | var pointA = CGPoint.zero 305 | var pointB = CGPoint.zero 306 | var pointC = CGPoint.zero 307 | switch arrowLocation { 308 | case .up: 309 | pointA = CGPoint(x: 0, y: 0) 310 | pointB = CGPoint(x: self.layerArrow.bounds.width, y: 0) 311 | pointC = CGPoint(x: self.layerArrow.bounds.width / 2, y: self.layerArrow.bounds.height) 312 | case .down: 313 | pointA = CGPoint(x: 0, y: self.layerArrow.bounds.height) 314 | pointB = CGPoint(x: self.layerArrow.bounds.width, y: self.layerArrow.bounds.height) 315 | pointC = CGPoint(x: self.layerArrow.bounds.width / 2, y: 0) 316 | } 317 | maskPath.move(to: pointA) 318 | maskPath.addLine(to: pointB) 319 | maskPath.addLine(to: pointC) 320 | maskPath.close() 321 | layerMask.path = maskPath.cgPath 322 | self.layerArrow.mask = layerMask 323 | 324 | self.layerContainer.addSublayer(self.layerArrow) 325 | } 326 | switch self.style { 327 | case .cover: 328 | initLayerCover() 329 | self.enableSeparator ? initLayerSeparator() : () 330 | case .strip: 331 | let strip_frame = self.indicatorStripFrame(self.selectedIndex, stripHeight: self.strip_height, stripLocation: self.strip_location, stripRange: self.strip_range) 332 | self.enableSlideway ? addLayerSlideway(strip_frame.midY, self.slidewayHeight, self.slidewayColor) : () 333 | initLayerStrip(strip_frame, self.strip_color) 334 | self.enableSeparator ? initLayerSeparator() : () 335 | case .rainbow: 336 | addLayerOutside() 337 | case .arrow: 338 | let arrow_frame = self.indicatorArrowFrame(self.selectedIndex, arrowLocation: self.arrow_location, arrowSize: self.arrow_size) 339 | var slideway_y: CGFloat = 0 340 | switch self.arrow_location { 341 | case .up: 342 | slideway_y = arrow_frame.origin.y + self.slidewayHeight / 2 343 | case .down: 344 | slideway_y = arrow_frame.maxY - self.slidewayHeight / 2 345 | } 346 | self.enableSlideway ? addLayerSlideway(slideway_y, self.slidewayHeight, self.slidewayColor) : () 347 | initLayerArrow(arrow_frame, self.arrow_location, self.arrow_color) 348 | self.enableSeparator ? initLayerSeparator() : () 349 | case .arrowStrip: 350 | let strip_frame = self.indicatorStripFrame(self.selectedIndex, stripHeight: self.arrowStrip_stripHeight, stripLocation: self.arrowStrip_location, stripRange: self.arrowStrip_stripRange) 351 | self.enableSlideway ? addLayerSlideway(strip_frame.midY, self.slidewayHeight, self.slidewayColor) : () 352 | initLayerStrip(strip_frame, self.arrowStrip_color) 353 | let arrow_frame = self.indicatorArrowFrame(self.selectedIndex, arrowLocation: self.arrowStrip_location, arrowSize: self.arrowStrip_arrowSize) 354 | initLayerArrow(arrow_frame, self.arrowStrip_location, self.arrowStrip_color) 355 | self.enableSeparator ? initLayerSeparator() : () 356 | } 357 | } 358 | 359 | // MARK: Custom methods 360 | func selectedIndexChanged(_ newIndex: Int, oldIndex: Int) { 361 | if self.enableAnimation && validIndex(oldIndex) { 362 | CATransaction.begin() 363 | CATransaction.setAnimationDuration(self.animationDuration) 364 | CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)) 365 | CATransaction.setCompletionBlock({ [unowned self] in 366 | switch self.style { 367 | case .rainbow: 368 | if self.validIndex(oldIndex) { 369 | self.switchRoundCornerForLayer(self.innerSegments[oldIndex].layerStrip!, isRoundCorner: false) 370 | } 371 | default: 372 | break 373 | } 374 | }) 375 | self.scrollView.contentSize.width > self.scrollView.frame.width ? self.scrollToSegment(newIndex) : () 376 | self.didSelectedIndexChanged(newIndex, oldIndex: oldIndex) 377 | CATransaction.commit() 378 | } else { 379 | self.didSelectedIndexChanged(newIndex, oldIndex: oldIndex) 380 | } 381 | 382 | self.sendActions(for: .valueChanged) 383 | } 384 | 385 | func didSelectedIndexChanged(_ newIndex: Int, oldIndex: Int) { 386 | switch style { 387 | case .cover: 388 | self.layerCover.actions = nil 389 | self.layerCover.frame = self.indicatorCoverFrame(newIndex) 390 | case .strip: 391 | self.layerStrip.actions = nil 392 | self.layerStrip.frame = self.indicatorStripFrame(newIndex, stripHeight: self.strip_height, stripLocation: self.strip_location, stripRange: self.strip_range) 393 | case .rainbow: 394 | if validIndex(oldIndex), let old_StripLayer = self.innerSegments[oldIndex].layerStrip { 395 | let old_StripFrame = old_StripLayer.frame 396 | old_StripLayer.frame = CGRect(x: old_StripFrame.origin.x, y: self.scrollView.frame.height - self.strip_height, width: old_StripFrame.width, height: self.strip_height) 397 | } 398 | if let new_StripLayer = self.innerSegments[newIndex].layerStrip { 399 | let new_StripFrame = new_StripLayer.frame 400 | new_StripLayer.frame = CGRect(x: new_StripFrame.origin.x, y: 0, width: new_StripFrame.width, height: self.scrollView.frame.height) 401 | self.switchRoundCornerForLayer(new_StripLayer, isRoundCorner: true) 402 | } 403 | case .arrow: 404 | self.layerArrow.actions = nil 405 | self.layerArrow.frame = self.indicatorArrowFrame(newIndex, arrowLocation: self.arrow_location, arrowSize: self.arrow_size) 406 | case .arrowStrip: 407 | self.layerStrip.actions = nil 408 | self.layerStrip.frame = self.indicatorStripFrame(newIndex, stripHeight: self.arrowStrip_stripHeight, stripLocation: self.arrowStrip_location, stripRange: self.arrowStrip_stripRange) 409 | self.layerArrow.actions = nil 410 | self.layerArrow.frame = self.indicatorArrowFrame(newIndex, arrowLocation: self.arrowStrip_location, arrowSize: self.arrowStrip_arrowSize) 411 | } 412 | 413 | if validIndex(oldIndex) { 414 | switch self.innerSegments[oldIndex].content.type { 415 | case .text: 416 | if let old_contentLayer = self.innerSegments[oldIndex].layerText as? CATextLayer { 417 | old_contentLayer.foregroundColor = self.segmentForegroundColor.cgColor 418 | } 419 | default: 420 | break 421 | } 422 | } 423 | switch self.innerSegments[newIndex].content.type { 424 | case .text: 425 | if let new_contentLayer = self.innerSegments[newIndex].layerText as? CATextLayer { 426 | new_contentLayer.foregroundColor = self.segmentForegroundColorSelected.cgColor 427 | } 428 | default: 429 | break 430 | } 431 | } 432 | 433 | func switchRoundCornerForLayer(_ layer: CALayer, isRoundCorner: Bool) { 434 | if isRoundCorner { 435 | let layerMask = CAShapeLayer() 436 | layerMask.fillColor = UIColor.white.cgColor 437 | layerMask.path = UIBezierPath(roundedRect: CGRect(origin: CGPoint.zero, size: layer.frame.size), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: self.rainbow_roundCornerRadius, height: self.rainbow_roundCornerRadius)).cgPath 438 | layer.mask = layerMask 439 | } else { 440 | layer.mask = nil 441 | } 442 | } 443 | 444 | func scrollToSegment(_ index: Int) { 445 | let segmentFrame = self.innerSegments[index].segmentFrame 446 | let targetRect = CGRect(x: segmentFrame.origin.x - (self.scrollView.frame.width - segmentFrame.width) / 2, y: 0, width: self.scrollView.frame.width, height: self.scrollView.frame.height) 447 | self.scrollView.scrollRectToVisible(targetRect, animated: true) 448 | } 449 | 450 | func segmentContentSize(_ segment: WBInnerSegment) -> CGSize { 451 | var size = CGSize.zero 452 | switch segment.content.type { 453 | case let .text(text): 454 | size = (text as NSString).size(attributes: [ 455 | NSFontAttributeName: segmentTextBold ? UIFont.boldSystemFont(ofSize: self.segmentTextFontSize) : UIFont.systemFont(ofSize: self.segmentTextFontSize) 456 | ]) 457 | case let .icon(icon): 458 | size = icon.size 459 | } 460 | return CGSize(width: ceil(size.width), height: ceil(size.height)) 461 | } 462 | 463 | func segmentFrame(_ index: Int) -> CGRect { 464 | var segmentOffset: CGFloat = (self.enableSeparator && self.style != .rainbow ? self.separatorWidth / 2 : 0) 465 | for (idx, segment) in self.innerSegments.enumerated() { 466 | if idx == index { 467 | break 468 | } else { 469 | segmentOffset += segment.segmentWidth + (self.enableSeparator && self.style != .rainbow ? self.separatorWidth : 0) 470 | } 471 | } 472 | return CGRect(x: segmentOffset , y: 0, width: self.innerSegments[index].segmentWidth, height: self.scrollView.frame.height) 473 | } 474 | 475 | func indicatorCoverFrame(_ index: Int) -> CGRect { 476 | if validIndex(index) { 477 | var box_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x 478 | var box_width: CGFloat = 0 479 | switch self.cover_range { 480 | case .content: 481 | box_x += (self.innerSegments[index].segmentWidth - self.innerSegments[index].contentSize.width) / 2 482 | box_width = self.innerSegments[index].contentSize.width 483 | case .segment: 484 | box_width = self.innerSegments[index].segmentWidth 485 | } 486 | return CGRect(x: box_x, y: 0, width: box_width, height: self.scrollView.frame.height) 487 | } else { 488 | return CGRect.zero 489 | } 490 | } 491 | 492 | func indicatorStripFrame(_ index: Int, stripHeight: CGFloat, stripLocation: WBSegmentIndicatorLocation, stripRange: WBSegmentIndicatorRange) -> CGRect { 493 | if validIndex(index) { 494 | var strip_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x 495 | var strip_y: CGFloat = 0 496 | var strip_width: CGFloat = 0 497 | switch stripLocation { 498 | case .down: 499 | strip_y = self.innerSegments[index].segmentFrame.height - stripHeight 500 | case .up: 501 | strip_y = 0 502 | } 503 | switch stripRange { 504 | case .content: 505 | strip_width = self.innerSegments[index].contentSize.width 506 | strip_x += (self.innerSegments[index].segmentWidth - strip_width) / 2 507 | case .segment: 508 | strip_width = self.innerSegments[index].segmentWidth 509 | } 510 | return CGRect(x: strip_x, y: strip_y, width: strip_width, height: stripHeight) 511 | } else { 512 | return CGRect.zero 513 | } 514 | } 515 | 516 | func indicatorArrowFrame(_ index: Int, arrowLocation: WBSegmentIndicatorLocation, arrowSize: CGSize) -> CGRect { 517 | if validIndex(index) { 518 | let arrow_x: CGFloat = self.innerSegments[index].segmentFrame.origin.x + (self.innerSegments[index].segmentFrame.width - arrowSize.width) / 2 519 | var arrow_y: CGFloat = 0 520 | switch arrowLocation { 521 | case .up: 522 | arrow_y = 0 523 | case .down: 524 | arrow_y = self.innerSegments[index].segmentFrame.height - self.arrow_size.height 525 | } 526 | return CGRect(x: arrow_x, y: arrow_y, width: arrowSize.width, height: arrowSize.height) 527 | } else { 528 | return CGRect.zero 529 | } 530 | } 531 | 532 | func indexForTouch(_ location: CGPoint) -> Int { 533 | var touch_offset_x = location.x 534 | var touch_index = 0 535 | for (index, segment) in self.innerSegments.enumerated() { 536 | touch_offset_x -= segment.segmentWidth + (self.enableSeparator && self.style != .rainbow ? self.separatorWidth : 0) 537 | if touch_offset_x < 0 { 538 | touch_index = index 539 | break 540 | } 541 | } 542 | return touch_index 543 | } 544 | 545 | func validIndex(_ index: Int) -> Bool { 546 | return index >= 0 && index < segments.count 547 | } 548 | } 549 | 550 | extension WBSegmentControl: WBTouchViewDelegate { 551 | public func didTouch(_ location: CGPoint) { 552 | selectedIndex = indexForTouch(location) 553 | } 554 | } 555 | 556 | class WBInnerSegment { 557 | 558 | let content: WBSegmentContentProtocol 559 | 560 | var segmentFrame: CGRect = CGRect.zero 561 | var segmentWidth: CGFloat = 0 562 | var contentSize: CGSize = CGSize.zero 563 | 564 | var layerText: CALayer! 565 | var layerIcon: CALayer! 566 | var layerStrip: CALayer! 567 | 568 | init(content: WBSegmentContentProtocol) { 569 | self.content = content 570 | } 571 | } 572 | 573 | public enum WBSegmentType { 574 | case text(String) 575 | case icon(UIImage) 576 | } 577 | 578 | public enum WBSegmentIndicatorStyle { 579 | case cover, strip, rainbow, arrow, arrowStrip 580 | } 581 | 582 | public enum WBSegmentIndicatorLocation { 583 | case up, down 584 | } 585 | 586 | public enum WBSegmentIndicatorRange { 587 | case content, segment 588 | } 589 | 590 | public enum WBSegmentNonScrollDistributionStyle { 591 | case center, left, right, average 592 | } 593 | 594 | class WBTouchView: UIView { 595 | 596 | var delegate: WBTouchViewDelegate? 597 | 598 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 599 | if let touch = touches.first { 600 | delegate?.didTouch(touch.location(in: self)) 601 | } 602 | } 603 | } 604 | -------------------------------------------------------------------------------- /Framework/WBSegmentControl/WBSegments.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Segment.swift 3 | // WBSegmentControl 4 | // 5 | // Created by 王继荣 on 7/28/16. 6 | // Copyright © 2016 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class TextSegment: NSObject, WBSegmentContentProtocol { 12 | 13 | public var text: String! 14 | public var otherAttr: String! 15 | 16 | public var type: WBSegmentType { 17 | return WBSegmentType.text(text) 18 | } 19 | 20 | public init(text: String, otherAttr: String = "") { 21 | super.init() 22 | 23 | self.text = text 24 | self.otherAttr = otherAttr 25 | } 26 | } 27 | 28 | public class IconSegment: NSObject, WBSegmentContentProtocol { 29 | 30 | public var icon: UIImage! 31 | 32 | public var type: WBSegmentType { 33 | return WBSegmentType.icon(icon) 34 | } 35 | 36 | public init(icon: UIImage) { 37 | super.init() 38 | 39 | self.icon = icon 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Framework/WBSegmentControlTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Framework/WBSegmentControlTests/WBSegmentControlTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WBSegmentControlTests.swift 3 | // WBSegmentControlTests 4 | // 5 | // Created by 王继荣 on 9/19/16. 6 | // Copyright © 2016 snowflyer. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import WBSegmentControl 11 | 12 | class WBSegmentControlTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 xiongxiong 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 | # WBSegmentControl 2 | 3 | [![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat)](https://developer.apple.com/swift/) 4 | [![CI Status](http://img.shields.io/travis/xiongxiong/WBSegmentControl.svg?style=flat)](https://travis-ci.org/xiongxiong/WBSegmentControl) 5 | [![Version](https://img.shields.io/cocoapods/v/WBSegmentControl.svg?style=flat)](http://cocoapods.org/pods/WBSegmentControl) 6 | [![Platform](https://img.shields.io/cocoapods/p/WBSegmentControl.svg?style=flat)](http://cocoapods.org/pods/WBSegmentControl) 7 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 8 | [![License](https://img.shields.io/cocoapods/l/WBSegmentControl.svg?style=flat)](http://cocoapods.org/pods/WBSegmentControl) 9 | 10 | An easy to use, customizable segment control, can be used to show tabs. 11 | 12 | ![WBSegmentControl](Framework/ScreenShot/WBSegmentControl.gif "WBSegmentControl") 13 | 14 | ## Contents 15 | - [Features](#features) 16 | - [Requirements](#requirements) 17 | - [Example](#example) 18 | - [Installation](#installation) 19 | - [Protocols](#protocols) 20 | - [Usage](#usage) 21 | - [Properties](#properties) 22 | - [Author](#author) 23 | - [License](#license) 24 | 25 | ## Features 26 | - [x] Flexible style - rainbow | cover | strip | arrow | arrowStrip 27 | - [x] Action delegate support 28 | - [x] Customized segment 29 | 30 | ## Requirements 31 | 32 | - iOS 8.0+ / Mac OS X 10.11+ / tvOS 9.0+ 33 | - Xcode 8.0+ 34 | - Swift 3.0+ 35 | 36 | ## Installation 37 | 38 | ### CocoaPods 39 | 40 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: 41 | 42 | ```bash 43 | $ gem install cocoapods 44 | ``` 45 | To integrate WBSegmentControl into your Xcode project using CocoaPods, specify it in your `Podfile`: 46 | 47 | ```ruby 48 | source 'https://github.com/CocoaPods/Specs.git' 49 | platform :ios, '8.0' 50 | use_frameworks! 51 | 52 | target '' do 53 | pod 'WBSegmentControl', '~> 0.2.0' 54 | end 55 | ``` 56 | 57 | Then, run the following command: 58 | 59 | ```bash 60 | $ pod install 61 | ``` 62 | 63 | ### Carthage 64 | 65 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. 66 | 67 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command: 68 | 69 | ```bash 70 | $ brew update 71 | $ brew install carthage 72 | ``` 73 | 74 | To integrate WBSegmentControl into your Xcode project using Carthage, specify it in your `Cartfile`: 75 | 76 | ```ogdl 77 | github "xiongxiong/WBSegmentControl" ~> 0.2.0 78 | ``` 79 | 80 | Run `carthage update` to build the framework and drag the built `WBSegmentControl.framework` into your Xcode project. 81 | 82 | ### Manually 83 | 84 | If you prefer not to use either of the aforementioned dependency managers, you can integrate WBSegmentControl into your project manually. 85 | 86 | ## Example 87 | 88 | Open the example project, build and run. 89 | 90 | ## Protocols 91 | 92 | ### WBSegmentControlDelegate 93 | 94 | ```swift 95 | public protocol WBSegmentControlDelegate { 96 | func segmentControl(segmentControl: WBSegmentControl, selectIndex newIndex: Int, oldIndex: Int) 97 | } 98 | ``` 99 | 100 | ### WBSegmentProtocol 101 | 102 | ```swift 103 | public protocol WBSegmentContentProtocol { 104 | var type: WBSegmentType { get } 105 | } 106 | ``` 107 | 108 | ## Usage 109 | 110 | ### Implement WBSegmentContentProtocol 111 | 112 | ```swift 113 | class TextSegment: NSObject, WBSegmentContentProtocol { 114 | 115 | var text: String! 116 | 117 | var type: WBSegmentType { 118 | return WBSegmentType.Text(text) 119 | } 120 | 121 | init(text: String) { 122 | super.init() 123 | 124 | self.text = text 125 | } 126 | } 127 | ``` 128 | 129 | IconSegment & TextSegment are already implemented, you can use it straightforwardly without implementing WBSegmentContentProtocol, or you can choose to implement WBSegmentContentProtocol to use your own segment type. 130 | 131 | ### Initialize segmentControl 132 | 133 | ```swift 134 | let segmentControl = WBSegmentControl() // initialize 135 | view.addSubview(segmentControl) 136 | ... 137 | segmentControl.segments = [ 138 | TextSegment(text: "News China"), 139 | TextSegment(text: "Breaking News"), 140 | ] // set segments 141 | segmentControl.style = .Rainbow // set style 142 | segmentControl.selectedIndex = 0 // set selected index 143 | ``` 144 | 145 | ### Implement WBSegmentControlDelegate 146 | 147 | ```swift 148 | extension MyViewController: WBSegmentControlDelegate { 149 | func segmentControl(segmentControl: WBSegmentControl, selectIndex newIndex: Int, oldIndex: Int) { 150 | 151 | } 152 | } 153 | ``` 154 | 155 | ### Get selected segment 156 | 157 | ```swift 158 | let selectedIndex = segmentControl.selectedIndex 159 | let selectedSegment: TextSegment? = segmentControl.selectedSegment as? TextSegment 160 | ``` 161 | 162 | ## Properties 163 | 164 | ### Settings - Common 165 | 166 | * indicatorStyle: IndicatorStyle = rainbow | cover | strip | arrow | arrowStrip 167 | * nonScrollDistributionStyle: NonScrollDistributionStyle = center | left | right | average 168 | * enableSeparator: Bool 169 | * separatorColor: UIColor 170 | * separatorWidth: CGFloat 171 | * separatorEdgeInsets: UIEdgeInsets 172 | * enableSlideway: Bool 173 | * slidewayHeight: CGFloat 174 | * slidewayColor: UIColor 175 | * enableAnimation: Bool 176 | * animationDuration: NSTimeInterval 177 | * contentBackgroundColor: UIColor 178 | * segmentMinWidth: CGFloat 179 | * segmentEdgeInsets: UIEdgeInsets 180 | * segmentTextBold: Bool 181 | * segmentTextFontSize: CGFloat 182 | * segmentTextForegroundColor: UIColor 183 | * segmentTextForegroundColorSelected: UIColor 184 | 185 | ### Settings - indicatorStyle == .Rainbow 186 | 187 | * rainbow_colors: [UIColor] 188 | * rainbow_height: CGFloat 189 | * rainbow_roundCornerRadius: CGFloat 190 | * rainbow_location: RainbowLocation = up | down 191 | * rainbow_outsideColor: UIColor 192 | 193 | ### Settings - indicatorStyle == .Cover 194 | 195 | * cover_range: CoverRange = segment | content 196 | * cover_opacity: Float 197 | * cover_color: UIColor 198 | 199 | ### Settings - indicatorStyle == .Strip 200 | 201 | * strip_range: StripRange = segment | content 202 | * strip_location: StripLocation = up | down 203 | * strip_color: UIColor 204 | * strip_height: CGFloat 205 | 206 | ### Settings - indicatorStyle == .Rainbow 207 | public var rainbow_colors: [UIColor] = [] 208 | public var rainbow_height: CGFloat = 3 209 | public var rainbow_roundCornerRadius: CGFloat = 4 210 | public var rainbow_location: RainbowLocation = .Down 211 | public var rainbow_outsideColor: UIColor = UIColor.grayColor() 212 | 213 | ### Settings - indicatorStyle == .Arrow 214 | 215 | * arrow_size: CGSize 216 | * arrow_location: ArrowLocation = up | down 217 | * arrow_color: UIColor 218 | 219 | ### Settings - indicatorStyle == .ArrowStrip 220 | 221 | * arrowStrip_location: ArrowStripLocation = up | down 222 | * arrowStrip_color: UIColor 223 | * arrowStrip_arrowSize: CGSize 224 | * arrowStrip_stripHeight: CGFloat 225 | * arrowStrip_stripRange: ArrowStripRange = segment | content 226 | 227 | ## Author 228 | 229 | xiongxiong, ximengwuheng@163.com 230 | 231 | ## License 232 | 233 | WBSegmentControl is available under the MIT license. See the LICENSE file for more info. 234 | -------------------------------------------------------------------------------- /WBSegmentControl.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | --------------------------------------------------------------------------------