├── CKSlideMenu.podspec ├── CKSlideMenu.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── CKSlideMenu.xcscmblueprint │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── caike.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── caike.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── CKSlideMenu.xcscheme │ └── xcschememanagement.plist ├── CKSlideMenuExample ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── CKChildViewController.swift ├── Info.plist └── ViewController.swift ├── LICENSE ├── OC版本 ├── CKSlideMenu-OC.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── caike.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── caike.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── CKSlideMenu-OC.xcscheme │ │ └── xcschememanagement.plist ├── CKSlideMenu-OC │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CKChildViewController.h │ ├── CKChildViewController.m │ ├── CkViewController.h │ ├── CkViewController.m │ ├── Info.plist │ ├── SlideMenu │ │ ├── CKSlideMenu.h │ │ └── CKSlideMenu.m │ ├── TableViewController.h │ ├── TableViewController.m │ └── main.m ├── CKSlideMenu-OCTests │ ├── CKSlideMenu_OCTests.m │ └── Info.plist └── CKSlideMenu-OCUITests │ ├── CKSlideMenu_OCUITests.m │ └── Info.plist ├── README.md ├── SlideMenu └── CKSlideMenu.swift ├── SlideMenu02.gif ├── SlideMenu03.gif └── SlideMneu01.gif /CKSlideMenu.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint CKSlideMenu.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "CKSlideMenu" 19 | s.version = "0.0.4" 20 | s.summary = "A SlideMenu for iOS" 21 | s.swift_version = "3.2" 22 | 23 | # This description is used to generate tags and improve search results. 24 | # * Think: What does it do? Why did you write it? What is the focus? 25 | # * Try to keep it short, snappy and to the point. 26 | # * Write the description between the DESC delimiters below. 27 | # * Finally, don't worry about the indent, CocoaPods strips it! 28 | s.description = "我是测试我是测试我是测试我是测试我是测试我是测试我是测试" 29 | 30 | s.homepage = "https://github.com/90ck/CKSlideMenu" 31 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 32 | 33 | 34 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 35 | # 36 | # Licensing your code is important. See http://choosealicense.com for more info. 37 | # CocoaPods will detect a license file if there is a named LICENSE* 38 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 39 | # 40 | 41 | s.license = { :type => "MIT", :file => "LICENSE"} 42 | # s.license = { :type => "MIT", :file => "FILE_LICENSE" } 43 | 44 | 45 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 46 | # 47 | # Specify the authors of the library, with email addresses. Email addresses 48 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 49 | # accepts just a name if you'd rather not provide an email address. 50 | # 51 | # Specify a social_media_url where others can refer to, for example a twitter 52 | # profile URL. 53 | # 54 | 55 | s.author = { "caike" => "caike@bmkp.cn" } 56 | # Or just: s.author = "caike" 57 | # s.authors = { "caike" => "caike@djcars.cn" } 58 | # s.social_media_url = "http://twitter.com/caike" 59 | 60 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 61 | # 62 | # If this Pod runs only on iOS or OS X, then specify the platform and 63 | # the deployment target. You can optionally include the target after the platform. 64 | # 65 | 66 | # s.platform = :ios 67 | s.platform = :ios, "8.0" 68 | 69 | # When using multiple platforms 70 | # s.ios.deployment_target = "5.0" 71 | # s.osx.deployment_target = "10.7" 72 | # s.watchos.deployment_target = "2.0" 73 | # s.tvos.deployment_target = "9.0" 74 | 75 | 76 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 77 | # 78 | # Specify the location from where the source should be retrieved. 79 | # Supports git, hg, bzr, svn and HTTP. 80 | # 81 | 82 | s.source = { :git => "https://github.com/90ck/CKSlideMenu.git", :tag => "#{s.version}" } 83 | 84 | 85 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 86 | # 87 | # CocoaPods is smart about how it includes source code. For source files 88 | # giving a folder will include any swift, h, m, mm, c & cpp files. 89 | # For header files it will include any header in the folder. 90 | # Not including the public_header_files will make all headers public. 91 | # 92 | 93 | s.source_files = "SlideMenu/" 94 | s.exclude_files = "Classes/Exclude" 95 | 96 | # s.public_header_files = "Classes/**/*.h" 97 | 98 | 99 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 100 | # 101 | # A list of resources included with the Pod. These are copied into the 102 | # target bundle with a build phase script. Anything else will be cleaned. 103 | # You can preserve files from being cleaned, please don't preserve 104 | # non-essential files like tests, examples and documentation. 105 | # 106 | 107 | # s.resource = "icon.png" 108 | # s.resources = "Resources/*.png" 109 | 110 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 111 | 112 | 113 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 114 | # 115 | # Link your library with frameworks, or libraries. Libraries do not include 116 | # the lib prefix of their name. 117 | # 118 | 119 | # s.framework = "SomeFramework" 120 | # s.frameworks = "SomeFramework", "AnotherFramework" 121 | 122 | # s.library = "iconv" 123 | # s.libraries = "iconv", "xml2" 124 | 125 | 126 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 127 | # 128 | # If your library depends on compiler flags you can set them in the xcconfig hash 129 | # where they will only apply to your library. If you depend on other Podspecs 130 | # you can include multiple dependencies to ensure it works. 131 | 132 | # s.requires_arc = true 133 | 134 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 135 | # s.dependency "JSONKit", "~> 1.4" 136 | 137 | #--swift-version = "3.2" 138 | 139 | end 140 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 67D5925320C688B600682ED8 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D5924820C688B500682ED8 /* ViewController.swift */; }; 11 | 67D5925520C688B600682ED8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67D5924B20C688B500682ED8 /* Assets.xcassets */; }; 12 | 67D5925620C688B600682ED8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67D5924C20C688B500682ED8 /* LaunchScreen.storyboard */; }; 13 | 67D5925720C688B600682ED8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67D5924E20C688B500682ED8 /* Main.storyboard */; }; 14 | 67D5925820C688B600682ED8 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D5925020C688B500682ED8 /* AppDelegate.swift */; }; 15 | 67D5925920C688B600682ED8 /* CKChildViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D5925120C688B500682ED8 /* CKChildViewController.swift */; }; 16 | 67D5925A20C688B600682ED8 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 67D5925220C688B500682ED8 /* Info.plist */; }; 17 | 67D5925F20C6893D00682ED8 /* CKSlideMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67D5925E20C6893D00682ED8 /* CKSlideMenu.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 673DF4C21EF79D7F0095BD94 /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 673DF4A51EF79D7F0095BD94 /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 673DF4AC1EF79D7F0095BD94; 26 | remoteInfo = CKSlideMenu; 27 | }; 28 | 673DF4CD1EF79D7F0095BD94 /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 673DF4A51EF79D7F0095BD94 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 673DF4AC1EF79D7F0095BD94; 33 | remoteInfo = CKSlideMenu; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 673DF4AD1EF79D7F0095BD94 /* CKSlideMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CKSlideMenu.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 673DF4C11EF79D7F0095BD94 /* CKSlideMenuTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKSlideMenuTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 673DF4CC1EF79D7F0095BD94 /* CKSlideMenuUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKSlideMenuUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 67D5924820C688B500682ED8 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 42 | 67D5924B20C688B500682ED8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 67D5924D20C688B500682ED8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 67D5924F20C688B500682ED8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 67D5925020C688B500682ED8 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | 67D5925120C688B500682ED8 /* CKChildViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CKChildViewController.swift; sourceTree = ""; }; 47 | 67D5925220C688B500682ED8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 67D5925E20C6893D00682ED8 /* CKSlideMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CKSlideMenu.swift; sourceTree = ""; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 673DF4AA1EF79D7F0095BD94 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | ); 57 | runOnlyForDeploymentPostprocessing = 0; 58 | }; 59 | 673DF4BE1EF79D7F0095BD94 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | 673DF4C91EF79D7F0095BD94 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 673DF4A41EF79D7F0095BD94 = { 77 | isa = PBXGroup; 78 | children = ( 79 | 67D5924720C688B500682ED8 /* CKSlideMenuExample */, 80 | 673DF4AE1EF79D7F0095BD94 /* Products */, 81 | ); 82 | sourceTree = ""; 83 | }; 84 | 673DF4AE1EF79D7F0095BD94 /* Products */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 673DF4AD1EF79D7F0095BD94 /* CKSlideMenu.app */, 88 | 673DF4C11EF79D7F0095BD94 /* CKSlideMenuTests.xctest */, 89 | 673DF4CC1EF79D7F0095BD94 /* CKSlideMenuUITests.xctest */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 67D5924720C688B500682ED8 /* CKSlideMenuExample */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 67D5924820C688B500682ED8 /* ViewController.swift */, 98 | 67D5925D20C6893D00682ED8 /* SlideMenu */, 99 | 67D5924B20C688B500682ED8 /* Assets.xcassets */, 100 | 67D5924C20C688B500682ED8 /* LaunchScreen.storyboard */, 101 | 67D5924E20C688B500682ED8 /* Main.storyboard */, 102 | 67D5925020C688B500682ED8 /* AppDelegate.swift */, 103 | 67D5925120C688B500682ED8 /* CKChildViewController.swift */, 104 | 67D5925220C688B500682ED8 /* Info.plist */, 105 | ); 106 | path = CKSlideMenuExample; 107 | sourceTree = SOURCE_ROOT; 108 | }; 109 | 67D5925D20C6893D00682ED8 /* SlideMenu */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 67D5925E20C6893D00682ED8 /* CKSlideMenu.swift */, 113 | ); 114 | path = SlideMenu; 115 | sourceTree = SOURCE_ROOT; 116 | }; 117 | /* End PBXGroup section */ 118 | 119 | /* Begin PBXNativeTarget section */ 120 | 673DF4AC1EF79D7F0095BD94 /* CKSlideMenu */ = { 121 | isa = PBXNativeTarget; 122 | buildConfigurationList = 673DF4D51EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenu" */; 123 | buildPhases = ( 124 | 673DF4A91EF79D7F0095BD94 /* Sources */, 125 | 673DF4AA1EF79D7F0095BD94 /* Frameworks */, 126 | 673DF4AB1EF79D7F0095BD94 /* Resources */, 127 | ); 128 | buildRules = ( 129 | ); 130 | dependencies = ( 131 | ); 132 | name = CKSlideMenu; 133 | productName = CKSlideMenu; 134 | productReference = 673DF4AD1EF79D7F0095BD94 /* CKSlideMenu.app */; 135 | productType = "com.apple.product-type.application"; 136 | }; 137 | 673DF4C01EF79D7F0095BD94 /* CKSlideMenuTests */ = { 138 | isa = PBXNativeTarget; 139 | buildConfigurationList = 673DF4D81EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenuTests" */; 140 | buildPhases = ( 141 | 673DF4BD1EF79D7F0095BD94 /* Sources */, 142 | 673DF4BE1EF79D7F0095BD94 /* Frameworks */, 143 | 673DF4BF1EF79D7F0095BD94 /* Resources */, 144 | ); 145 | buildRules = ( 146 | ); 147 | dependencies = ( 148 | 673DF4C31EF79D7F0095BD94 /* PBXTargetDependency */, 149 | ); 150 | name = CKSlideMenuTests; 151 | productName = CKSlideMenuTests; 152 | productReference = 673DF4C11EF79D7F0095BD94 /* CKSlideMenuTests.xctest */; 153 | productType = "com.apple.product-type.bundle.unit-test"; 154 | }; 155 | 673DF4CB1EF79D7F0095BD94 /* CKSlideMenuUITests */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 673DF4DB1EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenuUITests" */; 158 | buildPhases = ( 159 | 673DF4C81EF79D7F0095BD94 /* Sources */, 160 | 673DF4C91EF79D7F0095BD94 /* Frameworks */, 161 | 673DF4CA1EF79D7F0095BD94 /* Resources */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | 673DF4CE1EF79D7F0095BD94 /* PBXTargetDependency */, 167 | ); 168 | name = CKSlideMenuUITests; 169 | productName = CKSlideMenuUITests; 170 | productReference = 673DF4CC1EF79D7F0095BD94 /* CKSlideMenuUITests.xctest */; 171 | productType = "com.apple.product-type.bundle.ui-testing"; 172 | }; 173 | /* End PBXNativeTarget section */ 174 | 175 | /* Begin PBXProject section */ 176 | 673DF4A51EF79D7F0095BD94 /* Project object */ = { 177 | isa = PBXProject; 178 | attributes = { 179 | LastSwiftUpdateCheck = 0830; 180 | LastUpgradeCheck = 0830; 181 | ORGANIZATIONNAME = caike; 182 | TargetAttributes = { 183 | 673DF4AC1EF79D7F0095BD94 = { 184 | CreatedOnToolsVersion = 8.3.3; 185 | DevelopmentTeam = L855ZMKEYR; 186 | ProvisioningStyle = Automatic; 187 | }; 188 | 673DF4C01EF79D7F0095BD94 = { 189 | CreatedOnToolsVersion = 8.3.3; 190 | DevelopmentTeam = U5S4SZQP26; 191 | ProvisioningStyle = Automatic; 192 | TestTargetID = 673DF4AC1EF79D7F0095BD94; 193 | }; 194 | 673DF4CB1EF79D7F0095BD94 = { 195 | CreatedOnToolsVersion = 8.3.3; 196 | DevelopmentTeam = U5S4SZQP26; 197 | ProvisioningStyle = Automatic; 198 | TestTargetID = 673DF4AC1EF79D7F0095BD94; 199 | }; 200 | }; 201 | }; 202 | buildConfigurationList = 673DF4A81EF79D7F0095BD94 /* Build configuration list for PBXProject "CKSlideMenu" */; 203 | compatibilityVersion = "Xcode 3.2"; 204 | developmentRegion = English; 205 | hasScannedForEncodings = 0; 206 | knownRegions = ( 207 | en, 208 | Base, 209 | ); 210 | mainGroup = 673DF4A41EF79D7F0095BD94; 211 | productRefGroup = 673DF4AE1EF79D7F0095BD94 /* Products */; 212 | projectDirPath = ""; 213 | projectRoot = ""; 214 | targets = ( 215 | 673DF4AC1EF79D7F0095BD94 /* CKSlideMenu */, 216 | 673DF4C01EF79D7F0095BD94 /* CKSlideMenuTests */, 217 | 673DF4CB1EF79D7F0095BD94 /* CKSlideMenuUITests */, 218 | ); 219 | }; 220 | /* End PBXProject section */ 221 | 222 | /* Begin PBXResourcesBuildPhase section */ 223 | 673DF4AB1EF79D7F0095BD94 /* Resources */ = { 224 | isa = PBXResourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | 67D5925520C688B600682ED8 /* Assets.xcassets in Resources */, 228 | 67D5925720C688B600682ED8 /* Main.storyboard in Resources */, 229 | 67D5925620C688B600682ED8 /* LaunchScreen.storyboard in Resources */, 230 | 67D5925A20C688B600682ED8 /* Info.plist in Resources */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | 673DF4BF1EF79D7F0095BD94 /* Resources */ = { 235 | isa = PBXResourcesBuildPhase; 236 | buildActionMask = 2147483647; 237 | files = ( 238 | ); 239 | runOnlyForDeploymentPostprocessing = 0; 240 | }; 241 | 673DF4CA1EF79D7F0095BD94 /* Resources */ = { 242 | isa = PBXResourcesBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | }; 248 | /* End PBXResourcesBuildPhase section */ 249 | 250 | /* Begin PBXSourcesBuildPhase section */ 251 | 673DF4A91EF79D7F0095BD94 /* Sources */ = { 252 | isa = PBXSourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | 67D5925F20C6893D00682ED8 /* CKSlideMenu.swift in Sources */, 256 | 67D5925320C688B600682ED8 /* ViewController.swift in Sources */, 257 | 67D5925820C688B600682ED8 /* AppDelegate.swift in Sources */, 258 | 67D5925920C688B600682ED8 /* CKChildViewController.swift in Sources */, 259 | ); 260 | runOnlyForDeploymentPostprocessing = 0; 261 | }; 262 | 673DF4BD1EF79D7F0095BD94 /* Sources */ = { 263 | isa = PBXSourcesBuildPhase; 264 | buildActionMask = 2147483647; 265 | files = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | 673DF4C81EF79D7F0095BD94 /* Sources */ = { 270 | isa = PBXSourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXSourcesBuildPhase section */ 277 | 278 | /* Begin PBXTargetDependency section */ 279 | 673DF4C31EF79D7F0095BD94 /* PBXTargetDependency */ = { 280 | isa = PBXTargetDependency; 281 | target = 673DF4AC1EF79D7F0095BD94 /* CKSlideMenu */; 282 | targetProxy = 673DF4C21EF79D7F0095BD94 /* PBXContainerItemProxy */; 283 | }; 284 | 673DF4CE1EF79D7F0095BD94 /* PBXTargetDependency */ = { 285 | isa = PBXTargetDependency; 286 | target = 673DF4AC1EF79D7F0095BD94 /* CKSlideMenu */; 287 | targetProxy = 673DF4CD1EF79D7F0095BD94 /* PBXContainerItemProxy */; 288 | }; 289 | /* End PBXTargetDependency section */ 290 | 291 | /* Begin PBXVariantGroup section */ 292 | 67D5924C20C688B500682ED8 /* LaunchScreen.storyboard */ = { 293 | isa = PBXVariantGroup; 294 | children = ( 295 | 67D5924D20C688B500682ED8 /* Base */, 296 | ); 297 | name = LaunchScreen.storyboard; 298 | sourceTree = ""; 299 | }; 300 | 67D5924E20C688B500682ED8 /* Main.storyboard */ = { 301 | isa = PBXVariantGroup; 302 | children = ( 303 | 67D5924F20C688B500682ED8 /* Base */, 304 | ); 305 | name = Main.storyboard; 306 | sourceTree = ""; 307 | }; 308 | /* End PBXVariantGroup section */ 309 | 310 | /* Begin XCBuildConfiguration section */ 311 | 673DF4D31EF79D7F0095BD94 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ALWAYS_SEARCH_USER_PATHS = NO; 315 | CLANG_ANALYZER_NONNULL = YES; 316 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BOOL_CONVERSION = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 324 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = NO; 335 | DEBUG_INFORMATION_FORMAT = dwarf; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | ENABLE_TESTABILITY = YES; 338 | GCC_C_LANGUAGE_STANDARD = gnu99; 339 | GCC_DYNAMIC_NO_PIC = NO; 340 | GCC_NO_COMMON_BLOCKS = YES; 341 | GCC_OPTIMIZATION_LEVEL = 0; 342 | GCC_PREPROCESSOR_DEFINITIONS = ( 343 | "DEBUG=1", 344 | "$(inherited)", 345 | ); 346 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 347 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 348 | GCC_WARN_UNDECLARED_SELECTOR = YES; 349 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 350 | GCC_WARN_UNUSED_FUNCTION = YES; 351 | GCC_WARN_UNUSED_VARIABLE = YES; 352 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 353 | MTL_ENABLE_DEBUG_INFO = YES; 354 | ONLY_ACTIVE_ARCH = YES; 355 | SDKROOT = iphoneos; 356 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 357 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 358 | }; 359 | name = Debug; 360 | }; 361 | 673DF4D41EF79D7F0095BD94 /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_ANALYZER_NONNULL = YES; 366 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 367 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 368 | CLANG_CXX_LIBRARY = "libc++"; 369 | CLANG_ENABLE_MODULES = YES; 370 | CLANG_ENABLE_OBJC_ARC = YES; 371 | CLANG_WARN_BOOL_CONVERSION = YES; 372 | CLANG_WARN_CONSTANT_CONVERSION = YES; 373 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 374 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 375 | CLANG_WARN_EMPTY_BODY = YES; 376 | CLANG_WARN_ENUM_CONVERSION = YES; 377 | CLANG_WARN_INFINITE_RECURSION = YES; 378 | CLANG_WARN_INT_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 381 | CLANG_WARN_UNREACHABLE_CODE = YES; 382 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 383 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 384 | COPY_PHASE_STRIP = NO; 385 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 386 | ENABLE_NS_ASSERTIONS = NO; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | GCC_C_LANGUAGE_STANDARD = gnu99; 389 | GCC_NO_COMMON_BLOCKS = YES; 390 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 391 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 392 | GCC_WARN_UNDECLARED_SELECTOR = YES; 393 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 394 | GCC_WARN_UNUSED_FUNCTION = YES; 395 | GCC_WARN_UNUSED_VARIABLE = YES; 396 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 397 | MTL_ENABLE_DEBUG_INFO = NO; 398 | SDKROOT = iphoneos; 399 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 400 | VALIDATE_PRODUCT = YES; 401 | }; 402 | name = Release; 403 | }; 404 | 673DF4D61EF79D7F0095BD94 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 408 | DEVELOPMENT_TEAM = L855ZMKEYR; 409 | INFOPLIST_FILE = CKSlideMenuExample/Info.plist; 410 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 411 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 412 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenu; 413 | PRODUCT_NAME = "$(TARGET_NAME)"; 414 | SWIFT_VERSION = 3.0; 415 | }; 416 | name = Debug; 417 | }; 418 | 673DF4D71EF79D7F0095BD94 /* Release */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 422 | DEVELOPMENT_TEAM = L855ZMKEYR; 423 | INFOPLIST_FILE = CKSlideMenuExample/Info.plist; 424 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 425 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 426 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenu; 427 | PRODUCT_NAME = "$(TARGET_NAME)"; 428 | SWIFT_VERSION = 3.0; 429 | }; 430 | name = Release; 431 | }; 432 | 673DF4D91EF79D7F0095BD94 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 436 | BUNDLE_LOADER = "$(TEST_HOST)"; 437 | DEVELOPMENT_TEAM = U5S4SZQP26; 438 | INFOPLIST_FILE = CKSlideMenuTests/Info.plist; 439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 440 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenuTests; 441 | PRODUCT_NAME = "$(TARGET_NAME)"; 442 | SWIFT_VERSION = 3.0; 443 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CKSlideMenu.app/CKSlideMenu"; 444 | }; 445 | name = Debug; 446 | }; 447 | 673DF4DA1EF79D7F0095BD94 /* Release */ = { 448 | isa = XCBuildConfiguration; 449 | buildSettings = { 450 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 451 | BUNDLE_LOADER = "$(TEST_HOST)"; 452 | DEVELOPMENT_TEAM = U5S4SZQP26; 453 | INFOPLIST_FILE = CKSlideMenuTests/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 455 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenuTests; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | SWIFT_VERSION = 3.0; 458 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CKSlideMenu.app/CKSlideMenu"; 459 | }; 460 | name = Release; 461 | }; 462 | 673DF4DC1EF79D7F0095BD94 /* Debug */ = { 463 | isa = XCBuildConfiguration; 464 | buildSettings = { 465 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 466 | DEVELOPMENT_TEAM = U5S4SZQP26; 467 | INFOPLIST_FILE = CKSlideMenuUITests/Info.plist; 468 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 469 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenuUITests; 470 | PRODUCT_NAME = "$(TARGET_NAME)"; 471 | SWIFT_VERSION = 3.0; 472 | TEST_TARGET_NAME = CKSlideMenu; 473 | }; 474 | name = Debug; 475 | }; 476 | 673DF4DD1EF79D7F0095BD94 /* Release */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 480 | DEVELOPMENT_TEAM = U5S4SZQP26; 481 | INFOPLIST_FILE = CKSlideMenuUITests/Info.plist; 482 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 483 | PRODUCT_BUNDLE_IDENTIFIER = com.caidake.CKSlideMenuUITests; 484 | PRODUCT_NAME = "$(TARGET_NAME)"; 485 | SWIFT_VERSION = 3.0; 486 | TEST_TARGET_NAME = CKSlideMenu; 487 | }; 488 | name = Release; 489 | }; 490 | /* End XCBuildConfiguration section */ 491 | 492 | /* Begin XCConfigurationList section */ 493 | 673DF4A81EF79D7F0095BD94 /* Build configuration list for PBXProject "CKSlideMenu" */ = { 494 | isa = XCConfigurationList; 495 | buildConfigurations = ( 496 | 673DF4D31EF79D7F0095BD94 /* Debug */, 497 | 673DF4D41EF79D7F0095BD94 /* Release */, 498 | ); 499 | defaultConfigurationIsVisible = 0; 500 | defaultConfigurationName = Release; 501 | }; 502 | 673DF4D51EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenu" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 673DF4D61EF79D7F0095BD94 /* Debug */, 506 | 673DF4D71EF79D7F0095BD94 /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | 673DF4D81EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenuTests" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 673DF4D91EF79D7F0095BD94 /* Debug */, 515 | 673DF4DA1EF79D7F0095BD94 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | defaultConfigurationName = Release; 519 | }; 520 | 673DF4DB1EF79D7F0095BD94 /* Build configuration list for PBXNativeTarget "CKSlideMenuUITests" */ = { 521 | isa = XCConfigurationList; 522 | buildConfigurations = ( 523 | 673DF4DC1EF79D7F0095BD94 /* Debug */, 524 | 673DF4DD1EF79D7F0095BD94 /* Release */, 525 | ); 526 | defaultConfigurationIsVisible = 0; 527 | defaultConfigurationName = Release; 528 | }; 529 | /* End XCConfigurationList section */ 530 | }; 531 | rootObject = 673DF4A51EF79D7F0095BD94 /* Project object */; 532 | } 533 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/project.xcworkspace/xcshareddata/CKSlideMenu.xcscmblueprint: -------------------------------------------------------------------------------- 1 | { 2 | "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "2B45ADBEF0FD29ED1F5FDACEE4DCF25E58E3B62A", 3 | "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { 4 | 5 | }, 6 | "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { 7 | "FA60C986F29F46A6FAE375CC97183B4B6F231023" : 9223372036854775807, 8 | "2B45ADBEF0FD29ED1F5FDACEE4DCF25E58E3B62A" : 9223372036854775807 9 | }, 10 | "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "FF131217-75B2-4D4F-BDE5-97AFFDC67D38", 11 | "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { 12 | "FA60C986F29F46A6FAE375CC97183B4B6F231023" : "..\/..", 13 | "2B45ADBEF0FD29ED1F5FDACEE4DCF25E58E3B62A" : "CKSlideMenu\/" 14 | }, 15 | "DVTSourceControlWorkspaceBlueprintNameKey" : "CKSlideMenu", 16 | "DVTSourceControlWorkspaceBlueprintVersion" : 204, 17 | "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "CKSlideMenu\/CKSlideMenu.xcodeproj", 18 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ 19 | { 20 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "ssh:\/\/github.com\/90ck\/CKSlideMenu.git", 21 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 22 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "2B45ADBEF0FD29ED1F5FDACEE4DCF25E58E3B62A" 23 | }, 24 | { 25 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "git.coding.net:anke90\/work.git", 26 | "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git", 27 | "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "FA60C986F29F46A6FAE375CC97183B4B6F231023" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/project.xcworkspace/xcuserdata/caike.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/90ck/CKSlideMenu/08a6f16a34a6d9005337b367a7ad2b1a790d8a2c/CKSlideMenu.xcodeproj/project.xcworkspace/xcuserdata/caike.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/xcuserdata/caike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/xcuserdata/caike.xcuserdatad/xcschemes/CKSlideMenu.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /CKSlideMenu.xcodeproj/xcuserdata/caike.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CKSlideMenu.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 673DF4AC1EF79D7F0095BD94 16 | 17 | primary 18 | 19 | 20 | 673DF4C01EF79D7F0095BD94 21 | 22 | primary 23 | 24 | 25 | 673DF4CB1EF79D7F0095BD94 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /CKSlideMenuExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CKSlideMenu 4 | // 5 | // Created by ck on 2017/6/19. 6 | // Copyright © 2017年 caike. 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 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /CKSlideMenuExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /CKSlideMenuExample/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 | -------------------------------------------------------------------------------- /CKSlideMenuExample/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 | 31 | 38 | 45 | 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 | -------------------------------------------------------------------------------- /CKSlideMenuExample/CKChildViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKChildViewController.swift 3 | // CKSlideMenu 4 | // 5 | // Created by ck on 2017/6/19. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class CKChildViewController: UIViewController { 12 | 13 | var exmapleIndex = 0 14 | var slideMenu:CKSlideMenu? 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | self.automaticallyAdjustsScrollViewInsets = false 19 | view.backgroundColor = UIColor.white 20 | 21 | switch exmapleIndex { 22 | case 0: 23 | view.backgroundColor = UIColor.init(red: CGFloat(arc4random()%256)/255, green: CGFloat(arc4random()%256)/255, blue: CGFloat(arc4random()%256)/255, alpha: 1) 24 | case 1: 25 | example1() 26 | case 2: 27 | example2() 28 | case 3: 29 | example3() 30 | case 4: 31 | example4() 32 | default: 33 | break 34 | } 35 | 36 | } 37 | 38 | func example1() { 39 | let titles = ["今天","速度","是啊","测试","水电","今天","速度","是啊","今天","速度","是啊"] 40 | var arr:Array = [] 41 | for _ in 0 ..< titles.count { 42 | let vc = CKChildViewController() 43 | self.addChildViewController(vc) 44 | arr.append(vc) 45 | } 46 | slideMenu = CKSlideMenu(frame: CGRect(x:0,y:64,width:view.frame.width,height:40), titles:titles, childControllers:arr) 47 | slideMenu?.bodyFrame = CGRect.init(x: 0, y: 104, width: view.frame.width, height: view.frame.height - 104) 48 | slideMenu?.scrollToIndex(3) 49 | view.addSubview(slideMenu!) 50 | } 51 | 52 | func example2() { 53 | let titles = ["今天","速度100","是啊","测试机","水电","今天","速度","是啊","今天","速度","是啊"] 54 | var arr:Array = [] 55 | for _ in 0 ..< titles.count { 56 | let vc = CKChildViewController() 57 | self.addChildViewController(vc) 58 | arr.append(vc) 59 | } 60 | slideMenu = CKSlideMenu(frame: CGRect(x:0,y:64,width:view.frame.width,height:40), titles:titles, childControllers:arr) 61 | slideMenu?.indicatorStyle = .stretch 62 | slideMenu?.bottomPadding = 2 63 | slideMenu?.titleStyle = .transfrom 64 | slideMenu?.selectedColor = UIColor.orange 65 | slideMenu?.unSelectedColor = UIColor.gray 66 | slideMenu?.bodySuperView = view 67 | slideMenu?.bodyFrame = CGRect.init(x: 0, y: 104, width: view.frame.width, height: view.frame.height - 104) 68 | view.addSubview(slideMenu!) 69 | } 70 | 71 | func example3() { 72 | let titles = ["今天","速度","是啊"] 73 | var arr:Array = [] 74 | for _ in 0 ..< titles.count { 75 | let vc = CKChildViewController() 76 | self.addChildViewController(vc) 77 | arr.append(vc) 78 | } 79 | slideMenu = CKSlideMenu(frame: CGRect(x:0,y:0,width:view.frame.width,height:40), titles:titles, childControllers:arr) 80 | slideMenu?.indicatorStyle = .stretch 81 | slideMenu?.titleStyle = .transfrom 82 | slideMenu?.indicatorHeight = 1.5 83 | slideMenu?.bodySuperView = view 84 | slideMenu?.indicatorView.backgroundColor = UIColor.orange 85 | slideMenu?.isFixed = true 86 | slideMenu?.bodyFrame = CGRect.init(x: 0, y: 64, width: view.frame.width, height: view.frame.height - 64) 87 | slideMenu?.font = UIFont.systemFont(ofSize: 12) 88 | // slideMenu?.indicatorAnimatePadding = 0 89 | slideMenu?.indicatorAnimatePadding = 15 90 | navigationItem.titleView = slideMenu 91 | 92 | } 93 | 94 | func example4() { 95 | let titles = ["今天","速度100","是啊","测试机","水电","今天","速度","是啊","今天","速度","是啊"] 96 | var arr:Array = [] 97 | for _ in 0 ..< titles.count { 98 | let vc = CKChildViewController() 99 | self.addChildViewController(vc) 100 | arr.append(vc) 101 | } 102 | slideMenu = CKSlideMenu(frame: CGRect(x:0,y:64,width:view.frame.width,height:40), titles:titles, childControllers:arr) 103 | 104 | slideMenu?.titleStyle = .gradient 105 | slideMenu?.indicatorStyle = .followText 106 | slideMenu?.unSelectedColor = UIColor.gray 107 | slideMenu?.bottomPadding = 4 108 | slideMenu?.indicatorHeight = 2 109 | slideMenu?.bodySuperView = view 110 | slideMenu?.bodyFrame = CGRect.init(x: 0, y: 104, width: view.frame.width, height: view.frame.height - 104) 111 | view.addSubview(slideMenu!) 112 | } 113 | 114 | 115 | override func didReceiveMemoryWarning() { 116 | super.didReceiveMemoryWarning() 117 | // Dispose of any resources that can be recreated. 118 | } 119 | 120 | 121 | /* 122 | // MARK: - Navigation 123 | 124 | // In a storyboard-based application, you will often want to do a little preparation before navigation 125 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 126 | // Get the new view controller using segue.destinationViewController. 127 | // Pass the selected object to the new view controller. 128 | } 129 | */ 130 | 131 | } 132 | -------------------------------------------------------------------------------- /CKSlideMenuExample/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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /CKSlideMenuExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // CKSlideMenu 4 | // 5 | // Created by ck on 2017/6/19. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | var slideMenu:CKSlideMenu? 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | 18 | view.backgroundColor = UIColor.white 19 | self.automaticallyAdjustsScrollViewInsets = false 20 | 21 | self.title = "Demo" 22 | 23 | } 24 | 25 | override func didReceiveMemoryWarning() { 26 | super.didReceiveMemoryWarning() 27 | // Dispose of any resources that can be recreated. 28 | } 29 | 30 | 31 | @IBAction func example1(_ sender: Any) { 32 | let vc = CKChildViewController() 33 | vc.exmapleIndex = 1 34 | navigationController?.pushViewController(vc, animated: true) 35 | } 36 | 37 | @IBAction func example2(_ sender: Any) { 38 | let vc = CKChildViewController() 39 | vc.exmapleIndex = 2 40 | navigationController?.pushViewController(vc, animated: true) 41 | } 42 | 43 | @IBAction func example3(_ sender: Any) { 44 | let vc = CKChildViewController() 45 | vc.exmapleIndex = 3 46 | navigationController?.pushViewController(vc, animated: true) 47 | } 48 | 49 | @IBAction func example4(_ sender: Any) { 50 | let vc = CKChildViewController() 51 | vc.exmapleIndex = 4 52 | navigationController?.pushViewController(vc, animated: true) 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright © 2018 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 67F4FD9B1F4B22D8006696ED /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FD9A1F4B22D8006696ED /* main.m */; }; 11 | 67F4FD9E1F4B22D8006696ED /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FD9D1F4B22D8006696ED /* AppDelegate.m */; }; 12 | 67F4FDA41F4B22D8006696ED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67F4FDA21F4B22D8006696ED /* Main.storyboard */; }; 13 | 67F4FDA61F4B22D8006696ED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 67F4FDA51F4B22D8006696ED /* Assets.xcassets */; }; 14 | 67F4FDA91F4B22D8006696ED /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 67F4FDA71F4B22D8006696ED /* LaunchScreen.storyboard */; }; 15 | 67F4FDB41F4B22D8006696ED /* CKSlideMenu_OCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FDB31F4B22D8006696ED /* CKSlideMenu_OCTests.m */; }; 16 | 67F4FDBF1F4B22D9006696ED /* CKSlideMenu_OCUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FDBE1F4B22D9006696ED /* CKSlideMenu_OCUITests.m */; }; 17 | 67F4FDCE1F4B2333006696ED /* CKChildViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FDCD1F4B2333006696ED /* CKChildViewController.m */; }; 18 | 67F4FDD21F4B2362006696ED /* CKSlideMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FDD11F4B2362006696ED /* CKSlideMenu.m */; }; 19 | 67F4FDD51F4B23B2006696ED /* TableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 67F4FDD41F4B23B2006696ED /* TableViewController.m */; }; 20 | 67FE19651F4EB6D10066D7FC /* CkViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 67FE19641F4EB6D10066D7FC /* CkViewController.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | 67F4FDB01F4B22D8006696ED /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = 67F4FD8E1F4B22D8006696ED /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = 67F4FD951F4B22D8006696ED; 29 | remoteInfo = "CKSlideMenu-OC"; 30 | }; 31 | 67F4FDBB1F4B22D9006696ED /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = 67F4FD8E1F4B22D8006696ED /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = 67F4FD951F4B22D8006696ED; 36 | remoteInfo = "CKSlideMenu-OC"; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | 67F4FD961F4B22D8006696ED /* CKSlideMenu-OC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "CKSlideMenu-OC.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | 67F4FD9A1F4B22D8006696ED /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 43 | 67F4FD9C1F4B22D8006696ED /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 44 | 67F4FD9D1F4B22D8006696ED /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 45 | 67F4FDA31F4B22D8006696ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 67F4FDA51F4B22D8006696ED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 67F4FDA81F4B22D8006696ED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 67F4FDAA1F4B22D8006696ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 67F4FDAF1F4B22D8006696ED /* CKSlideMenu-OCTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "CKSlideMenu-OCTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 67F4FDB31F4B22D8006696ED /* CKSlideMenu_OCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKSlideMenu_OCTests.m; sourceTree = ""; }; 51 | 67F4FDB51F4B22D8006696ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 67F4FDBA1F4B22D9006696ED /* CKSlideMenu-OCUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "CKSlideMenu-OCUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 67F4FDBE1F4B22D9006696ED /* CKSlideMenu_OCUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKSlideMenu_OCUITests.m; sourceTree = ""; }; 54 | 67F4FDC01F4B22D9006696ED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 67F4FDCC1F4B2333006696ED /* CKChildViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKChildViewController.h; sourceTree = ""; }; 56 | 67F4FDCD1F4B2333006696ED /* CKChildViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKChildViewController.m; sourceTree = ""; }; 57 | 67F4FDD01F4B2362006696ED /* CKSlideMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKSlideMenu.h; sourceTree = ""; }; 58 | 67F4FDD11F4B2362006696ED /* CKSlideMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKSlideMenu.m; sourceTree = ""; }; 59 | 67F4FDD31F4B23B2006696ED /* TableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableViewController.h; sourceTree = ""; }; 60 | 67F4FDD41F4B23B2006696ED /* TableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableViewController.m; sourceTree = ""; }; 61 | 67FE19631F4EB6D10066D7FC /* CkViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CkViewController.h; sourceTree = ""; }; 62 | 67FE19641F4EB6D10066D7FC /* CkViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CkViewController.m; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 67F4FD931F4B22D8006696ED /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | 67F4FDAC1F4B22D8006696ED /* Frameworks */ = { 74 | isa = PBXFrameworksBuildPhase; 75 | buildActionMask = 2147483647; 76 | files = ( 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | 67F4FDB71F4B22D9006696ED /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 67F4FD8D1F4B22D8006696ED = { 91 | isa = PBXGroup; 92 | children = ( 93 | 67F4FD981F4B22D8006696ED /* CKSlideMenu-OC */, 94 | 67F4FDB21F4B22D8006696ED /* CKSlideMenu-OCTests */, 95 | 67F4FDBD1F4B22D9006696ED /* CKSlideMenu-OCUITests */, 96 | 67F4FD971F4B22D8006696ED /* Products */, 97 | ); 98 | sourceTree = ""; 99 | }; 100 | 67F4FD971F4B22D8006696ED /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 67F4FD961F4B22D8006696ED /* CKSlideMenu-OC.app */, 104 | 67F4FDAF1F4B22D8006696ED /* CKSlideMenu-OCTests.xctest */, 105 | 67F4FDBA1F4B22D9006696ED /* CKSlideMenu-OCUITests.xctest */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | 67F4FD981F4B22D8006696ED /* CKSlideMenu-OC */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 67F4FD9C1F4B22D8006696ED /* AppDelegate.h */, 114 | 67F4FD9D1F4B22D8006696ED /* AppDelegate.m */, 115 | 67F4FDD31F4B23B2006696ED /* TableViewController.h */, 116 | 67F4FDD41F4B23B2006696ED /* TableViewController.m */, 117 | 67F4FDCC1F4B2333006696ED /* CKChildViewController.h */, 118 | 67F4FDCD1F4B2333006696ED /* CKChildViewController.m */, 119 | 67FE19631F4EB6D10066D7FC /* CkViewController.h */, 120 | 67FE19641F4EB6D10066D7FC /* CkViewController.m */, 121 | 67F4FDCF1F4B2350006696ED /* SlideMenu */, 122 | 67F4FDA21F4B22D8006696ED /* Main.storyboard */, 123 | 67F4FDA51F4B22D8006696ED /* Assets.xcassets */, 124 | 67F4FDA71F4B22D8006696ED /* LaunchScreen.storyboard */, 125 | 67F4FDAA1F4B22D8006696ED /* Info.plist */, 126 | 67F4FD991F4B22D8006696ED /* Supporting Files */, 127 | ); 128 | path = "CKSlideMenu-OC"; 129 | sourceTree = ""; 130 | }; 131 | 67F4FD991F4B22D8006696ED /* Supporting Files */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 67F4FD9A1F4B22D8006696ED /* main.m */, 135 | ); 136 | name = "Supporting Files"; 137 | sourceTree = ""; 138 | }; 139 | 67F4FDB21F4B22D8006696ED /* CKSlideMenu-OCTests */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 67F4FDB31F4B22D8006696ED /* CKSlideMenu_OCTests.m */, 143 | 67F4FDB51F4B22D8006696ED /* Info.plist */, 144 | ); 145 | path = "CKSlideMenu-OCTests"; 146 | sourceTree = ""; 147 | }; 148 | 67F4FDBD1F4B22D9006696ED /* CKSlideMenu-OCUITests */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 67F4FDBE1F4B22D9006696ED /* CKSlideMenu_OCUITests.m */, 152 | 67F4FDC01F4B22D9006696ED /* Info.plist */, 153 | ); 154 | path = "CKSlideMenu-OCUITests"; 155 | sourceTree = ""; 156 | }; 157 | 67F4FDCF1F4B2350006696ED /* SlideMenu */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 67F4FDD01F4B2362006696ED /* CKSlideMenu.h */, 161 | 67F4FDD11F4B2362006696ED /* CKSlideMenu.m */, 162 | ); 163 | path = SlideMenu; 164 | sourceTree = ""; 165 | }; 166 | /* End PBXGroup section */ 167 | 168 | /* Begin PBXNativeTarget section */ 169 | 67F4FD951F4B22D8006696ED /* CKSlideMenu-OC */ = { 170 | isa = PBXNativeTarget; 171 | buildConfigurationList = 67F4FDC31F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OC" */; 172 | buildPhases = ( 173 | 67F4FD921F4B22D8006696ED /* Sources */, 174 | 67F4FD931F4B22D8006696ED /* Frameworks */, 175 | 67F4FD941F4B22D8006696ED /* Resources */, 176 | ); 177 | buildRules = ( 178 | ); 179 | dependencies = ( 180 | ); 181 | name = "CKSlideMenu-OC"; 182 | productName = "CKSlideMenu-OC"; 183 | productReference = 67F4FD961F4B22D8006696ED /* CKSlideMenu-OC.app */; 184 | productType = "com.apple.product-type.application"; 185 | }; 186 | 67F4FDAE1F4B22D8006696ED /* CKSlideMenu-OCTests */ = { 187 | isa = PBXNativeTarget; 188 | buildConfigurationList = 67F4FDC61F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OCTests" */; 189 | buildPhases = ( 190 | 67F4FDAB1F4B22D8006696ED /* Sources */, 191 | 67F4FDAC1F4B22D8006696ED /* Frameworks */, 192 | 67F4FDAD1F4B22D8006696ED /* Resources */, 193 | ); 194 | buildRules = ( 195 | ); 196 | dependencies = ( 197 | 67F4FDB11F4B22D8006696ED /* PBXTargetDependency */, 198 | ); 199 | name = "CKSlideMenu-OCTests"; 200 | productName = "CKSlideMenu-OCTests"; 201 | productReference = 67F4FDAF1F4B22D8006696ED /* CKSlideMenu-OCTests.xctest */; 202 | productType = "com.apple.product-type.bundle.unit-test"; 203 | }; 204 | 67F4FDB91F4B22D9006696ED /* CKSlideMenu-OCUITests */ = { 205 | isa = PBXNativeTarget; 206 | buildConfigurationList = 67F4FDC91F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OCUITests" */; 207 | buildPhases = ( 208 | 67F4FDB61F4B22D9006696ED /* Sources */, 209 | 67F4FDB71F4B22D9006696ED /* Frameworks */, 210 | 67F4FDB81F4B22D9006696ED /* Resources */, 211 | ); 212 | buildRules = ( 213 | ); 214 | dependencies = ( 215 | 67F4FDBC1F4B22D9006696ED /* PBXTargetDependency */, 216 | ); 217 | name = "CKSlideMenu-OCUITests"; 218 | productName = "CKSlideMenu-OCUITests"; 219 | productReference = 67F4FDBA1F4B22D9006696ED /* CKSlideMenu-OCUITests.xctest */; 220 | productType = "com.apple.product-type.bundle.ui-testing"; 221 | }; 222 | /* End PBXNativeTarget section */ 223 | 224 | /* Begin PBXProject section */ 225 | 67F4FD8E1F4B22D8006696ED /* Project object */ = { 226 | isa = PBXProject; 227 | attributes = { 228 | LastUpgradeCheck = 0830; 229 | ORGANIZATIONNAME = caike; 230 | TargetAttributes = { 231 | 67F4FD951F4B22D8006696ED = { 232 | CreatedOnToolsVersion = 8.3.3; 233 | DevelopmentTeam = L855ZMKEYR; 234 | ProvisioningStyle = Automatic; 235 | }; 236 | 67F4FDAE1F4B22D8006696ED = { 237 | CreatedOnToolsVersion = 8.3.3; 238 | DevelopmentTeam = L855ZMKEYR; 239 | ProvisioningStyle = Automatic; 240 | TestTargetID = 67F4FD951F4B22D8006696ED; 241 | }; 242 | 67F4FDB91F4B22D9006696ED = { 243 | CreatedOnToolsVersion = 8.3.3; 244 | DevelopmentTeam = L855ZMKEYR; 245 | ProvisioningStyle = Automatic; 246 | TestTargetID = 67F4FD951F4B22D8006696ED; 247 | }; 248 | }; 249 | }; 250 | buildConfigurationList = 67F4FD911F4B22D8006696ED /* Build configuration list for PBXProject "CKSlideMenu-OC" */; 251 | compatibilityVersion = "Xcode 3.2"; 252 | developmentRegion = English; 253 | hasScannedForEncodings = 0; 254 | knownRegions = ( 255 | en, 256 | Base, 257 | ); 258 | mainGroup = 67F4FD8D1F4B22D8006696ED; 259 | productRefGroup = 67F4FD971F4B22D8006696ED /* Products */; 260 | projectDirPath = ""; 261 | projectRoot = ""; 262 | targets = ( 263 | 67F4FD951F4B22D8006696ED /* CKSlideMenu-OC */, 264 | 67F4FDAE1F4B22D8006696ED /* CKSlideMenu-OCTests */, 265 | 67F4FDB91F4B22D9006696ED /* CKSlideMenu-OCUITests */, 266 | ); 267 | }; 268 | /* End PBXProject section */ 269 | 270 | /* Begin PBXResourcesBuildPhase section */ 271 | 67F4FD941F4B22D8006696ED /* Resources */ = { 272 | isa = PBXResourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 67F4FDA91F4B22D8006696ED /* LaunchScreen.storyboard in Resources */, 276 | 67F4FDA61F4B22D8006696ED /* Assets.xcassets in Resources */, 277 | 67F4FDA41F4B22D8006696ED /* Main.storyboard in Resources */, 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | 67F4FDAD1F4B22D8006696ED /* Resources */ = { 282 | isa = PBXResourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | 67F4FDB81F4B22D9006696ED /* Resources */ = { 289 | isa = PBXResourcesBuildPhase; 290 | buildActionMask = 2147483647; 291 | files = ( 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXResourcesBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | 67F4FD921F4B22D8006696ED /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 67F4FDD51F4B23B2006696ED /* TableViewController.m in Sources */, 303 | 67F4FDD21F4B2362006696ED /* CKSlideMenu.m in Sources */, 304 | 67FE19651F4EB6D10066D7FC /* CkViewController.m in Sources */, 305 | 67F4FD9E1F4B22D8006696ED /* AppDelegate.m in Sources */, 306 | 67F4FD9B1F4B22D8006696ED /* main.m in Sources */, 307 | 67F4FDCE1F4B2333006696ED /* CKChildViewController.m in Sources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | 67F4FDAB1F4B22D8006696ED /* Sources */ = { 312 | isa = PBXSourcesBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | 67F4FDB41F4B22D8006696ED /* CKSlideMenu_OCTests.m in Sources */, 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | }; 319 | 67F4FDB61F4B22D9006696ED /* Sources */ = { 320 | isa = PBXSourcesBuildPhase; 321 | buildActionMask = 2147483647; 322 | files = ( 323 | 67F4FDBF1F4B22D9006696ED /* CKSlideMenu_OCUITests.m in Sources */, 324 | ); 325 | runOnlyForDeploymentPostprocessing = 0; 326 | }; 327 | /* End PBXSourcesBuildPhase section */ 328 | 329 | /* Begin PBXTargetDependency section */ 330 | 67F4FDB11F4B22D8006696ED /* PBXTargetDependency */ = { 331 | isa = PBXTargetDependency; 332 | target = 67F4FD951F4B22D8006696ED /* CKSlideMenu-OC */; 333 | targetProxy = 67F4FDB01F4B22D8006696ED /* PBXContainerItemProxy */; 334 | }; 335 | 67F4FDBC1F4B22D9006696ED /* PBXTargetDependency */ = { 336 | isa = PBXTargetDependency; 337 | target = 67F4FD951F4B22D8006696ED /* CKSlideMenu-OC */; 338 | targetProxy = 67F4FDBB1F4B22D9006696ED /* PBXContainerItemProxy */; 339 | }; 340 | /* End PBXTargetDependency section */ 341 | 342 | /* Begin PBXVariantGroup section */ 343 | 67F4FDA21F4B22D8006696ED /* Main.storyboard */ = { 344 | isa = PBXVariantGroup; 345 | children = ( 346 | 67F4FDA31F4B22D8006696ED /* Base */, 347 | ); 348 | name = Main.storyboard; 349 | sourceTree = ""; 350 | }; 351 | 67F4FDA71F4B22D8006696ED /* LaunchScreen.storyboard */ = { 352 | isa = PBXVariantGroup; 353 | children = ( 354 | 67F4FDA81F4B22D8006696ED /* Base */, 355 | ); 356 | name = LaunchScreen.storyboard; 357 | sourceTree = ""; 358 | }; 359 | /* End PBXVariantGroup section */ 360 | 361 | /* Begin XCBuildConfiguration section */ 362 | 67F4FDC11F4B22D9006696ED /* Debug */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | ALWAYS_SEARCH_USER_PATHS = NO; 366 | CLANG_ANALYZER_NONNULL = YES; 367 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 368 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 369 | CLANG_CXX_LIBRARY = "libc++"; 370 | CLANG_ENABLE_MODULES = YES; 371 | CLANG_ENABLE_OBJC_ARC = YES; 372 | CLANG_WARN_BOOL_CONVERSION = YES; 373 | CLANG_WARN_CONSTANT_CONVERSION = YES; 374 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 375 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 376 | CLANG_WARN_EMPTY_BODY = YES; 377 | CLANG_WARN_ENUM_CONVERSION = YES; 378 | CLANG_WARN_INFINITE_RECURSION = YES; 379 | CLANG_WARN_INT_CONVERSION = YES; 380 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 381 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 382 | CLANG_WARN_UNREACHABLE_CODE = YES; 383 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 384 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 385 | COPY_PHASE_STRIP = NO; 386 | DEBUG_INFORMATION_FORMAT = dwarf; 387 | ENABLE_STRICT_OBJC_MSGSEND = YES; 388 | ENABLE_TESTABILITY = YES; 389 | GCC_C_LANGUAGE_STANDARD = gnu99; 390 | GCC_DYNAMIC_NO_PIC = NO; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_OPTIMIZATION_LEVEL = 0; 393 | GCC_PREPROCESSOR_DEFINITIONS = ( 394 | "DEBUG=1", 395 | "$(inherited)", 396 | ); 397 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 398 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 399 | GCC_WARN_UNDECLARED_SELECTOR = YES; 400 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 401 | GCC_WARN_UNUSED_FUNCTION = YES; 402 | GCC_WARN_UNUSED_VARIABLE = YES; 403 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 404 | MTL_ENABLE_DEBUG_INFO = YES; 405 | ONLY_ACTIVE_ARCH = YES; 406 | SDKROOT = iphoneos; 407 | }; 408 | name = Debug; 409 | }; 410 | 67F4FDC21F4B22D9006696ED /* Release */ = { 411 | isa = XCBuildConfiguration; 412 | buildSettings = { 413 | ALWAYS_SEARCH_USER_PATHS = NO; 414 | CLANG_ANALYZER_NONNULL = YES; 415 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 416 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 417 | CLANG_CXX_LIBRARY = "libc++"; 418 | CLANG_ENABLE_MODULES = YES; 419 | CLANG_ENABLE_OBJC_ARC = YES; 420 | CLANG_WARN_BOOL_CONVERSION = YES; 421 | CLANG_WARN_CONSTANT_CONVERSION = YES; 422 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 423 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 424 | CLANG_WARN_EMPTY_BODY = YES; 425 | CLANG_WARN_ENUM_CONVERSION = YES; 426 | CLANG_WARN_INFINITE_RECURSION = YES; 427 | CLANG_WARN_INT_CONVERSION = YES; 428 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 429 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 430 | CLANG_WARN_UNREACHABLE_CODE = YES; 431 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 432 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 433 | COPY_PHASE_STRIP = NO; 434 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 435 | ENABLE_NS_ASSERTIONS = NO; 436 | ENABLE_STRICT_OBJC_MSGSEND = YES; 437 | GCC_C_LANGUAGE_STANDARD = gnu99; 438 | GCC_NO_COMMON_BLOCKS = YES; 439 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 440 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 441 | GCC_WARN_UNDECLARED_SELECTOR = YES; 442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 443 | GCC_WARN_UNUSED_FUNCTION = YES; 444 | GCC_WARN_UNUSED_VARIABLE = YES; 445 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 446 | MTL_ENABLE_DEBUG_INFO = NO; 447 | SDKROOT = iphoneos; 448 | VALIDATE_PRODUCT = YES; 449 | }; 450 | name = Release; 451 | }; 452 | 67F4FDC41F4B22D9006696ED /* Debug */ = { 453 | isa = XCBuildConfiguration; 454 | buildSettings = { 455 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 456 | DEVELOPMENT_TEAM = L855ZMKEYR; 457 | INFOPLIST_FILE = "CKSlideMenu-OC/Info.plist"; 458 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 459 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 460 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OC"; 461 | PRODUCT_NAME = "$(TARGET_NAME)"; 462 | }; 463 | name = Debug; 464 | }; 465 | 67F4FDC51F4B22D9006696ED /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | DEVELOPMENT_TEAM = L855ZMKEYR; 470 | INFOPLIST_FILE = "CKSlideMenu-OC/Info.plist"; 471 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 472 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 473 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OC"; 474 | PRODUCT_NAME = "$(TARGET_NAME)"; 475 | }; 476 | name = Release; 477 | }; 478 | 67F4FDC71F4B22D9006696ED /* Debug */ = { 479 | isa = XCBuildConfiguration; 480 | buildSettings = { 481 | BUNDLE_LOADER = "$(TEST_HOST)"; 482 | DEVELOPMENT_TEAM = L855ZMKEYR; 483 | INFOPLIST_FILE = "CKSlideMenu-OCTests/Info.plist"; 484 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 485 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OCTests"; 486 | PRODUCT_NAME = "$(TARGET_NAME)"; 487 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CKSlideMenu-OC.app/CKSlideMenu-OC"; 488 | }; 489 | name = Debug; 490 | }; 491 | 67F4FDC81F4B22D9006696ED /* Release */ = { 492 | isa = XCBuildConfiguration; 493 | buildSettings = { 494 | BUNDLE_LOADER = "$(TEST_HOST)"; 495 | DEVELOPMENT_TEAM = L855ZMKEYR; 496 | INFOPLIST_FILE = "CKSlideMenu-OCTests/Info.plist"; 497 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 498 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OCTests"; 499 | PRODUCT_NAME = "$(TARGET_NAME)"; 500 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CKSlideMenu-OC.app/CKSlideMenu-OC"; 501 | }; 502 | name = Release; 503 | }; 504 | 67F4FDCA1F4B22D9006696ED /* Debug */ = { 505 | isa = XCBuildConfiguration; 506 | buildSettings = { 507 | DEVELOPMENT_TEAM = L855ZMKEYR; 508 | INFOPLIST_FILE = "CKSlideMenu-OCUITests/Info.plist"; 509 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 510 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OCUITests"; 511 | PRODUCT_NAME = "$(TARGET_NAME)"; 512 | TEST_TARGET_NAME = "CKSlideMenu-OC"; 513 | }; 514 | name = Debug; 515 | }; 516 | 67F4FDCB1F4B22D9006696ED /* Release */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | DEVELOPMENT_TEAM = L855ZMKEYR; 520 | INFOPLIST_FILE = "CKSlideMenu-OCUITests/Info.plist"; 521 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 522 | PRODUCT_BUNDLE_IDENTIFIER = "com.caidake.CKSlideMenu-OCUITests"; 523 | PRODUCT_NAME = "$(TARGET_NAME)"; 524 | TEST_TARGET_NAME = "CKSlideMenu-OC"; 525 | }; 526 | name = Release; 527 | }; 528 | /* End XCBuildConfiguration section */ 529 | 530 | /* Begin XCConfigurationList section */ 531 | 67F4FD911F4B22D8006696ED /* Build configuration list for PBXProject "CKSlideMenu-OC" */ = { 532 | isa = XCConfigurationList; 533 | buildConfigurations = ( 534 | 67F4FDC11F4B22D9006696ED /* Debug */, 535 | 67F4FDC21F4B22D9006696ED /* Release */, 536 | ); 537 | defaultConfigurationIsVisible = 0; 538 | defaultConfigurationName = Release; 539 | }; 540 | 67F4FDC31F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OC" */ = { 541 | isa = XCConfigurationList; 542 | buildConfigurations = ( 543 | 67F4FDC41F4B22D9006696ED /* Debug */, 544 | 67F4FDC51F4B22D9006696ED /* Release */, 545 | ); 546 | defaultConfigurationIsVisible = 0; 547 | defaultConfigurationName = Release; 548 | }; 549 | 67F4FDC61F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OCTests" */ = { 550 | isa = XCConfigurationList; 551 | buildConfigurations = ( 552 | 67F4FDC71F4B22D9006696ED /* Debug */, 553 | 67F4FDC81F4B22D9006696ED /* Release */, 554 | ); 555 | defaultConfigurationIsVisible = 0; 556 | defaultConfigurationName = Release; 557 | }; 558 | 67F4FDC91F4B22D9006696ED /* Build configuration list for PBXNativeTarget "CKSlideMenu-OCUITests" */ = { 559 | isa = XCConfigurationList; 560 | buildConfigurations = ( 561 | 67F4FDCA1F4B22D9006696ED /* Debug */, 562 | 67F4FDCB1F4B22D9006696ED /* Release */, 563 | ); 564 | defaultConfigurationIsVisible = 0; 565 | defaultConfigurationName = Release; 566 | }; 567 | /* End XCConfigurationList section */ 568 | }; 569 | rootObject = 67F4FD8E1F4B22D8006696ED /* Project object */; 570 | } 571 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/project.xcworkspace/xcuserdata/caike.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/90ck/CKSlideMenu/08a6f16a34a6d9005337b367a7ad2b1a790d8a2c/OC版本/CKSlideMenu-OC.xcodeproj/project.xcworkspace/xcuserdata/caike.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/xcuserdata/caike.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/xcuserdata/caike.xcuserdatad/xcschemes/CKSlideMenu-OC.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC.xcodeproj/xcuserdata/caike.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | CKSlideMenu-OC.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 67F4FD951F4B22D8006696ED 16 | 17 | primary 18 | 19 | 20 | 67F4FDAE1F4B22D8006696ED 21 | 22 | primary 23 | 24 | 25 | 67F4FDB91F4B22D9006696ED 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/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 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/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 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/CKChildViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKChildViewController.h 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKChildViewController : UIViewController 12 | 13 | /** */ 14 | @property (nonatomic,assign)NSInteger type; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/CKChildViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKChildViewController.m 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import "CKChildViewController.h" 10 | #import "CKSlideMenu.h" 11 | #import "CkViewController.h" 12 | @interface CKChildViewController () 13 | 14 | @end 15 | 16 | @implementation CKChildViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | self.view.backgroundColor = [UIColor whiteColor]; 21 | self.automaticallyAdjustsScrollViewInsets = NO; 22 | 23 | if (self.type == 0) { 24 | NSArray *titles = @[@"今日",@"阿萨德",@"爱迪生",@"暗示",@"说的",@"粉丝",@"阿萨德",@"爱迪生",@"暗示",@"说的"]; 25 | NSMutableArray *arr = [NSMutableArray array]; 26 | for (int i = 0; i 10 | 11 | @interface CkViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/CkViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CkViewController.m 3 | // CKSlideMenuDemo 4 | // 5 | // Created by ck on 2017/6/8. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import "CkViewController.h" 10 | 11 | @interface CkViewController () 12 | 13 | @end 14 | 15 | @implementation CkViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | 21 | // self.view.backgroundColor = [UIColor cyanColor]; 22 | self.view.backgroundColor = [UIColor colorWithRed:(arc4random()%255 / 255.0) green:(arc4random()%255 / 255.0) blue:(arc4random()%255 / 255.0) alpha:1]; 23 | 24 | } 25 | 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | /* 33 | #pragma mark - Navigation 34 | 35 | // In a storyboard-based application, you will often want to do a little preparation before navigation 36 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 37 | // Get the new view controller using [segue destinationViewController]. 38 | // Pass the selected object to the new view controller. 39 | } 40 | */ 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/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 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/SlideMenu/CKSlideMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // CKSlideMenu.h 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger,SlideMenuTitleStyle){ 12 | SlideMenuTitleStyleNormal, //默认 无效果 13 | SlideMenuTitleStyleGradient, //颜色渐变 14 | SlideMenuTitleStyleTransfrom, //放大 15 | SlideMenuTitleStyleAll //颜色渐变+放大 16 | }; 17 | 18 | typedef NS_ENUM(NSInteger,SlideMenuIndicatorStyle){ 19 | SlideMenuIndicatorStyleNormal, //默认 20 | SlideMenuIndicatorStyleFollowText, //跟随文本长度 21 | SlideMenuIndicatorStyleStretch //伸缩 22 | }; 23 | 24 | 25 | @interface CKSlideMenu : UIView 26 | 27 | /** title风格 */ 28 | @property (nonatomic,assign)SlideMenuTitleStyle titleStyle; 29 | 30 | /** indicator风格 */ 31 | @property (nonatomic,assign)SlideMenuIndicatorStyle indicatorStyle; 32 | /** 菜单是否固定 默认不固定*/ 33 | @property (nonatomic,assign)BOOL isFixed; 34 | 35 | /** 是否懒加载自控制器 */ 36 | @property (nonatomic,assign)BOOL lazyLoad; 37 | 38 | /** 选中颜色 */ 39 | @property (nonatomic,strong)UIColor *selectedColor; 40 | 41 | /** 未选中颜色 */ 42 | @property (nonatomic,strong)UIColor *unselectedColor; 43 | 44 | /** 菜单字体 */ 45 | @property (nonatomic,strong)UIFont *font; 46 | 47 | /** 下标宽度 */ 48 | @property (nonatomic,assign)CGFloat indicatorWidth; 49 | 50 | /** 下标高度 */ 51 | @property (nonatomic,assign)CGFloat indicatorHeight; 52 | 53 | /** 下标颜色 默认为选中颜色*/ 54 | @property (nonatomic,strong)UIColor *indicatorColor; 55 | 56 | /** 下标距离底部偏移量 */ 57 | @property (nonatomic,assign)CGFloat indicatorOffsety; 58 | 59 | /** 下标伸缩动画的偏移量 SlideMenuIndicatorStyleStretch生效 */ 60 | @property (nonatomic,assign)CGFloat indicatorAnimatePadding; 61 | 62 | /** bodyScrollView的父视图 默认为SlideMenu的父视图*/ 63 | @property (nonatomic,weak)UIView *bodySuperView; 64 | 65 | /** bodyScrollView的frame */ 66 | @property (nonatomic,assign)CGRect bodyFrame; 67 | 68 | /** 是否显示分割线 */ 69 | @property (nonatomic,assign)BOOL showLine; 70 | 71 | /** 是否显示下标 默认显示*/ 72 | @property (nonatomic,assign)BOOL showIndicator; 73 | 74 | - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles controllers:(NSArray *)controllers; 75 | 76 | 77 | /** 78 | 刷新数据 79 | 80 | @param titles 标题数组 81 | @param controllers 控制器数组 82 | @param index 显示位置 83 | */ 84 | - (void)reloadTitles:(NSArray *)titles controllers:(NSArray *)controllers atIndex:(NSInteger)index; 85 | 86 | /** 87 | 滚动到对应位置 88 | 89 | @param toIndex 需要显示的位置 90 | */ 91 | - (void)scrollToIndex:(NSInteger)toIndex; 92 | 93 | @end 94 | 95 | 96 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/SlideMenu/CKSlideMenu.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKSlideMenu.m 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import "CKSlideMenu.h" 10 | #import 11 | 12 | // 在运行时关联的关键方法 13 | static NSString *textWidth_Key; 14 | static NSString *textMinX_Key; 15 | static NSString *textMaxX_Key; 16 | 17 | @interface UIButton (textWith) 18 | /** text长度 */ 19 | @property (nonatomic,assign)CGFloat textWidth; 20 | 21 | /** text的MinX */ 22 | @property (nonatomic,assign,readonly)CGFloat textMinX; 23 | 24 | /** text的MaxX */ 25 | @property (nonatomic,assign,readonly)CGFloat textMaxX; 26 | @end 27 | 28 | @interface CKSlideMenu () 29 | { 30 | 31 | NSInteger _leftIndex; /** 左边索引 */ 32 | 33 | NSInteger _rightIndex; /** 右边索引 */ 34 | } 35 | /** 子控制器数组 */ 36 | @property (nonatomic,strong)NSArray *controllers; 37 | 38 | /** title数组 */ 39 | @property (nonatomic,strong)NSArray *titleArr; 40 | 41 | /** item数组 */ 42 | @property (nonatomic,strong)NSMutableArray *itemArr; 43 | 44 | /** 底部分割线 */ 45 | @property (nonatomic,strong)UIView *sepertateView; 46 | 47 | /** 菜单滚动视图 */ 48 | @property (nonatomic,strong)UIScrollView *tabScrollView; 49 | 50 | /** body滚动视图 */ 51 | @property (nonatomic,strong)UIScrollView *bodyScrollView; 52 | 53 | /** 下标视图 */ 54 | @property (nonatomic,strong)UIView *indicatorView; 55 | 56 | /** 选中索引 */ 57 | @property (nonatomic,assign)NSInteger currentIndex; 58 | 59 | /** item文字边距 */ 60 | @property (nonatomic,assign)CGFloat itemPadding; 61 | 62 | @end 63 | 64 | @implementation CKSlideMenu 65 | 66 | - (instancetype)initWithFrame:(CGRect)frame titles:(NSArray *)titles controllers:(NSArray *)controllers; 67 | { 68 | if (self = [super initWithFrame:frame]) { 69 | _controllers = controllers; 70 | _titleArr = titles; 71 | [self initSetting]; 72 | [self addSubview:self.tabScrollView]; 73 | [self.tabScrollView addSubview:self.indicatorView]; 74 | [self addSubview:self.sepertateView]; 75 | } 76 | return self; 77 | } 78 | 79 | - (void)reloadTitles:(NSArray *)titles controllers:(NSArray *)controllers atIndex:(NSInteger)index 80 | { 81 | _titleArr = titles; 82 | _controllers = controllers; 83 | _currentIndex = index; 84 | [self setNeedsLayout]; 85 | } 86 | 87 | //初始化参数 88 | - (void)initSetting 89 | { 90 | _selectedColor = [UIColor redColor]; 91 | _unselectedColor = [UIColor blackColor]; 92 | _indicatorColor = _selectedColor; 93 | _indicatorWidth = 20; 94 | _indicatorHeight = 2; 95 | _indicatorOffsety = 0; 96 | _itemPadding = 15; 97 | _indicatorAnimatePadding = 8; 98 | _titleStyle = SlideMenuTitleStyleNormal; 99 | _indicatorStyle = SlideMenuIndicatorStyleNormal; 100 | _isFixed = NO; 101 | _itemArr = [NSMutableArray array]; 102 | _font = [UIFont systemFontOfSize:14]; 103 | } 104 | 105 | //布局 106 | - (void)layoutSubviews 107 | { 108 | [super layoutSubviews]; 109 | 110 | self.tabScrollView.frame = self.bounds; 111 | self.sepertateView.frame = CGRectMake(0, self.frame.size.height - 0.5, self.frame.size.width, 0.5); 112 | 113 | [self setupTabContents]; 114 | 115 | [self setupBodyScrollView]; 116 | 117 | [self loadBodyContentAtIndex:_currentIndex]; 118 | 119 | [self resetTabScrollViewFrame]; 120 | 121 | _bodyScrollView.contentSize = CGSizeMake(_bodyScrollView.frame.size.width*_controllers.count, _bodyScrollView.frame.size.height); 122 | [_bodyScrollView setContentOffset:CGPointMake(_bodyScrollView.frame.size.width*_currentIndex, 0) animated:NO]; 123 | 124 | [self setupIndicatorView]; 125 | } 126 | 127 | 128 | /** 129 | 配置indicator的UI 130 | */ 131 | - (void)setupIndicatorView 132 | { 133 | UIButton *currentItem = _itemArr[_currentIndex]; 134 | CGRect frame = currentItem.frame; 135 | frame.origin.y = self.frame.size.height - _indicatorOffsety - _indicatorHeight; 136 | frame.size.height = _indicatorHeight; 137 | 138 | if (_indicatorStyle == SlideMenuIndicatorStyleNormal) { 139 | frame.origin.x = CGRectGetMidX(frame) - _indicatorWidth/2; 140 | frame.size.width = _indicatorWidth; 141 | } 142 | else{ 143 | frame.origin.x = currentItem.textMinX; 144 | frame.size.width = currentItem.textWidth; 145 | } 146 | self.indicatorView.frame = frame; 147 | } 148 | 149 | /** 150 | 配置menu 151 | */ 152 | - (void)setupTabContents 153 | { 154 | for (UIButton *item in self.itemArr) { 155 | [item removeFromSuperview]; 156 | } 157 | [self.itemArr removeAllObjects]; 158 | 159 | 160 | CGFloat originX = 0; 161 | CGFloat totalTextLength = 0; 162 | for (int i = 0; i < self.titleArr.count; i++) { 163 | UIButton *item = [UIButton new]; 164 | [item setTitleColor:_selectedColor forState:UIControlStateSelected]; 165 | [item setTitleColor:_unselectedColor forState:UIControlStateNormal]; 166 | item.titleLabel.textColor = _unselectedColor; 167 | item.reversesTitleShadowWhenHighlighted = YES; 168 | item.titleLabel.font = _font; 169 | [item setTitle:_titleArr[i] forState:UIControlStateNormal]; 170 | [item addTarget:self action:@selector(itemClicked:) forControlEvents:UIControlEventTouchUpInside]; 171 | 172 | CGSize size = [_titleArr[i] sizeWithAttributes:@{NSFontAttributeName:_font}]; 173 | item.frame = CGRectMake(originX, 0, size.width+_itemPadding*2, self.frame.size.height); 174 | item.textWidth = size.width; 175 | originX = CGRectGetMaxX(item.frame); 176 | [self.itemArr addObject:item]; 177 | [self.tabScrollView addSubview:item]; 178 | item.selected = i == _currentIndex; 179 | totalTextLength += size.width; 180 | } 181 | 182 | //固定型修正 183 | if (_isFixed) { 184 | if (totalTextLength > self.frame.size.width) { 185 | CGFloat width = self.frame.size.width / _titleArr.count; 186 | for (UIButton *item in _itemArr) { 187 | NSInteger index = [_itemArr indexOfObject:item]; 188 | item.frame = CGRectMake(width*index, 0, width, item.frame.size.height); 189 | item.textWidth = width; 190 | } 191 | } 192 | else { 193 | //未超过,按照文本长度计算padding 194 | CGFloat itemPadding = (self.frame.size.width - totalTextLength)/(_titleArr.count*2); 195 | originX = 0; 196 | for (UIButton *item in _itemArr) { 197 | // NSInteger index = [_itemArr indexOfObject:item]; 198 | item.frame = CGRectMake(originX, 0, item.textWidth+2*itemPadding, item.frame.size.height); 199 | originX = CGRectGetMaxX(item.frame); 200 | } 201 | } 202 | } 203 | if (_titleStyle == SlideMenuTitleStyleTransfrom || _titleStyle == SlideMenuTitleStyleAll) { 204 | [self transfromItem:_itemArr[_currentIndex] percent:1]; 205 | } 206 | _tabScrollView.contentSize = CGSizeMake(originX, self.frame.size.height); 207 | } 208 | 209 | /** 210 | 添加bodyScorllView视图 211 | */ 212 | - (void)setupBodyScrollView 213 | { 214 | if (self.bodySuperView == nil) { 215 | [self.superview addSubview:self.bodyScrollView]; 216 | } 217 | else{ 218 | [self.bodySuperView addSubview:self.bodyScrollView]; 219 | } 220 | } 221 | 222 | //加载子控制器 223 | - (void)loadBodyContentAtIndex:(NSInteger)index 224 | { 225 | if (_lazyLoad) { 226 | UIViewController *vc = _controllers[index]; 227 | if (!vc.viewLoaded) { 228 | vc.view.frame = _bodyScrollView.bounds; 229 | vc.view.center = CGPointMake(CGRectGetWidth(_bodyScrollView.frame)*(index+0.5), _bodyScrollView.frame.size.height/2); 230 | [_bodyScrollView addSubview:vc.view]; 231 | } 232 | } 233 | else{ 234 | for (int i = 0; i < _controllers.count; i++) { 235 | UIViewController *vc = _controllers[i]; 236 | vc.view.frame = _bodyScrollView.bounds; 237 | vc.view.center = CGPointMake(CGRectGetWidth(_bodyScrollView.frame)*(i+0.5), _bodyScrollView.frame.size.height/2); 238 | [_bodyScrollView addSubview:vc.view]; 239 | } 240 | } 241 | } 242 | 243 | #pragma mark setter 244 | - (void)setBodyFrame:(CGRect)bodyFrame 245 | { 246 | self.bodyScrollView.frame = bodyFrame; 247 | self.bodyScrollView.contentSize = CGSizeMake(bodyFrame.size.width*self.controllers.count, bodyFrame.size.height); 248 | } 249 | 250 | - (void)setIndicatorWidth:(CGFloat)indicatorWidth 251 | { 252 | _indicatorWidth = indicatorWidth; 253 | [self setNeedsLayout]; 254 | } 255 | 256 | - (void)setIndicatorHeight:(CGFloat)indicatorHeight 257 | { 258 | _indicatorHeight = indicatorHeight; 259 | [self setNeedsLayout]; 260 | } 261 | 262 | - (void)setSelectedColor:(UIColor *)selectedColor 263 | { 264 | _selectedColor = selectedColor; 265 | [self setNeedsLayout]; 266 | } 267 | 268 | - (void)setUnselectedColor:(UIColor *)unselectedColor 269 | { 270 | _unselectedColor = unselectedColor; 271 | [self setNeedsLayout]; 272 | } 273 | 274 | - (void)setIndicatorOffsety:(CGFloat)indicatorOffsety 275 | { 276 | _indicatorOffsety = indicatorOffsety; 277 | [self setNeedsLayout]; 278 | } 279 | 280 | - (void)setFont:(UIFont *)font 281 | { 282 | _font = font; 283 | [self setNeedsLayout]; 284 | } 285 | 286 | - (void)setTitleStyle:(SlideMenuTitleStyle)titleStyle 287 | { 288 | _titleStyle = titleStyle; 289 | [self setNeedsLayout]; 290 | } 291 | 292 | - (void)setIndicatorStyle:(SlideMenuIndicatorStyle)indicatorStyle 293 | { 294 | _indicatorStyle = indicatorStyle; 295 | [self setNeedsLayout]; 296 | } 297 | 298 | -(void)setShowLine:(BOOL)showLine 299 | { 300 | self.sepertateView.hidden = !showLine; 301 | } 302 | 303 | - (void)setShowIndicator:(BOOL)showIndicator 304 | { 305 | _showIndicator = showIndicator; 306 | self.indicatorView.hidden = !showIndicator; 307 | if (showIndicator) { 308 | [self setupIndicatorView]; 309 | } 310 | } 311 | 312 | - (void)setIndicatorColor:(UIColor *)indicatorColor 313 | { 314 | _indicatorColor = indicatorColor; 315 | self.indicatorView.backgroundColor = indicatorColor; 316 | } 317 | 318 | #pragma mark Private 319 | - (void)itemClicked:(UIButton *)button 320 | { 321 | if (button.selected) { 322 | return; 323 | } 324 | [self scrollToIndex:[_itemArr indexOfObject:button]]; 325 | } 326 | 327 | - (void)scrollToIndex:(NSInteger)toIndex 328 | { 329 | 330 | if (_itemArr.count <= toIndex) { 331 | _currentIndex = toIndex; 332 | return; 333 | } 334 | 335 | UIButton *fromItem = _itemArr[_currentIndex]; 336 | UIButton *toItem = _itemArr[toIndex]; 337 | 338 | _currentIndex = toIndex; 339 | 340 | //title样式 341 | if (_titleStyle == SlideMenuTitleStyleTransfrom || _titleStyle == SlideMenuTitleStyleAll) { 342 | [UIView animateWithDuration:0.25 animations:^{ 343 | [self transfromItem:fromItem percent:0]; 344 | [self transfromItem:toItem percent:1]; 345 | }]; 346 | } 347 | else{ 348 | fromItem.selected = NO; 349 | toItem.selected = YES; 350 | } 351 | 352 | void (^completeAction)() = ^(){ 353 | [_bodyScrollView setContentOffset:CGPointMake(_bodyScrollView.frame.size.width*toIndex, 0) animated:NO]; 354 | [self resetTabScrollViewFrame]; 355 | }; 356 | 357 | if (self.indicatorView.hidden) { 358 | completeAction(); 359 | return; 360 | } 361 | //更新indicator样式 362 | switch (_indicatorStyle) { 363 | case SlideMenuIndicatorStyleNormal: 364 | { 365 | [UIView animateWithDuration:0.25 animations:^{ 366 | self.indicatorView.center = CGPointMake(toItem.center.x, self.indicatorView.center.y); 367 | } completion:^(BOOL finished) { 368 | completeAction(); 369 | }]; 370 | } 371 | break; 372 | case SlideMenuIndicatorStyleFollowText: 373 | { 374 | CGRect bounds = self.indicatorView.bounds; 375 | bounds.size.width = toItem.textWidth; 376 | [UIView animateWithDuration:0.25 animations:^{ 377 | self.indicatorView.bounds = bounds; 378 | self.indicatorView.center = CGPointMake(toItem.center.x, self.indicatorView.center.y); 379 | } completion:^(BOOL finished) { 380 | completeAction(); 381 | }]; 382 | } 383 | break; 384 | case SlideMenuIndicatorStyleStretch: 385 | { 386 | CGRect frame = self.indicatorView.frame; 387 | frame.size.width = toItem.textWidth; 388 | CGRect finnalFrame = frame; 389 | 390 | CGFloat max = fromItem.textWidth + toItem.textWidth + 2*_itemPadding; 391 | frame.size.width = max - _indicatorAnimatePadding*2; 392 | 393 | CGFloat x = (CGRectGetMaxX(toItem.frame) - CGRectGetMinX(fromItem.frame))/2 + CGRectGetMinX(fromItem.frame) + _itemPadding; 394 | 395 | [UIView animateKeyframesWithDuration:0.25 delay:0 options:UIViewKeyframeAnimationOptionCalculationModePaced animations:^{ 396 | 397 | [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.125 animations:^{ 398 | self.indicatorView.frame = frame; 399 | self.indicatorView.center = CGPointMake(x, self.indicatorView.center.y); 400 | }]; 401 | 402 | [UIView addKeyframeWithRelativeStartTime:0.125 relativeDuration:0.125 animations:^{ 403 | self.indicatorView.frame = finnalFrame; 404 | self.indicatorView.center = CGPointMake(toItem.center.x, self.indicatorView.center.y); 405 | }]; 406 | 407 | 408 | } completion:^(BOOL finished) { 409 | completeAction(); 410 | }]; 411 | } 412 | break; 413 | 414 | default: 415 | break; 416 | } 417 | } 418 | 419 | - (void)updateIndicatorStyle:(CGFloat)relativeLocation 420 | { 421 | if (self.indicatorView.hidden) { 422 | return; 423 | } 424 | UIButton *leftItem = self.itemArr[_leftIndex]; 425 | UIButton *rightItem = self.itemArr[_rightIndex]; 426 | switch (_indicatorStyle) { 427 | case SlideMenuIndicatorStyleNormal: 428 | { 429 | //常规模式 只需更新中心点即可 430 | CGFloat max = rightItem.center.x - leftItem.center.x; 431 | self.indicatorView.center = CGPointMake(leftItem.center.x + max*relativeLocation, self.indicatorView.center.y); 432 | } 433 | break; 434 | case SlideMenuIndicatorStyleFollowText: 435 | { 436 | CGRect frame = self.indicatorView.frame; 437 | CGFloat maxWidth = rightItem.textWidth - leftItem.textWidth; 438 | frame.size.width = leftItem.textWidth + maxWidth*relativeLocation; 439 | self.indicatorView.frame = frame; 440 | 441 | CGFloat max = rightItem.center.x - leftItem.center.x; 442 | self.indicatorView.center = CGPointMake(leftItem.center.x + max*relativeLocation, self.indicatorView.center.y); 443 | } 444 | break; 445 | case SlideMenuIndicatorStyleStretch: 446 | { 447 | //仔细观察位移效果,分析出如下计算公式 448 | CGRect frame = self.indicatorView.frame; 449 | 450 | CGFloat maxWidth = rightItem.textMaxX - leftItem.textMinX - _indicatorAnimatePadding*2; 451 | if (relativeLocation <= 0.5) { 452 | frame.size.width = leftItem.textWidth + (maxWidth - leftItem.textWidth)*(relativeLocation/0.5); 453 | frame.origin.x = leftItem.textMinX + _indicatorAnimatePadding*(relativeLocation/0.5); 454 | } 455 | else{ 456 | frame.size.width = rightItem.textWidth + (maxWidth - rightItem.textWidth)*((1-relativeLocation)/0.5); 457 | frame.origin.x = rightItem.textMaxX - frame.size.width - _indicatorAnimatePadding*((1-relativeLocation)/0.5); 458 | } 459 | self.indicatorView.frame = frame; 460 | } 461 | break; 462 | 463 | default: 464 | break; 465 | } 466 | } 467 | 468 | - (void)updateTitleStyle:(CGFloat)relativeLocation 469 | { 470 | UIButton *leftItem = self.itemArr[_leftIndex]; 471 | UIButton *rightItem = self.itemArr[_rightIndex]; 472 | 473 | switch (_titleStyle) { 474 | case SlideMenuTitleStyleNormal: 475 | { 476 | leftItem.selected = relativeLocation <= 0.5; 477 | rightItem.selected = !leftItem.selected; 478 | } 479 | break; 480 | case SlideMenuTitleStyleGradient: 481 | { 482 | leftItem.selected = relativeLocation <= 0.5; 483 | rightItem.selected = !leftItem.selected; 484 | 485 | CGFloat percent = relativeLocation <= 0.5 ? (1-relativeLocation) : relativeLocation; 486 | [leftItem setTitleColor:[self averageColorFrom:_unselectedColor to:_selectedColor percent:percent] forState:UIControlStateSelected]; 487 | [leftItem setTitleColor:[self averageColorFrom:_selectedColor to:_unselectedColor percent:percent] forState:UIControlStateNormal]; 488 | 489 | [rightItem setTitleColor:[self averageColorFrom:_unselectedColor to:_selectedColor percent:percent] forState:UIControlStateSelected]; 490 | [rightItem setTitleColor:[self averageColorFrom:_selectedColor to:_unselectedColor percent:percent] forState:UIControlStateNormal]; 491 | } 492 | break; 493 | case SlideMenuTitleStyleTransfrom: 494 | { 495 | 496 | [self transfromItem:leftItem percent:1-relativeLocation]; 497 | [self transfromItem:rightItem percent:relativeLocation]; 498 | } 499 | break; 500 | case SlideMenuTitleStyleAll: 501 | { 502 | CGFloat percent = relativeLocation <= 0.5 ? (1-relativeLocation) : relativeLocation; 503 | [leftItem setTitleColor:[self averageColorFrom:_unselectedColor to:_selectedColor percent:percent] forState:UIControlStateSelected]; 504 | [leftItem setTitleColor:[self averageColorFrom:_selectedColor to:_unselectedColor percent:percent] forState:UIControlStateNormal]; 505 | 506 | [rightItem setTitleColor:[self averageColorFrom:_unselectedColor to:_selectedColor percent:percent] forState:UIControlStateSelected]; 507 | [rightItem setTitleColor:[self averageColorFrom:_selectedColor to:_unselectedColor percent:percent] forState:UIControlStateNormal]; 508 | [self transfromItem:leftItem percent:1-relativeLocation]; 509 | [self transfromItem:rightItem percent:relativeLocation]; 510 | } 511 | break; 512 | default: 513 | break; 514 | } 515 | } 516 | 517 | - (void)transfromItem:(UIButton *)item percent:(CGFloat)percent 518 | { 519 | item.selected = percent >= 0.5 ; 520 | item.transform = CGAffineTransformMakeScale(1+0.1*percent, 1+0.1*percent); 521 | } 522 | 523 | /** 524 | * 修正tabScrollView的位置 525 | */ 526 | - (void)resetTabScrollViewFrame 527 | { 528 | if (self.isFixed) { 529 | return; 530 | } 531 | UIButton *selectedItem = self.itemArr[_currentIndex]; 532 | CGFloat tab_width = self.tabScrollView.frame.size.width; 533 | CGFloat reviseX; 534 | if (selectedItem.center.x + tab_width/2 >= self.tabScrollView.contentSize.width) { 535 | reviseX = self.tabScrollView.contentSize.width - tab_width; 536 | } 537 | else if (selectedItem.center.x - tab_width/2 <= 0) { 538 | reviseX = 0; 539 | } 540 | else{ 541 | reviseX = selectedItem.center.x - tab_width/2; 542 | } 543 | 544 | [self.tabScrollView setContentOffset:CGPointMake(reviseX, 0) animated:YES]; 545 | } 546 | 547 | 548 | #pragma mark Delegate 549 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 550 | { 551 | if (scrollView == self.bodyScrollView) { 552 | CGFloat offsetX = scrollView.contentOffset.x; 553 | 554 | if (_lazyLoad) { 555 | _currentIndex = lroundf(offsetX / scrollView.frame.size.width); 556 | NSInteger index = _currentIndex; 557 | if (offsetX > scrollView.frame.size.width*_currentIndex) { 558 | index = (_currentIndex + 1) >= _itemArr.count ? _currentIndex : _currentIndex + 1; 559 | } 560 | else if (offsetX < scrollView.frame.size.width * _currentIndex) { 561 | index = (_currentIndex - 1) < 0 ? 0 : _currentIndex - 1; 562 | } 563 | [self loadBodyContentAtIndex:index]; 564 | } 565 | 566 | if (offsetX <= 0) { //左边界 567 | _leftIndex = 0; 568 | _rightIndex = _leftIndex; 569 | } 570 | else if (offsetX >= scrollView.contentSize.width - scrollView.frame.size.width) { //右边界 571 | _leftIndex = self.itemArr.count - 1; 572 | _rightIndex = _leftIndex; 573 | } 574 | else{ 575 | _leftIndex = (NSInteger)(offsetX/scrollView.frame.size.width); 576 | _rightIndex = _leftIndex + 1; 577 | } 578 | 579 | CGFloat relativeLocation = (offsetX/scrollView.frame.size.width - _leftIndex); 580 | if (relativeLocation == 0) { 581 | return; 582 | } 583 | [self updateIndicatorStyle:relativeLocation]; 584 | [self updateTitleStyle:relativeLocation]; 585 | } 586 | } 587 | 588 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 589 | { 590 | if (scrollView == self.bodyScrollView) { 591 | _currentIndex = scrollView.contentOffset.x / scrollView.frame.size.width; 592 | [self resetTabScrollViewFrame]; 593 | } 594 | } 595 | 596 | 597 | 598 | #pragma mark - 懒加载 UI 599 | - (UIScrollView *)tabScrollView 600 | { 601 | if (!_tabScrollView) { 602 | _tabScrollView = [[UIScrollView alloc]initWithFrame:self.bounds]; 603 | _tabScrollView.showsVerticalScrollIndicator = NO; 604 | _tabScrollView.showsHorizontalScrollIndicator = NO; 605 | _tabScrollView.backgroundColor = [UIColor clearColor]; 606 | } 607 | return _tabScrollView; 608 | } 609 | 610 | - (UIView *)indicatorView 611 | { 612 | if (!_indicatorView) { 613 | _indicatorView = [UIView new]; 614 | _indicatorView.backgroundColor = self.indicatorColor; 615 | } 616 | return _indicatorView; 617 | } 618 | 619 | - (UIView *)sepertateView 620 | { 621 | if (_sepertateView == nil) { 622 | _sepertateView = [[UIView alloc]init]; 623 | _sepertateView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1]; 624 | } 625 | return _sepertateView; 626 | } 627 | 628 | - (UIScrollView *)bodyScrollView 629 | { 630 | if (_bodyScrollView == nil) { 631 | _bodyScrollView = [[UIScrollView alloc]initWithFrame:CGRectZero]; 632 | _bodyScrollView.showsVerticalScrollIndicator = NO; 633 | _bodyScrollView.showsHorizontalScrollIndicator = NO; 634 | _bodyScrollView.bounces = NO; 635 | _bodyScrollView.delegate = self; 636 | _bodyScrollView.pagingEnabled = YES; 637 | } 638 | return _bodyScrollView; 639 | } 640 | 641 | 642 | #pragma mark other 643 | 644 | //渐变颜色 645 | - (UIColor *)averageColorFrom:(UIColor *)fromColor to:(UIColor *)toColor percent:(CGFloat)percent 646 | { 647 | CGFloat fromRed = 0; 648 | CGFloat fromGreen = 0; 649 | CGFloat fromBlue = 0; 650 | CGFloat fromeAlpha = 0; 651 | [fromColor getRed:&fromRed green:&fromGreen blue:&fromBlue alpha:&fromeAlpha]; 652 | 653 | CGFloat toRed = 0; 654 | CGFloat toGreen = 0; 655 | CGFloat toBlue = 0; 656 | CGFloat toAlpha = 0; 657 | [toColor getRed:&toRed green:&toGreen blue:&toBlue alpha:&toAlpha]; 658 | 659 | CGFloat nowRed = fromRed + (toRed - fromRed)*percent; 660 | CGFloat nowGreen = fromGreen + (toGreen - fromGreen)*percent; 661 | CGFloat nowBlue = fromBlue + (toBlue - fromBlue)*percent; 662 | CGFloat nowAlpha = fromeAlpha + (toAlpha - fromeAlpha)*percent; 663 | return [UIColor colorWithRed:nowRed green:nowGreen blue:nowBlue alpha:nowAlpha]; 664 | } 665 | 666 | 667 | @end 668 | 669 | 670 | 671 | #pragma mark Buttton 分类 672 | @implementation UIButton (textWith) 673 | 674 | - (void)setTextWidth:(CGFloat)textWidth 675 | { 676 | objc_setAssociatedObject(self, &textWidth_Key, @(textWidth), OBJC_ASSOCIATION_RETAIN); 677 | } 678 | 679 | - (CGFloat)textWidth 680 | { 681 | id obj = objc_getAssociatedObject(self, &textWidth_Key); 682 | if (obj != nil && [obj isKindOfClass:[NSNumber class]]) { 683 | return [(NSNumber*)obj floatValue]; 684 | } 685 | return 0; 686 | } 687 | 688 | 689 | - (CGFloat)textMinX 690 | { 691 | return (self.frame.size.width - self.textWidth)/2 + self.frame.origin.x; 692 | } 693 | 694 | - (CGFloat)textMaxX 695 | { 696 | return CGRectGetMaxX(self.frame) - (self.frame.size.width - self.textWidth)/2; 697 | } 698 | 699 | @end 700 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/TableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.h 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/TableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableViewController.m 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import "TableViewController.h" 10 | #import "CKChildViewController.h" 11 | 12 | @interface TableViewController () 13 | 14 | /** 数据源 */ 15 | @property (nonatomic,strong) NSArray *dataArr; 16 | 17 | @end 18 | 19 | @implementation TableViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.dataArr = @[@"example1",@"example2",@"example3",@"example4"]; 25 | 26 | self.title = @"Demo"; 27 | // Uncomment the following line to preserve selection between presentations. 28 | // self.clearsSelectionOnViewWillAppear = NO; 29 | 30 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 31 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 32 | } 33 | 34 | - (void)didReceiveMemoryWarning { 35 | [super didReceiveMemoryWarning]; 36 | // Dispose of any resources that can be recreated. 37 | } 38 | 39 | #pragma mark - Table view data source 40 | 41 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 42 | 43 | return 1; 44 | } 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 | 48 | return 4; 49 | } 50 | 51 | 52 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 53 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath]; 54 | cell.textLabel.text = self.dataArr[indexPath.row]; 55 | // if (cell == nil) { 56 | // cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"]; 57 | // } 58 | // Configure the cell... 59 | 60 | return cell; 61 | } 62 | 63 | 64 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 65 | { 66 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 67 | CKChildViewController *vc = [[CKChildViewController alloc]init]; 68 | vc.type = indexPath.row; 69 | [self.navigationController pushViewController:vc animated:YES]; 70 | } 71 | 72 | 73 | /* 74 | // Override to support conditional editing of the table view. 75 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 76 | // Return NO if you do not want the specified item to be editable. 77 | return YES; 78 | } 79 | */ 80 | 81 | /* 82 | // Override to support editing the table view. 83 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 84 | if (editingStyle == UITableViewCellEditingStyleDelete) { 85 | // Delete the row from the data source 86 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 87 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 88 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 89 | } 90 | } 91 | */ 92 | 93 | /* 94 | // Override to support rearranging the table view. 95 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { 96 | } 97 | */ 98 | 99 | /* 100 | // Override to support conditional rearranging of the table view. 101 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 102 | // Return NO if you do not want the item to be re-orderable. 103 | return YES; 104 | } 105 | */ 106 | 107 | /* 108 | #pragma mark - Navigation 109 | 110 | // In a storyboard-based application, you will often want to do a little preparation before navigation 111 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 112 | // Get the new view controller using [segue destinationViewController]. 113 | // Pass the selected object to the new view controller. 114 | } 115 | */ 116 | 117 | @end 118 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OC/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CKSlideMenu-OC 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OCTests/CKSlideMenu_OCTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKSlideMenu_OCTests.m 3 | // CKSlideMenu-OCTests 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKSlideMenu_OCTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation CKSlideMenu_OCTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OCTests/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 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OCUITests/CKSlideMenu_OCUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // CKSlideMenu_OCUITests.m 3 | // CKSlideMenu-OCUITests 4 | // 5 | // Created by ck on 2017/8/21. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CKSlideMenu_OCUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation CKSlideMenu_OCUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // 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. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /OC版本/CKSlideMenu-OCUITests/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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ##### CKSlideMenu 介绍 4 | 5 | ------ 6 | 7 | > 2017.8.21 8 | > 9 | > 最近把这个滚动导航做了一次优化,想做到更多的使用场景。 10 | > 11 | > 添加了固定模式、下标及title细节的自定义。 12 | > 13 | > 具体使用见下文或者demo 14 | 15 | ​ **支持cocoapod** : `pod 'CKSlideMenu'` 16 | 17 | ​ 闲来无事,看到半塘的滚动菜单的动画还是蛮有意思的。所以写了这个一个东西,效果如下(效果图可能没有更新,可以具体看demo): 18 | 19 | 20 | 21 | ![SlideMneu01](./SlideMneu01.gif) ![SlideMenu03](./SlideMenu02.gif) 22 | 23 | 24 | 25 | 26 | > ~~当数组元素个数较少时,会固定顶部的滚动视图,重新布局位置~~ 27 | 28 | 改为用户控制是否固定顶部的滚动视图,这样似乎更加人性化。 29 | 30 | ```swift 31 | /// 是否是固定型菜单(不需要修正滚动) 32 | var isFixed:Bool = false 33 | ``` 34 | 35 | ![SlideMenu02](./SlideMenu03.gif) 36 | 37 | 38 | ###### 1.主要属性 39 | 40 | ```swift 41 | //MARK: - 成员变量 42 | /// 是否是固定型菜单(不需要修正滚动) 43 | var isFixed:Bool = false 44 | 45 | /// 是否懒加载子控制器 (有些用户想要滚动到对应视图才执行加载动作,所以添加了这个属性) 46 | var lazyLoad:Bool = true 47 | 48 | /// 选中颜色 (在不设置下标颜色的时候,会此为下标的颜色) 49 | var selectedColor:UIColor = UIColor.red 50 | 51 | /// 未选中颜色 52 | var unSelectedColor:UIColor = UIColor.black 53 | 54 | /// 下标宽度 (在titleStyle 为normal时有效) 55 | var indicatorWidth:CGFloat = 30 56 | 57 | /// 下标高度 58 | var indicatorHeight:CGFloat = 2 59 | 60 | /// 下标距离底部距离 61 | var bottomPadding:CGFloat = 0 62 | 63 | //伸缩动画的偏移量 在indicatorStyle = stretch是生效 64 | var indicatorAnimatePadding:CGFloat = 8.0 65 | 66 | /// 标题字体 67 | var font:UIFont = UIFont.systemFont(ofSize: 13) 68 | 69 | /// 下标样式 70 | var indicatorStyle:SlideMenuIndicatorStyle = .normal 71 | 72 | /// 标题样式 73 | var titleStyle:SlideMenuTitleStyle = .normal 74 | 75 | ///bodyScrollView的父视图,默认为SlideMenu的父视图 76 | weak var bodySuperView:UIView? 77 | 78 | ///bodyScrollView的frame 79 | var bodyFrame:CGRect = CGRect.zero 80 | ``` 81 | 82 | 83 | 84 | ###### 2.样式 85 | 86 | ```swift 87 | enum SlideMenuTitleStyle { 88 | case normal //默认 89 | case gradient //颜色渐变 90 | case transfrom //放大 91 | } 92 | 93 | enum SlideMenuIndicatorStyle { 94 | case normal //常规 95 | case followText //跟随文本长度 96 | case stretch //伸缩 (推荐半塘效果) 97 | } 98 | ``` 99 | 100 | 101 | 102 | ###### 3.使用方法 103 | 104 | ```swift 105 | let titles = ["今天","速度100","是啊","测试机","水电","今天","速度","是啊","今天","速度","是啊"] 106 | var arr:Array = [] 107 | for _ in 0 ..< titles.count { 108 | let vc = CKChildViewController() 109 | self.addChildViewController(vc) 110 | arr.append(vc) 111 | } 112 | let slideMenu = CKSlideMenu(frame: CGRect(x:0,y:64,width:view.frame.width,height:40), titles:titles, childControllers:arr) 113 | slideMenu.titleStyle = .gradient 114 | slideMenu.indicatorStyle = .followText 115 | slideMenu.unSelectedColor = UIColor.gray 116 | slideMenu.bottomPadding = 4 117 | slideMenu.indicatorHeight = 2 118 | slideMenu.bodySuperView = view 119 | slideMenu.bodyFrame = CGRect.init(x: 0, y: 104, width: view.frame.width, height: view.frame.height - 104) 120 | //slideMenu.font = UIFont.systemFont(ofSize: 12) 121 | view.addSubview(slideMenu!) 122 | ``` 123 | 上述属性均可设置来满足不同的效果,欢迎指正出现的问题。谢谢~ 124 | 125 | [代码地址:https://github.com/90ck/CKSlideMenu](https://github.com/90ck/CKSlideMenu) 126 | 127 | [简书:http://www.jianshu.com/p/6ff8a4cb7d0b](http://www.jianshu.com/p/6ff8a4cb7d0b) 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /SlideMenu/CKSlideMenu.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CKSlideMenu.swift 3 | // LearnSwift 4 | // 5 | // Created by ck on 2017/6/15. 6 | // Copyright © 2017年 caike. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | enum SlideMenuTitleStyle { 12 | case normal //默认 13 | case gradient //渐变颜色 14 | case transfrom //放大 15 | } 16 | 17 | enum SlideMenuIndicatorStyle { 18 | case normal //常规 19 | case followText //跟随文本长度 20 | case stretch //伸缩 默认 21 | } 22 | 23 | 24 | 25 | class CKSlideMenu: UIView { 26 | 27 | //MARK: - 成员变量 28 | /// 是否是固定型菜单(不需要修正滚动) 29 | var isFixed:Bool = false 30 | 31 | /// 是否懒加载子控制器 32 | var lazyLoad:Bool = true 33 | 34 | /// 选中颜色 35 | var selectedColor:UIColor = UIColor.red { 36 | didSet { 37 | for item in itemButtons { 38 | item.setTitleColor(selectedColor, for: .selected) 39 | } 40 | } 41 | } 42 | 43 | /// 未选中颜色 44 | var unSelectedColor:UIColor = UIColor.black { 45 | didSet { 46 | for item in itemButtons { 47 | item.setTitleColor(unSelectedColor, for: .normal) 48 | } 49 | } 50 | } 51 | 52 | /// 下标宽度 53 | var indicatorWidth:CGFloat = 30 { //SlideMenuIndicatorStyle 为normal时有效 54 | didSet { 55 | setNeedsLayout() 56 | } 57 | } 58 | 59 | /// 下标高度 60 | var indicatorHeight:CGFloat = 2 { 61 | didSet { 62 | setNeedsLayout() 63 | } 64 | } 65 | 66 | /// 下标距离底部距离 67 | var bottomPadding:CGFloat = 0 { 68 | didSet { 69 | setNeedsLayout() 70 | } 71 | } 72 | 73 | //伸缩动画的偏移量 在indicatorStyle = stretch是生效 74 | var indicatorAnimatePadding:CGFloat = 8.0 75 | 76 | /// 标题字体 77 | var font:UIFont = UIFont.systemFont(ofSize: 13) { 78 | didSet { 79 | needLayout = true 80 | setNeedsLayout() 81 | } 82 | } 83 | 84 | /// 下标样式 85 | var indicatorStyle:SlideMenuIndicatorStyle = .normal { 86 | didSet{ 87 | setNeedsLayout() 88 | } 89 | } 90 | 91 | /// 标题样式 92 | var titleStyle:SlideMenuTitleStyle = .normal { 93 | didSet{ 94 | setNeedsLayout() 95 | } 96 | } 97 | 98 | ///bodyScrollView的父视图,默认为SlideMenu的父视图 99 | weak var bodySuperView:UIView? { 100 | didSet{ 101 | needLayout = true 102 | setNeedsLayout() 103 | } 104 | } 105 | 106 | ///bodyScrollView的frame 107 | var bodyFrame:CGRect = CGRect.zero { 108 | didSet{ 109 | bodyScrollView.frame = bodyFrame 110 | } 111 | } 112 | 113 | 114 | /// 菜单栏 115 | lazy var tabScrollView:UIScrollView = { 116 | let tabScrollView = UIScrollView.init(frame: self.bounds) 117 | tabScrollView.showsVerticalScrollIndicator = false 118 | tabScrollView.showsHorizontalScrollIndicator = false 119 | tabScrollView.backgroundColor = UIColor.clear 120 | return tabScrollView 121 | }() 122 | 123 | 124 | /// 内容视图 125 | lazy var bodyScrollView:UIScrollView = { 126 | let bodyScrollView = UIScrollView.init(frame: CGRect.zero) 127 | bodyScrollView.showsVerticalScrollIndicator = false 128 | bodyScrollView.showsHorizontalScrollIndicator = false 129 | bodyScrollView.isPagingEnabled = true 130 | bodyScrollView.bounces = false 131 | bodyScrollView.delegate = self 132 | return bodyScrollView 133 | }() 134 | 135 | 136 | /// 下标视图 137 | lazy var indicatorView:UIView = UIView() 138 | 139 | ///当前索引 140 | fileprivate(set) var currentIndex:Int = 0 141 | 142 | /// 底部分割线 默认不显示 143 | lazy var line:UIView = UIView() 144 | 145 | fileprivate var leftIndex:Int = 0 146 | fileprivate var rightIndex:Int = 0 147 | 148 | fileprivate var itemButtons:Array = [] 149 | // tab文字的边距 150 | fileprivate var itemMargin:CGFloat = 15.0 151 | 152 | private var needLayout:Bool = true 153 | private var titlesArr:Array 154 | private var controllers:Array 155 | 156 | 157 | // MARK: - 生命周期 158 | required init?(coder aDecoder: NSCoder) { 159 | fatalError("init(coder:) has not been implemented") 160 | } 161 | 162 | init(frame:CGRect ,titles:Array, childControllers:Array) { 163 | titlesArr = titles 164 | controllers = childControllers 165 | super.init(frame: frame) 166 | 167 | addSubview(tabScrollView) 168 | tabScrollView.addSubview(indicatorView) 169 | indicatorView.backgroundColor = selectedColor 170 | line.backgroundColor = UIColor(white: 0.9, alpha: 1) 171 | line.isHidden = true 172 | self.addSubview(line) 173 | } 174 | 175 | override func layoutSubviews() { 176 | super.layoutSubviews() 177 | 178 | tabScrollView.frame = self.bounds 179 | line.frame = CGRect(x: 0, y: self.frame.height - 0.5, width: self.frame.width, height: 0.5) 180 | 181 | if needLayout { 182 | for item in itemButtons { 183 | item.removeFromSuperview() 184 | } 185 | itemButtons.removeAll() 186 | setupTabScrollView() 187 | if bodySuperView != nil { 188 | bodySuperView?.addSubview(bodyScrollView) 189 | } 190 | else{ 191 | superview?.addSubview(bodyScrollView) 192 | } 193 | if lazyLoad { 194 | lazyLoadContents(at: currentIndex) 195 | } 196 | else { 197 | for (index, vc) in controllers.enumerated() { 198 | vc.view.frame = bodyScrollView.bounds 199 | vc.view.center = CGPoint(x: bodyScrollView.frame.width*(CGFloat(index)+0.5), y: bodyScrollView.frame.height/2) 200 | bodyScrollView.addSubview(vc.view) 201 | } 202 | } 203 | bodyScrollView.contentSize = CGSize(width: bodyScrollView.frame.width*CGFloat(controllers.count), height: bodyScrollView.frame.height) 204 | bodyScrollView.setContentOffset(CGPoint(x:bodyScrollView.frame.size.width*CGFloat(currentIndex), y:0), animated: false) 205 | resetTabScrollViewFrame() 206 | needLayout = false 207 | } 208 | setupIndicatorView() 209 | } 210 | 211 | /// 配置导航栏 212 | private func setupTabScrollView() { 213 | 214 | var originX:CGFloat = 0 215 | var totalTextLenght:CGFloat = 0 216 | for (index,title) in titlesArr.enumerated() { 217 | let item = UIButton.init() 218 | item.setTitleColor(selectedColor, for: .selected) 219 | item.setTitleColor(unSelectedColor, for: .normal) 220 | item.reversesTitleShadowWhenHighlighted = true 221 | item.titleLabel?.font = font 222 | item.setTitle(title, for: .normal) 223 | item.addTarget(self, action: #selector(itemClicked(_:)), for: .touchUpInside) 224 | 225 | let size = (title as NSString).size(attributes: [NSFontAttributeName:font]) 226 | item.frame = CGRect(x: originX, y: 0, width: size.width + itemMargin*2, height: self.frame.height) 227 | item.textWidth = size.width 228 | originX = item.frame.maxX 229 | itemButtons.append(item) 230 | tabScrollView.addSubview(item) 231 | item.isSelected = index == currentIndex 232 | if titleStyle == .transfrom && index == currentIndex { 233 | transformItem(item, isIdentify: false) 234 | } 235 | totalTextLenght += size.width 236 | } 237 | 238 | //固定型修正 239 | if isFixed { 240 | if totalTextLenght > self.frame.width { 241 | //文字长度超过容器,则平分宽度 242 | let width = self.frame.width/CGFloat(self.titlesArr.count) 243 | for (index,item) in itemButtons.enumerated() { 244 | item.frame = CGRect(x: width*CGFloat(index), y: 0, width: width, height: item.frame.height) 245 | item.textWidth = width 246 | } 247 | } 248 | else{ 249 | //未超过,按照文本长度计算margin 250 | let margin = (self.frame.width - totalTextLenght)/CGFloat(titlesArr.count*2) 251 | originX = 0 252 | for (_,item) in itemButtons.enumerated() { 253 | item.frame = CGRect(x: originX, y: 0, width: item.textWidth+2*margin, height: item.frame.height) 254 | originX = item.frame.maxX 255 | } 256 | } 257 | } 258 | tabScrollView.contentSize = CGSize(width: originX, height: self.frame.height) 259 | } 260 | 261 | ///配置下标 262 | private func setupIndicatorView() { 263 | 264 | var frame = itemButtons[currentIndex].frame 265 | frame.origin.y = self.frame.height - bottomPadding - indicatorHeight 266 | frame.size.height = indicatorHeight 267 | 268 | if indicatorStyle == .normal { 269 | frame.origin.x = frame.midX - indicatorWidth/2 270 | frame.size.width = indicatorWidth 271 | } 272 | else { 273 | let text = titlesArr[currentIndex] 274 | let size = (text as NSString).size(attributes: [NSFontAttributeName:font]) 275 | frame.origin.x = frame.midX - size.width/2 276 | frame.size.width = size.width 277 | } 278 | indicatorView.frame = frame 279 | } 280 | 281 | 282 | // 修正tabScrollView的位置 283 | fileprivate func resetTabScrollViewFrame() { 284 | 285 | if self.isFixed { 286 | return 287 | } 288 | 289 | let seletedItem = itemButtons[currentIndex] 290 | let tab_width = tabScrollView.frame.width 291 | var reviseX:CGFloat = 0 292 | 293 | if seletedItem.center.x + tab_width/2 >= tabScrollView.contentSize.width { 294 | reviseX = tabScrollView.contentSize.width - tab_width 295 | } 296 | else if (seletedItem.center.x - tab_width/2) <= 0 { 297 | reviseX = 0 298 | } 299 | else { 300 | reviseX = seletedItem.center.x - tab_width/2 301 | } 302 | tabScrollView.setContentOffset(CGPoint(x:reviseX,y:0), animated: true) 303 | } 304 | 305 | /// 懒加载子控制器 306 | /// 307 | /// - Parameter index: 索引 308 | fileprivate func lazyLoadContents(at index:Int) { 309 | let vc = controllers[index] 310 | if !vc.isViewLoaded { 311 | vc.view.frame = bodyScrollView.bounds 312 | vc.view.center = CGPoint(x: bodyScrollView.frame.width*(CGFloat(index)+0.5), y: bodyScrollView.frame.height/2) 313 | bodyScrollView.addSubview(vc.view) 314 | } 315 | } 316 | 317 | 318 | deinit { 319 | print("\(#function)") 320 | } 321 | 322 | 323 | //MARK: - 事件及UI 324 | 325 | func scrollToIndex(_ index:UInt) { 326 | if itemButtons.count > Int(index) { 327 | let button = itemButtons[currentIndex] 328 | itemClicked(button) 329 | } 330 | else { 331 | currentIndex = Int(index) 332 | } 333 | } 334 | 335 | 336 | /// 更新下标的UI效果 337 | /// 338 | /// - Parameter relativeLacation: 滑动的相对距离 339 | func updateIndicatorStyle(_ relativeLacation:CGFloat) { 340 | 341 | let leftItem = itemButtons[leftIndex] 342 | let rightItem = itemButtons[rightIndex] 343 | 344 | switch indicatorStyle { 345 | case .normal: 346 | //常规模式 只需更新中心点即可 347 | let max = rightItem.center.x - leftItem.center.x 348 | self.indicatorView.center = CGPoint(x:leftItem.center.x + max*relativeLacation,y:indicatorView.center.y) 349 | case .followText: 350 | 351 | 352 | var frame = self.indicatorView.frame 353 | let maxWidth = rightItem.textWidth - leftItem.textWidth 354 | frame.size.width = leftItem.textWidth + maxWidth*relativeLacation 355 | indicatorView.frame = frame 356 | 357 | let max = rightItem.center.x - leftItem.center.x 358 | indicatorView.center = CGPoint(x:leftItem.center.x + max*relativeLacation,y:indicatorView.center.y) 359 | 360 | case .stretch: 361 | //仔细观察位移效果,分析出如下计算公式 362 | var frame = self.indicatorView.frame 363 | 364 | let maxWidth = rightItem.textMaxX - leftItem.textMinX - indicatorAnimatePadding*2 365 | if relativeLacation <= 0.5 { 366 | frame.size.width = leftItem.textWidth + (maxWidth - leftItem.textWidth)*(relativeLacation/0.5) 367 | frame.origin.x = leftItem.textMinX + indicatorAnimatePadding*(relativeLacation/0.5) 368 | } 369 | else{ 370 | frame.size.width = rightItem.textWidth + (maxWidth - rightItem.textWidth)*((1-relativeLacation)/0.5) 371 | frame.origin.x = rightItem.textMaxX - frame.size.width - indicatorAnimatePadding*((1-relativeLacation)/0.5) 372 | } 373 | self.indicatorView.frame = frame 374 | } 375 | } 376 | 377 | 378 | /// 更新标题的UI效果 379 | /// 380 | /// - Parameter relativeLacation: 滑动的相对距离 381 | func updateTitleStyle(_ relativeLacation:CGFloat) { 382 | 383 | let leftItem = itemButtons[leftIndex] 384 | let rightItem = itemButtons[rightIndex] 385 | 386 | switch titleStyle { 387 | case .gradient: 388 | 389 | leftItem.isSelected = relativeLacation <= 0.5 390 | rightItem.isSelected = relativeLacation > 0.5 391 | 392 | let percent = relativeLacation <= 0.5 ? (1-relativeLacation) : relativeLacation 393 | 394 | leftItem.setTitleColor(self.averageColor(fromColor: unSelectedColor, toColor: selectedColor, percent: percent), for: .selected) 395 | leftItem.setTitleColor(self.averageColor(fromColor: selectedColor, toColor: unSelectedColor, percent: percent), for: .normal) 396 | 397 | rightItem.setTitleColor(self.averageColor(fromColor: unSelectedColor, toColor: selectedColor, percent: percent), for: .selected) 398 | rightItem.setTitleColor(self.averageColor(fromColor: selectedColor, toColor: unSelectedColor, percent: percent), for: .normal) 399 | 400 | case .normal: 401 | leftItem.isSelected = relativeLacation <= 0.5 402 | rightItem.isSelected = relativeLacation > 0.5 403 | 404 | default: 405 | 406 | if relativeLacation <= 0.5 { 407 | transformItem(leftItem, isIdentify: false) 408 | transformItem(rightItem, isIdentify: true) 409 | } 410 | else { 411 | transformItem(leftItem, isIdentify: true) 412 | transformItem(rightItem, isIdentify: false) 413 | } 414 | break 415 | } 416 | } 417 | 418 | 419 | /// 对item进行放大和还原操作 420 | /// 421 | /// - Parameters: 422 | /// - item: button 423 | /// - isIdentify: 是否还原 424 | private func transformItem(_ item:UIButton, isIdentify:Bool) { 425 | item.isSelected = !isIdentify 426 | item.transform = isIdentify ? CGAffineTransform.identity : CGAffineTransform.init(scaleX: 1.05, y: 1.05) 427 | 428 | } 429 | 430 | 431 | // 导航栏点击事件 432 | func itemClicked(_ button:UIButton) { 433 | if button.isSelected { 434 | return 435 | } 436 | let fromIndex = currentIndex 437 | currentIndex = itemButtons.index(of: button)! 438 | self.changeTitleItem(from: fromIndex, to: currentIndex) 439 | self.changeIndicator(from: fromIndex, to: currentIndex) 440 | bodyScrollView.setContentOffset(CGPoint(x:bodyScrollView.frame.size.width*CGFloat(currentIndex), y:0), animated: false) 441 | self.resetTabScrollViewFrame() 442 | } 443 | 444 | //点击事件触发的UI更新 445 | private func changeTitleItem(from:Int ,to:Int) { 446 | 447 | self.itemButtons[from].isSelected = false 448 | self.itemButtons[to].isSelected = true 449 | 450 | if titleStyle == .transfrom { 451 | UIView.animate(withDuration: 0.25, animations: { 452 | self.itemButtons[to].transform = CGAffineTransform.init(scaleX: 1.05, y: 1.05) 453 | self.itemButtons[from].transform = CGAffineTransform.identity 454 | 455 | }, completion: nil) 456 | } 457 | } 458 | 459 | //点击事件触发的UI更新 460 | private func changeIndicator(from:Int, to:Int) { 461 | let fromItem = itemButtons[from] 462 | let toItem = itemButtons[to] 463 | 464 | switch indicatorStyle { 465 | case .normal: 466 | UIView.animate(withDuration: 0.3, animations: { 467 | self.indicatorView.center = CGPoint(x:toItem.center.x,y:self.indicatorView.center.y) 468 | }) 469 | case .followText: 470 | var bounds = indicatorView.bounds 471 | bounds.size.width = toItem.textWidth 472 | UIView.animate(withDuration: 0.3, animations: { 473 | self.indicatorView.bounds = bounds 474 | self.indicatorView.center = CGPoint(x:toItem.center.x,y:self.indicatorView.center.y) 475 | 476 | }) 477 | case .stretch: 478 | var frame = indicatorView.frame 479 | frame.size.width = itemButtons[to].textWidth 480 | let finnalFrame = frame 481 | 482 | let max = fromItem.textWidth + toItem.textWidth + 2*itemMargin 483 | frame.size.width = max - indicatorAnimatePadding*2 484 | 485 | let x = (toItem.frame.maxX - fromItem.frame.minX)/2 + fromItem.frame.minX + itemMargin 486 | 487 | UIView.animateKeyframes(withDuration: 0.3, delay: 0, options: .calculationModePaced, animations: { 488 | 489 | UIView.addKeyframe(withRelativeStartTime:0, relativeDuration: 0.15, animations: { 490 | self.indicatorView.frame = frame 491 | self.indicatorView.center = CGPoint(x: x, y: self.indicatorView.center.y) 492 | }) 493 | 494 | UIView.addKeyframe(withRelativeStartTime: 0.15, relativeDuration: 0.15, animations: { 495 | self.indicatorView.frame = finnalFrame 496 | self.indicatorView.center = CGPoint(x: toItem.center.x, y: self.indicatorView.center.y) 497 | }) 498 | 499 | }, completion: nil) 500 | } 501 | } 502 | } 503 | 504 | 505 | // MARK: - 代理 506 | extension CKSlideMenu: UIScrollViewDelegate { 507 | 508 | 509 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 510 | 511 | if scrollView == self.bodyScrollView { 512 | let offset = scrollView.contentOffset 513 | currentIndex = lroundf(Float(scrollView.contentOffset.x / scrollView.frame.size.width)) 514 | 515 | var index = currentIndex 516 | if offset.x > scrollView.frame.width*CGFloat(currentIndex) { 517 | 518 | index = (currentIndex + 1) >= itemButtons.count ? currentIndex : currentIndex + 1 519 | } 520 | else if (offset.x < scrollView.frame.width*CGFloat(currentIndex)) { 521 | index = (currentIndex - 1) < 0 ? 0 : currentIndex - 1 522 | } 523 | lazyLoadContents(at:index) 524 | 525 | if offset.x <= 0 { 526 | // 左边界 527 | leftIndex = 0 528 | rightIndex = leftIndex 529 | } 530 | else if (offset.x >= scrollView.contentSize.width - scrollView.frame.width) { 531 | //右边界 532 | leftIndex = itemButtons.count - 1 533 | rightIndex = leftIndex 534 | } 535 | else{ 536 | leftIndex = Int(offset.x/scrollView.frame.width) 537 | rightIndex = leftIndex + 1 538 | } 539 | 540 | //计算偏移的相对位移 541 | let relativeLacation = bodyScrollView.contentOffset.x/bodyScrollView.frame.width - CGFloat(leftIndex) 542 | if relativeLacation == 0 { 543 | return 544 | } 545 | //更新UI 546 | self.updateIndicatorStyle(relativeLacation) 547 | self.updateTitleStyle(relativeLacation) 548 | 549 | } 550 | } 551 | 552 | 553 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 554 | if scrollView == bodyScrollView { 555 | currentIndex = Int(scrollView.contentOffset.x / scrollView.frame.size.width) 556 | // lazyLoadContents(at:currentIndex) 557 | self.resetTabScrollViewFrame() 558 | } 559 | } 560 | 561 | } 562 | 563 | 564 | extension CKSlideMenu { 565 | //渐变颜色 566 | fileprivate func averageColor(fromColor:UIColor , toColor:UIColor , percent:CGFloat) -> UIColor { 567 | var fromRed:CGFloat = 0.0 568 | var fromGreen:CGFloat = 0.0 569 | var fromBlue:CGFloat = 0.0 570 | var fromAlpha:CGFloat = 0.0 571 | fromColor.getRed(&fromRed, green: &fromGreen, blue: &fromBlue, alpha: &fromAlpha) 572 | 573 | var toRed:CGFloat = 0.0 574 | var toGreen:CGFloat = 0.0 575 | var toBlue:CGFloat = 0.0 576 | var toAlpha:CGFloat = 0.0 577 | toColor.getRed(&toRed, green: &toGreen, blue: &toBlue, alpha: &toAlpha) 578 | 579 | let nowRed = fromRed + (toRed - fromRed)*percent 580 | let nowGreen = fromGreen + (toGreen - fromGreen)*percent 581 | let nowBlue = fromBlue + (toBlue - fromBlue)*percent 582 | let nowAlpha = fromAlpha + (toAlpha - fromAlpha)*percent 583 | 584 | return UIColor(red: nowRed, green: nowGreen, blue: nowBlue, alpha: nowAlpha) 585 | } 586 | } 587 | 588 | 589 | private extension UIButton { 590 | private struct AssociatedKeys { 591 | static var textWidthName = "key_textWidth" 592 | } 593 | 594 | /// title的文本长度 595 | var textWidth:CGFloat { 596 | get{ 597 | return objc_getAssociatedObject(self, &AssociatedKeys.textWidthName) as? CGFloat ?? 0 598 | } 599 | set{ 600 | objc_setAssociatedObject(self, &AssociatedKeys.textWidthName, newValue , objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) 601 | } 602 | } 603 | 604 | var textMinX:CGFloat { 605 | get { 606 | return (self.frame.width - self.textWidth)/2 + self.frame.minX 607 | } 608 | } 609 | 610 | var textMaxX:CGFloat { 611 | get { 612 | return self.frame.maxX - (self.frame.width - self.textWidth)/2 613 | } 614 | } 615 | } 616 | 617 | 618 | 619 | -------------------------------------------------------------------------------- /SlideMenu02.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/90ck/CKSlideMenu/08a6f16a34a6d9005337b367a7ad2b1a790d8a2c/SlideMenu02.gif -------------------------------------------------------------------------------- /SlideMenu03.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/90ck/CKSlideMenu/08a6f16a34a6d9005337b367a7ad2b1a790d8a2c/SlideMenu03.gif -------------------------------------------------------------------------------- /SlideMneu01.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/90ck/CKSlideMenu/08a6f16a34a6d9005337b367a7ad2b1a790d8a2c/SlideMneu01.gif --------------------------------------------------------------------------------