├── .DS_Store ├── Contributors.md ├── LICENSE ├── README.md ├── Screenshots └── screenshot.png ├── WMSegmentControl.podspec ├── WMSegmentControl.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── wasim.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── wasim.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist └── WMSegmentControl ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json ├── female.imageset │ ├── Contents.json │ ├── female.png │ ├── female@2x.png │ └── female@3x.png ├── home.imageset │ ├── Contents.json │ └── home.png ├── male.imageset │ ├── Contents.json │ ├── male.png │ ├── male@2x.png │ └── male@3x.png ├── open_now.imageset │ ├── Contents.json │ └── open_now.pdf ├── person.imageset │ ├── Contents.json │ └── person.png ├── phone_number.imageset │ ├── Contents.json │ └── phone_number.pdf └── video.imageset │ ├── Contents.json │ └── video.png ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── SegmentViewController.swift └── Source └── WMSegment.swift /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/.DS_Store -------------------------------------------------------------------------------- /Contributors.md: -------------------------------------------------------------------------------- 1 | Maysam Shahsavari https://maysamsh.me 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Wasim Malek 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WMSegmentControl 2 | Custom segment control for iOS 3 | 4 | ![](https://github.com/malekwasim/WMSegmentControl/blob/master/Screenshots/screenshot.png) 5 | 6 | ### Detail information with screen 7 | https://elearningswift.com/custom-segment-control-for-ios-wmsegmentcontrol/ 8 | ### Usage 9 | Using WMSegment control is easy 10 | 11 | With Storybord 12 | ``` 13 | Drag a UIView and change its class to WMSegment. 14 | now you can set the properties as per your requirements. 15 | ``` 16 | Programatically 17 | ``` 18 | let anotherSegment = WMSegment(frame: frame) 19 | anotherSegment.type = .normal // normal (Default),imageOnTop, onlyImage 20 | anotherSegment.selectorType = .bottomBar //normal (Default), bottomBar 21 | // If you want round selector 22 | anotherSegment.isRounded = true //By default false 23 | //Set titles of your segment 24 | anotherSegment.buttonTitles = "Apple,Google,Facebook" 25 | //Set images 26 | anotherSegment.buttonImages = "apple_light,google_light,facebook_light" 27 | //Set selected images 28 | anotherSegment.buttonSelectedImages = "apple_dark,google_dark,facebook_dark" 29 | 30 | // set text color for non - selected segment values 31 | anotherSegment.textColor = .black 32 | // set text color for selected segment value 33 | anotherSegment.selectorTextColor = .orange 34 | //set Color for selected segment 35 | anotherSegment.selectorColor = .green 36 | //set font for selcted segment value 37 | anotherSegment.SelectedFont = UIFont(name: "ChalkboardSE-Bold", size: 15)! 38 | // set font for segment options 39 | anotherSegment.normalFont = UIFont(name: "ChalkboardSE-Regular", size: 15)! 40 | self.view.addSubview(anotherSegment) 41 | ``` 42 | ### Get selected Index 43 | ``` 44 | you can get the selected index two ways 45 | 1. Using Callback (swifty way) 46 | anotherSegment.onValueChanged = { index in 47 | print("I have selected index \(index) from WMSegment") 48 | } 49 | 2. Using Function - connect with segment for valueChange event 50 | @IBAction func segmentValueChange(_ sender: WMSegment) { 51 | print("selected index = \(sender.selectedSegmentIndex)") 52 | } 53 | ``` 54 | 55 | ### Suppoert Device rotation 56 | To support device rotation please add following code in appdelegate.(Due to iOS 14 issues, need some extra line of code) 57 | ``` 58 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 59 | // Override point for customization after application launch. 60 | NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil) 61 | return true 62 | } 63 | 64 | @objc func rotated() { 65 | if UIDevice.current.orientation.isLandscape { 66 | print("Landscape") 67 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DeviceRotated"), object: nil) 68 | 69 | } 70 | 71 | if UIDevice.current.orientation.isPortrait { 72 | print("Portrait") 73 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DeviceRotated"), object: nil) 74 | } 75 | } 76 | ``` 77 | ### Installation 78 | Using CocoaPods 79 | 80 | ``` 81 | pod 'WMSegmentControl' 82 | ``` 83 | Manually 84 | ``` 85 | Copy WMSegment.swift file from source folder and add it to your project. 86 | ``` 87 | -------------------------------------------------------------------------------- /Screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/Screenshots/screenshot.png -------------------------------------------------------------------------------- /WMSegmentControl.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'WMSegmentControl' 3 | s.version = '2.0' 4 | s.summary = 'Custom segment control for iOS' 5 | 6 | s.description = <<-DESC 7 | Custom segment control for iOS. Create a stylish segment control for you app. 8 | DESC 9 | 10 | s.homepage = 'https://github.com/malekwasim/WMSegmentControl' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'Wasim' => 'Wasim.malek.009@gmail.com' } 13 | s.source = { :git => 'https://github.com/malekwasim/WMSegmentControl.git', :tag => s.version.to_s } 14 | 15 | s.ios.deployment_target = '9.0' 16 | s.source_files = 'WMSegmentControl/Source/*.swift' 17 | s.swift_version = "4.2" 18 | 19 | end -------------------------------------------------------------------------------- /WMSegmentControl.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9FCA69FA229BB70300181099 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCA69F9229BB70300181099 /* AppDelegate.swift */; }; 11 | 9FCA69FC229BB70300181099 /* SegmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCA69FB229BB70300181099 /* SegmentViewController.swift */; }; 12 | 9FCA69FF229BB70300181099 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9FCA69FD229BB70300181099 /* Main.storyboard */; }; 13 | 9FCA6A01229BB70600181099 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FCA6A00229BB70600181099 /* Assets.xcassets */; }; 14 | 9FCA6A04229BB70600181099 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9FCA6A02229BB70600181099 /* LaunchScreen.storyboard */; }; 15 | 9FCA6A0D229BB75300181099 /* WMSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FCA6A0C229BB75300181099 /* WMSegment.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXFileReference section */ 19 | 9FCA69F6229BB70300181099 /* WMSegmentControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WMSegmentControl.app; sourceTree = BUILT_PRODUCTS_DIR; }; 20 | 9FCA69F9229BB70300181099 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 21 | 9FCA69FB229BB70300181099 /* SegmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SegmentViewController.swift; sourceTree = ""; }; 22 | 9FCA69FE229BB70300181099 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 23 | 9FCA6A00229BB70600181099 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 24 | 9FCA6A03229BB70600181099 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 25 | 9FCA6A05229BB70600181099 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 26 | 9FCA6A0C229BB75300181099 /* WMSegment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WMSegment.swift; sourceTree = ""; }; 27 | /* End PBXFileReference section */ 28 | 29 | /* Begin PBXFrameworksBuildPhase section */ 30 | 9FCA69F3229BB70300181099 /* Frameworks */ = { 31 | isa = PBXFrameworksBuildPhase; 32 | buildActionMask = 2147483647; 33 | files = ( 34 | ); 35 | runOnlyForDeploymentPostprocessing = 0; 36 | }; 37 | /* End PBXFrameworksBuildPhase section */ 38 | 39 | /* Begin PBXGroup section */ 40 | 9FCA69ED229BB70300181099 = { 41 | isa = PBXGroup; 42 | children = ( 43 | 9FCA69F8229BB70300181099 /* WMSegmentControl */, 44 | 9FCA69F7229BB70300181099 /* Products */, 45 | ); 46 | sourceTree = ""; 47 | }; 48 | 9FCA69F7229BB70300181099 /* Products */ = { 49 | isa = PBXGroup; 50 | children = ( 51 | 9FCA69F6229BB70300181099 /* WMSegmentControl.app */, 52 | ); 53 | name = Products; 54 | sourceTree = ""; 55 | }; 56 | 9FCA69F8229BB70300181099 /* WMSegmentControl */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | 9FCA6A0B229BB73A00181099 /* Source */, 60 | 9FCA69F9229BB70300181099 /* AppDelegate.swift */, 61 | 9FCA69FB229BB70300181099 /* SegmentViewController.swift */, 62 | 9FCA69FD229BB70300181099 /* Main.storyboard */, 63 | 9FCA6A00229BB70600181099 /* Assets.xcassets */, 64 | 9FCA6A02229BB70600181099 /* LaunchScreen.storyboard */, 65 | 9FCA6A05229BB70600181099 /* Info.plist */, 66 | ); 67 | path = WMSegmentControl; 68 | sourceTree = ""; 69 | }; 70 | 9FCA6A0B229BB73A00181099 /* Source */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 9FCA6A0C229BB75300181099 /* WMSegment.swift */, 74 | ); 75 | path = Source; 76 | sourceTree = ""; 77 | }; 78 | /* End PBXGroup section */ 79 | 80 | /* Begin PBXNativeTarget section */ 81 | 9FCA69F5229BB70300181099 /* WMSegmentControl */ = { 82 | isa = PBXNativeTarget; 83 | buildConfigurationList = 9FCA6A08229BB70600181099 /* Build configuration list for PBXNativeTarget "WMSegmentControl" */; 84 | buildPhases = ( 85 | 9FCA69F2229BB70300181099 /* Sources */, 86 | 9FCA69F3229BB70300181099 /* Frameworks */, 87 | 9FCA69F4229BB70300181099 /* Resources */, 88 | ); 89 | buildRules = ( 90 | ); 91 | dependencies = ( 92 | ); 93 | name = WMSegmentControl; 94 | productName = WMSegmentControl; 95 | productReference = 9FCA69F6229BB70300181099 /* WMSegmentControl.app */; 96 | productType = "com.apple.product-type.application"; 97 | }; 98 | /* End PBXNativeTarget section */ 99 | 100 | /* Begin PBXProject section */ 101 | 9FCA69EE229BB70300181099 /* Project object */ = { 102 | isa = PBXProject; 103 | attributes = { 104 | LastSwiftUpdateCheck = 1010; 105 | LastUpgradeCheck = 1010; 106 | ORGANIZATIONNAME = "Wasim Malek"; 107 | TargetAttributes = { 108 | 9FCA69F5229BB70300181099 = { 109 | CreatedOnToolsVersion = 10.1; 110 | }; 111 | }; 112 | }; 113 | buildConfigurationList = 9FCA69F1229BB70300181099 /* Build configuration list for PBXProject "WMSegmentControl" */; 114 | compatibilityVersion = "Xcode 9.3"; 115 | developmentRegion = en; 116 | hasScannedForEncodings = 0; 117 | knownRegions = ( 118 | en, 119 | Base, 120 | ); 121 | mainGroup = 9FCA69ED229BB70300181099; 122 | productRefGroup = 9FCA69F7229BB70300181099 /* Products */; 123 | projectDirPath = ""; 124 | projectRoot = ""; 125 | targets = ( 126 | 9FCA69F5229BB70300181099 /* WMSegmentControl */, 127 | ); 128 | }; 129 | /* End PBXProject section */ 130 | 131 | /* Begin PBXResourcesBuildPhase section */ 132 | 9FCA69F4229BB70300181099 /* Resources */ = { 133 | isa = PBXResourcesBuildPhase; 134 | buildActionMask = 2147483647; 135 | files = ( 136 | 9FCA6A04229BB70600181099 /* LaunchScreen.storyboard in Resources */, 137 | 9FCA6A01229BB70600181099 /* Assets.xcassets in Resources */, 138 | 9FCA69FF229BB70300181099 /* Main.storyboard in Resources */, 139 | ); 140 | runOnlyForDeploymentPostprocessing = 0; 141 | }; 142 | /* End PBXResourcesBuildPhase section */ 143 | 144 | /* Begin PBXSourcesBuildPhase section */ 145 | 9FCA69F2229BB70300181099 /* Sources */ = { 146 | isa = PBXSourcesBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | 9FCA69FC229BB70300181099 /* SegmentViewController.swift in Sources */, 150 | 9FCA6A0D229BB75300181099 /* WMSegment.swift in Sources */, 151 | 9FCA69FA229BB70300181099 /* AppDelegate.swift in Sources */, 152 | ); 153 | runOnlyForDeploymentPostprocessing = 0; 154 | }; 155 | /* End PBXSourcesBuildPhase section */ 156 | 157 | /* Begin PBXVariantGroup section */ 158 | 9FCA69FD229BB70300181099 /* Main.storyboard */ = { 159 | isa = PBXVariantGroup; 160 | children = ( 161 | 9FCA69FE229BB70300181099 /* Base */, 162 | ); 163 | name = Main.storyboard; 164 | sourceTree = ""; 165 | }; 166 | 9FCA6A02229BB70600181099 /* LaunchScreen.storyboard */ = { 167 | isa = PBXVariantGroup; 168 | children = ( 169 | 9FCA6A03229BB70600181099 /* Base */, 170 | ); 171 | name = LaunchScreen.storyboard; 172 | sourceTree = ""; 173 | }; 174 | /* End PBXVariantGroup section */ 175 | 176 | /* Begin XCBuildConfiguration section */ 177 | 9FCA6A06229BB70600181099 /* Debug */ = { 178 | isa = XCBuildConfiguration; 179 | buildSettings = { 180 | ALWAYS_SEARCH_USER_PATHS = NO; 181 | CLANG_ANALYZER_NONNULL = YES; 182 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 183 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 184 | CLANG_CXX_LIBRARY = "libc++"; 185 | CLANG_ENABLE_MODULES = YES; 186 | CLANG_ENABLE_OBJC_ARC = YES; 187 | CLANG_ENABLE_OBJC_WEAK = YES; 188 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 189 | CLANG_WARN_BOOL_CONVERSION = YES; 190 | CLANG_WARN_COMMA = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 193 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 194 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 195 | CLANG_WARN_EMPTY_BODY = YES; 196 | CLANG_WARN_ENUM_CONVERSION = YES; 197 | CLANG_WARN_INFINITE_RECURSION = YES; 198 | CLANG_WARN_INT_CONVERSION = YES; 199 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 200 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 201 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 202 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 203 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 204 | CLANG_WARN_STRICT_PROTOTYPES = YES; 205 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 206 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 207 | CLANG_WARN_UNREACHABLE_CODE = YES; 208 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 209 | CODE_SIGN_IDENTITY = "iPhone Developer"; 210 | COPY_PHASE_STRIP = NO; 211 | DEBUG_INFORMATION_FORMAT = dwarf; 212 | ENABLE_STRICT_OBJC_MSGSEND = YES; 213 | ENABLE_TESTABILITY = YES; 214 | GCC_C_LANGUAGE_STANDARD = gnu11; 215 | GCC_DYNAMIC_NO_PIC = NO; 216 | GCC_NO_COMMON_BLOCKS = YES; 217 | GCC_OPTIMIZATION_LEVEL = 0; 218 | GCC_PREPROCESSOR_DEFINITIONS = ( 219 | "DEBUG=1", 220 | "$(inherited)", 221 | ); 222 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 223 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 224 | GCC_WARN_UNDECLARED_SELECTOR = YES; 225 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 226 | GCC_WARN_UNUSED_FUNCTION = YES; 227 | GCC_WARN_UNUSED_VARIABLE = YES; 228 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 229 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 230 | MTL_FAST_MATH = YES; 231 | ONLY_ACTIVE_ARCH = YES; 232 | SDKROOT = iphoneos; 233 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 234 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 235 | }; 236 | name = Debug; 237 | }; 238 | 9FCA6A07229BB70600181099 /* Release */ = { 239 | isa = XCBuildConfiguration; 240 | buildSettings = { 241 | ALWAYS_SEARCH_USER_PATHS = NO; 242 | CLANG_ANALYZER_NONNULL = YES; 243 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 244 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 245 | CLANG_CXX_LIBRARY = "libc++"; 246 | CLANG_ENABLE_MODULES = YES; 247 | CLANG_ENABLE_OBJC_ARC = YES; 248 | CLANG_ENABLE_OBJC_WEAK = YES; 249 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 250 | CLANG_WARN_BOOL_CONVERSION = YES; 251 | CLANG_WARN_COMMA = YES; 252 | CLANG_WARN_CONSTANT_CONVERSION = YES; 253 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 256 | CLANG_WARN_EMPTY_BODY = YES; 257 | CLANG_WARN_ENUM_CONVERSION = YES; 258 | CLANG_WARN_INFINITE_RECURSION = YES; 259 | CLANG_WARN_INT_CONVERSION = YES; 260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 261 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 262 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 264 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 265 | CLANG_WARN_STRICT_PROTOTYPES = YES; 266 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 267 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 268 | CLANG_WARN_UNREACHABLE_CODE = YES; 269 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 270 | CODE_SIGN_IDENTITY = "iPhone Developer"; 271 | COPY_PHASE_STRIP = NO; 272 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 273 | ENABLE_NS_ASSERTIONS = NO; 274 | ENABLE_STRICT_OBJC_MSGSEND = YES; 275 | GCC_C_LANGUAGE_STANDARD = gnu11; 276 | GCC_NO_COMMON_BLOCKS = YES; 277 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 278 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 279 | GCC_WARN_UNDECLARED_SELECTOR = YES; 280 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 281 | GCC_WARN_UNUSED_FUNCTION = YES; 282 | GCC_WARN_UNUSED_VARIABLE = YES; 283 | IPHONEOS_DEPLOYMENT_TARGET = 12.1; 284 | MTL_ENABLE_DEBUG_INFO = NO; 285 | MTL_FAST_MATH = YES; 286 | SDKROOT = iphoneos; 287 | SWIFT_COMPILATION_MODE = wholemodule; 288 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 289 | VALIDATE_PRODUCT = YES; 290 | }; 291 | name = Release; 292 | }; 293 | 9FCA6A09229BB70600181099 /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | CODE_SIGN_STYLE = Automatic; 298 | DEVELOPMENT_TEAM = ""; 299 | INFOPLIST_FILE = WMSegmentControl/Info.plist; 300 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 301 | LD_RUNPATH_SEARCH_PATHS = ( 302 | "$(inherited)", 303 | "@executable_path/Frameworks", 304 | ); 305 | PRODUCT_BUNDLE_IDENTIFIER = WM.WMSegmentControl; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | SWIFT_VERSION = 4.2; 308 | TARGETED_DEVICE_FAMILY = "1,2"; 309 | }; 310 | name = Debug; 311 | }; 312 | 9FCA6A0A229BB70600181099 /* Release */ = { 313 | isa = XCBuildConfiguration; 314 | buildSettings = { 315 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 316 | CODE_SIGN_STYLE = Automatic; 317 | DEVELOPMENT_TEAM = ""; 318 | INFOPLIST_FILE = WMSegmentControl/Info.plist; 319 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 320 | LD_RUNPATH_SEARCH_PATHS = ( 321 | "$(inherited)", 322 | "@executable_path/Frameworks", 323 | ); 324 | PRODUCT_BUNDLE_IDENTIFIER = WM.WMSegmentControl; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | SWIFT_VERSION = 4.2; 327 | TARGETED_DEVICE_FAMILY = "1,2"; 328 | }; 329 | name = Release; 330 | }; 331 | /* End XCBuildConfiguration section */ 332 | 333 | /* Begin XCConfigurationList section */ 334 | 9FCA69F1229BB70300181099 /* Build configuration list for PBXProject "WMSegmentControl" */ = { 335 | isa = XCConfigurationList; 336 | buildConfigurations = ( 337 | 9FCA6A06229BB70600181099 /* Debug */, 338 | 9FCA6A07229BB70600181099 /* Release */, 339 | ); 340 | defaultConfigurationIsVisible = 0; 341 | defaultConfigurationName = Release; 342 | }; 343 | 9FCA6A08229BB70600181099 /* Build configuration list for PBXNativeTarget "WMSegmentControl" */ = { 344 | isa = XCConfigurationList; 345 | buildConfigurations = ( 346 | 9FCA6A09229BB70600181099 /* Debug */, 347 | 9FCA6A0A229BB70600181099 /* Release */, 348 | ); 349 | defaultConfigurationIsVisible = 0; 350 | defaultConfigurationName = Release; 351 | }; 352 | /* End XCConfigurationList section */ 353 | }; 354 | rootObject = 9FCA69EE229BB70300181099 /* Project object */; 355 | } 356 | -------------------------------------------------------------------------------- /WMSegmentControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WMSegmentControl.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WMSegmentControl.xcodeproj/project.xcworkspace/xcuserdata/wasim.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl.xcodeproj/project.xcworkspace/xcuserdata/wasim.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WMSegmentControl.xcodeproj/xcuserdata/wasim.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WMSegmentControl.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9FCA69F5229BB70300181099 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WMSegmentControl/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // WMSegmentControl 4 | // 5 | // Created by Wasim Malek on 27/05/19. 6 | // Copyright © 2019 Wasim Malek. 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: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.rotated), name: UIDevice.orientationDidChangeNotification, object: nil) 20 | return true 21 | } 22 | 23 | @objc func rotated() { 24 | if UIDevice.current.orientation.isLandscape { 25 | print("Landscape") 26 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DeviceRotated"), object: nil) 27 | 28 | } 29 | 30 | if UIDevice.current.orientation.isPortrait { 31 | print("Portrait") 32 | NotificationCenter.default.post(name: Notification.Name(rawValue: "DeviceRotated"), object: nil) 33 | } 34 | } 35 | 36 | func applicationWillResignActive(_ application: UIApplication) { 37 | // 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. 38 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 39 | } 40 | 41 | func applicationDidEnterBackground(_ application: UIApplication) { 42 | // 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. 43 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 44 | } 45 | 46 | func applicationWillEnterForeground(_ application: UIApplication) { 47 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | func applicationDidBecomeActive(_ application: UIApplication) { 51 | // 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. 52 | } 53 | 54 | func applicationWillTerminate(_ application: UIApplication) { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | } 60 | 61 | -------------------------------------------------------------------------------- /WMSegmentControl/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 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/female.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "female.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "female@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "female@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/female.imageset/female.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/female.imageset/female.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/female.imageset/female@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/female.imageset/female@2x.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/female.imageset/female@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/female.imageset/female@3x.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "home.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/home.imageset/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/home.imageset/home.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/male.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "male.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "male@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "male@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/male.imageset/male.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/male.imageset/male.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/male.imageset/male@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/male.imageset/male@2x.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/male.imageset/male@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/male.imageset/male@3x.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/open_now.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "open_now.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/open_now.imageset/open_now.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/open_now.imageset/open_now.pdf -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/person.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "person.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/person.imageset/person.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/person.imageset/person.png -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/phone_number.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "phone_number.pdf", 5 | "idiom" : "universal" 6 | } 7 | ], 8 | "info" : { 9 | "author" : "xcode", 10 | "version" : 1 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/phone_number.imageset/phone_number.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/phone_number.imageset/phone_number.pdf -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/video.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x" 10 | }, 11 | { 12 | "idiom" : "universal", 13 | "filename" : "video.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /WMSegmentControl/Assets.xcassets/video.imageset/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malekwasim/WMSegmentControl/a78c21ce52e8203ddc27a958af29996fffecded4/WMSegmentControl/Assets.xcassets/video.imageset/video.png -------------------------------------------------------------------------------- /WMSegmentControl/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 | -------------------------------------------------------------------------------- /WMSegmentControl/Base.lproj/Main.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 | 29 | 30 | 31 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | -------------------------------------------------------------------------------- /WMSegmentControl/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WMSegmentControl/SegmentViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // WMSegmentControl 4 | // 5 | // Created by Wasim Malek on 27/05/19. 6 | // Copyright © 2019 Wasim Malek. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SegmentViewController: UITableViewController { 12 | 13 | @IBOutlet weak var sgTextOnly: WMSegment! 14 | @IBOutlet weak var sgTextImage: WMSegment! 15 | @IBOutlet weak var sgTextImageRound: WMSegment! 16 | @IBOutlet weak var sgImageOnly: WMSegment! 17 | @IBOutlet weak var sgTextOnlyBar: WMSegment! 18 | @IBOutlet weak var sgImageOnlyBar: WMSegment! 19 | 20 | override func viewDidLoad() { 21 | super.viewDidLoad() 22 | self.title = "Custom Segment" 23 | sgImageOnly.type = .onlyImage 24 | sgImageOnlyBar.type = .onlyImage 25 | sgImageOnlyBar.selectorType = .bottomBar 26 | sgTextOnlyBar.selectorType = .bottomBar 27 | sgTextOnlyBar.SelectedFont = UIFont(name: "ChalkboardSE-Bold", size: 15)! 28 | sgTextOnlyBar.normalFont = UIFont(name: "ChalkboardSE-Regular", size: 15)! 29 | 30 | //Using callbacks 31 | sgTextOnly.onValueChanged = { index in 32 | print("I have selected index \(index) from WMSegment!") 33 | } 34 | } 35 | 36 | @IBAction func segmentValueChange(_ sender: WMSegment) { 37 | print("selected index = \(sender.selectedSegmentIndex)") 38 | /*switch sender.selectedSegmentIndex { 39 | case 0: 40 | print("first item") 41 | case 1: 42 | print("second item") 43 | case 2: 44 | print("Third item") 45 | default: 46 | print("default item") 47 | }*/ 48 | } 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /WMSegmentControl/Source/WMSegment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WMSegment.swift 3 | // WMSegmentControl 4 | // 5 | // Created by Wasim Malek on 27/05/19. 6 | // Copyright © 2019 Wasim Malek. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | @IBDesignable 11 | open class WMSegment: UIControl { 12 | public var onValueChanged: ((_ index: Int)->())? 13 | var buttons = [UIButton]() 14 | var selector: UIView! 15 | public var selectedSegmentIndex: Int = 0 16 | 17 | public var type: SegementType = .normal { 18 | didSet { 19 | updateView() 20 | } 21 | } 22 | 23 | public var selectorType: SelectorType = .normal { 24 | didSet { 25 | updateView() 26 | } 27 | } 28 | 29 | @IBInspectable 30 | public var borderWidth: CGFloat = 0 { 31 | didSet { 32 | layer.borderWidth = borderWidth 33 | } 34 | } 35 | 36 | @IBInspectable 37 | public var borderColor: UIColor = .clear { 38 | didSet { 39 | layer.borderColor = borderColor.cgColor 40 | } 41 | } 42 | 43 | @IBInspectable 44 | public var cornerRadius: CGFloat = 0 { 45 | didSet { 46 | layer.cornerRadius = cornerRadius 47 | } 48 | } 49 | @IBInspectable 50 | public var buttonTitles: String = ""{ 51 | didSet { 52 | updateView() 53 | } 54 | } 55 | 56 | @IBInspectable 57 | public var buttonImages: String = ""{ 58 | didSet { 59 | updateView() 60 | } 61 | } 62 | 63 | @IBInspectable 64 | public var buttonImagesSelected: String = "" 65 | 66 | @IBInspectable 67 | public var textColor: UIColor = .lightGray { 68 | didSet { 69 | updateView() 70 | } 71 | } 72 | 73 | @IBInspectable 74 | public var selectorTextColor: UIColor = .white { 75 | didSet { 76 | updateView() 77 | } 78 | } 79 | @IBInspectable 80 | public var selectorColor: UIColor = .darkGray { 81 | didSet { 82 | updateView() 83 | } 84 | } 85 | 86 | @IBInspectable 87 | public var isRounded: Bool = false { 88 | didSet { 89 | if self.isRounded == true { 90 | layer.cornerRadius = frame.height/2 91 | } 92 | updateView() 93 | } 94 | } 95 | 96 | @IBInspectable 97 | public var bottomBarHeight : CGFloat = 5.0 { 98 | didSet { 99 | updateView() 100 | } 101 | } 102 | 103 | public var normalFont : UIFont = UIFont.systemFont(ofSize: 15) { 104 | didSet { 105 | updateView() 106 | } 107 | } 108 | 109 | public var SelectedFont : UIFont = UIFont.systemFont(ofSize: 15) { 110 | didSet { 111 | updateView() 112 | } 113 | } 114 | 115 | public var animate: Bool = true 116 | 117 | private var isFrameAreSet = false 118 | open override func awakeFromNib() { 119 | super.awakeFromNib() 120 | 121 | updateView() 122 | } 123 | 124 | open func updateView() { 125 | self.clipsToBounds = true 126 | buttons.removeAll() 127 | subviews.forEach({$0.removeFromSuperview()}) 128 | NotificationCenter.default.removeObserver("DeviceRotated") 129 | NotificationCenter.default.addObserver(self, selector: #selector(setViewLayout), name: NSNotification.Name(rawValue: "DeviceRotated"), object: nil) 130 | if self.type == .normal { 131 | buttons = getButtonsForNormalSegment() 132 | } else if self.type == .imageOnTop { 133 | buttons = getButtonsForNormalSegment(true) 134 | } else if self.type == .onlyImage { 135 | buttons = getButtonsForOnlyImageSegment() 136 | } 137 | 138 | if selectedSegmentIndex < buttons.count { 139 | buttons[selectedSegmentIndex].tintColor = selectorTextColor 140 | buttons[selectedSegmentIndex].setTitleColor(selectorTextColor, for: .normal) 141 | buttons[selectedSegmentIndex].titleLabel?.font = SelectedFont 142 | } 143 | setupSelector() 144 | addSubview(selector) 145 | let sv = UIStackView(arrangedSubviews: buttons) 146 | sv.axis = .horizontal 147 | sv.alignment = .fill 148 | sv.distribution = .fillEqually//.fillProportionally 149 | addSubview(sv) 150 | sv.translatesAutoresizingMaskIntoConstraints = false 151 | 152 | sv.topAnchor.constraint(equalTo: self.topAnchor).isActive = true 153 | sv.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true 154 | sv.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true 155 | sv.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true 156 | } 157 | 158 | func setupSelector() { 159 | 160 | let titles = buttonTitles.components(separatedBy: ",") 161 | let images = buttonImages.components(separatedBy: ",") 162 | var selectorWidth = frame.width / CGFloat(titles.count) 163 | if self.type == .onlyImage { 164 | selectorWidth = frame.width / CGFloat(images.count) 165 | } 166 | 167 | 168 | if selectorType == .normal { 169 | selector = UIView(frame: CGRect(x: 0, y: 0, width: selectorWidth, height: frame.height)) 170 | if isRounded { 171 | selector.layer.cornerRadius = frame.height / 2 172 | } else { 173 | selector.layer.cornerRadius = 0 174 | } 175 | } else if selectorType == .bottomBar { 176 | selector = UIView(frame: CGRect(x: 0, y: frame.height - bottomBarHeight, width: selectorWidth, height: bottomBarHeight)) 177 | selector.layer.cornerRadius = 0 178 | } 179 | 180 | selector.backgroundColor = selectorColor 181 | } 182 | 183 | //MARK : Get Button as per segment type 184 | func getButtonsForNormalSegment(_ isImageTop: Bool = false) -> [UIButton] { 185 | var btn = [UIButton]() 186 | let titles = buttonTitles.components(separatedBy: ",") 187 | let images = buttonImages.components(separatedBy: ",") 188 | for (index, buttonTitle) in titles.enumerated() { 189 | let button = UIButton(type: .system) 190 | button.setTitle(buttonTitle, for: .normal) 191 | button.tag = index 192 | button.tintColor = textColor 193 | button.setTitleColor(textColor, for: .normal) 194 | button.titleLabel?.font = normalFont 195 | button.titleLabel?.textAlignment = .center 196 | button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) 197 | btn.append(button) 198 | if index < images.count { 199 | if images[index] != ""{ 200 | button.setImage(UIImage(named: images[index]), for: .normal) 201 | if isImageTop == false { 202 | button.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) 203 | } else { 204 | button.centerImageAndButton(5, imageOnTop: true) 205 | } 206 | } 207 | 208 | 209 | } 210 | } 211 | 212 | return btn 213 | } 214 | 215 | func getButtonsForOnlyImageSegment() -> [UIButton] { 216 | var btn = [UIButton]() 217 | let images = buttonImages.components(separatedBy: ",") 218 | for (index, buttonImage) in images.enumerated() { 219 | let button = UIButton(type: .system) 220 | button.setImage(UIImage(named: buttonImage), for: .normal) 221 | button.tag = index 222 | button.tintColor = textColor 223 | button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) 224 | btn.append(button) 225 | 226 | } 227 | return btn 228 | } 229 | 230 | open override func layoutSubviews() { 231 | super.layoutSubviews() 232 | if isFrameAreSet == false { 233 | setViewLayout() 234 | } 235 | } 236 | 237 | @objc open func setViewLayout() { 238 | layoutIfNeeded() 239 | updateView() 240 | let _animated = self.animate 241 | self.animate = false 242 | setSelectedIndex(self.selectedSegmentIndex) 243 | self.animate = _animated 244 | isFrameAreSet = true 245 | } 246 | 247 | @objc func buttonTapped(_ sender: UIButton) { 248 | let images = self.buttonImages.components(separatedBy: ",") 249 | let imagesSelected = self.buttonImagesSelected.components(separatedBy: ",") 250 | 251 | for (buttonIndex, btn) in buttons.enumerated() { 252 | btn.tintColor = textColor 253 | btn.setTitleColor(textColor, for: .normal) 254 | btn.titleLabel?.font = normalFont 255 | 256 | if let image = images[safe: buttonIndex] { 257 | btn.setImage(UIImage(named: image), for: .normal) 258 | } 259 | 260 | if btn == sender { 261 | if let imageSelected = imagesSelected[safe: buttonIndex], !imageSelected.isEmpty { 262 | btn.setImage(UIImage(named: imageSelected), for: .normal) 263 | } 264 | selectedSegmentIndex = buttonIndex 265 | let startPosition = frame.width/CGFloat(buttons.count) * CGFloat(buttonIndex) 266 | if self.animate { 267 | UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: { 268 | self.selector.frame.origin.x = startPosition 269 | }, completion: nil) 270 | }else{ 271 | self.selector.frame.origin.x = startPosition 272 | } 273 | btn.titleLabel?.font = SelectedFont 274 | btn.tintColor = selectorTextColor 275 | btn.setTitleColor(selectorTextColor, for: .normal) 276 | } 277 | } 278 | onValueChanged?(selectedSegmentIndex) 279 | sendActions(for: .valueChanged) 280 | } 281 | //MARK: set Selected Index 282 | open func setSelectedIndex(_ index: Int) { 283 | let images = self.buttonImages.components(separatedBy: ",") 284 | let imagesSelected = self.buttonImagesSelected.components(separatedBy: ",") 285 | 286 | for (buttonIndex, btn) in buttons.enumerated() { 287 | btn.tintColor = textColor 288 | btn.setTitleColor(textColor, for: .normal) 289 | if let image = images[safe: buttonIndex] { 290 | btn.setImage(UIImage(named: image), for: .normal) 291 | } 292 | 293 | if btn.tag == index { 294 | if let imageSelected = imagesSelected[safe: buttonIndex], !imageSelected.isEmpty { 295 | btn.setImage(UIImage(named: imageSelected), for: .normal) 296 | } 297 | selectedSegmentIndex = buttonIndex 298 | let startPosition = frame.width/CGFloat(buttons.count) * CGFloat(buttonIndex) 299 | if self.animate { 300 | UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: { 301 | self.selector.frame.origin.x = startPosition 302 | }, completion: nil) 303 | }else{ 304 | self.selector.frame.origin.x = startPosition 305 | } 306 | 307 | btn.tintColor = selectorTextColor 308 | btn.setTitleColor(selectorTextColor, for: .normal) 309 | } 310 | } 311 | } 312 | 313 | //MARK: chage Selector Color 314 | open func changeSelectedColor(_ color: UIColor) { 315 | self.selector.backgroundColor = color 316 | } 317 | 318 | } 319 | //MARK: UIbutton Extesion 320 | extension UIButton { 321 | func centerImageAndButton(_ gap: CGFloat, imageOnTop: Bool) { 322 | 323 | guard let imageView = self.currentImage, 324 | let titleLabel = self.titleLabel?.text else { return } 325 | 326 | let sign: CGFloat = imageOnTop ? 1 : -1 327 | self.titleEdgeInsets = UIEdgeInsets(top: (imageView.size.height + gap) * sign, left: -imageView.size.width, bottom: 0, right: 0); 328 | 329 | let titleSize = titleLabel.size(withAttributes:[NSAttributedString.Key.font: self.titleLabel!.font!]) 330 | self.imageEdgeInsets = UIEdgeInsets(top: -(titleSize.height + gap) * sign, left: 0, bottom: 0, right: -titleSize.width) 331 | } 332 | } 333 | 334 | extension Array { 335 | public subscript (safe index: Index) -> Element? { 336 | return indices.contains(index) ? self[index] : nil 337 | } 338 | } 339 | 340 | //MARK: Enums 341 | public enum SegementType: Int { 342 | case normal = 0, imageOnTop, onlyImage 343 | } 344 | 345 | public enum SelectorType: Int { 346 | case normal = 0, bottomBar 347 | } 348 | 349 | --------------------------------------------------------------------------------