├── .gitattributes ├── .gitignore ├── Example ├── IndexBar.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── IndexBar │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift ├── IndexBar.podspec ├── IndexBar ├── 0.0.1 │ └── IndexBar.podspec ├── 0.0.2 │ └── IndexBar.podspec ├── 0.0.3 │ └── IndexBar.podspec ├── 1.0.0 │ └── IndexBar.podspec ├── 1.0.1 │ └── IndexBar.podspec ├── IndexBar.swift └── IndexBarBubbleView.swift ├── IndexBar@1x.png ├── LICENSE ├── README.md └── 图像.gif /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | *.rb linguist-language=swift 3 | *.podspec linguist-language=swift 4 | 5 | *.storyboard linguist-language=swift 6 | *.json linguist-language=swift 7 | 8 | 9 | *.xcodeproj linguist-language=swift -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | -------------------------------------------------------------------------------- /Example/IndexBar.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7642E5452511E6C900FC6D68 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7642E5442511E6C900FC6D68 /* AppDelegate.swift */; }; 11 | 7642E5472511E6C900FC6D68 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7642E5462511E6C900FC6D68 /* SceneDelegate.swift */; }; 12 | 7642E5492511E6C900FC6D68 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7642E5482511E6C900FC6D68 /* ViewController.swift */; }; 13 | 7642E54C2511E6C900FC6D68 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7642E54A2511E6C900FC6D68 /* Main.storyboard */; }; 14 | 7642E54E2511E6CB00FC6D68 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7642E54D2511E6CB00FC6D68 /* Assets.xcassets */; }; 15 | 7642E5512511E6CB00FC6D68 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7642E54F2511E6CB00FC6D68 /* LaunchScreen.storyboard */; }; 16 | 7642E5602511F19A00FC6D68 /* IndexBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7642E55E2511F19A00FC6D68 /* IndexBar.swift */; }; 17 | 7642E5612511F19A00FC6D68 /* IndexBarBubbleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7642E55F2511F19A00FC6D68 /* IndexBarBubbleView.swift */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 7642E5412511E6C900FC6D68 /* IndexBar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IndexBar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 7642E5442511E6C900FC6D68 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 23 | 7642E5462511E6C900FC6D68 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 24 | 7642E5482511E6C900FC6D68 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 25 | 7642E54B2511E6C900FC6D68 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 26 | 7642E54D2511E6CB00FC6D68 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 27 | 7642E5502511E6CB00FC6D68 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 28 | 7642E5522511E6CB00FC6D68 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29 | 7642E55E2511F19A00FC6D68 /* IndexBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndexBar.swift; sourceTree = ""; }; 30 | 7642E55F2511F19A00FC6D68 /* IndexBarBubbleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IndexBarBubbleView.swift; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 7642E53E2511E6C900FC6D68 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 7642E5382511E6C900FC6D68 = { 45 | isa = PBXGroup; 46 | children = ( 47 | 7642E5432511E6C900FC6D68 /* IndexBar */, 48 | 7642E5422511E6C900FC6D68 /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 7642E5422511E6C900FC6D68 /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 7642E5412511E6C900FC6D68 /* IndexBar.app */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 7642E5432511E6C900FC6D68 /* IndexBar */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 7642E55D2511F19A00FC6D68 /* IndexBar */, 64 | 7642E5442511E6C900FC6D68 /* AppDelegate.swift */, 65 | 7642E5462511E6C900FC6D68 /* SceneDelegate.swift */, 66 | 7642E5482511E6C900FC6D68 /* ViewController.swift */, 67 | 7642E54A2511E6C900FC6D68 /* Main.storyboard */, 68 | 7642E54D2511E6CB00FC6D68 /* Assets.xcassets */, 69 | 7642E54F2511E6CB00FC6D68 /* LaunchScreen.storyboard */, 70 | 7642E5522511E6CB00FC6D68 /* Info.plist */, 71 | ); 72 | path = IndexBar; 73 | sourceTree = ""; 74 | }; 75 | 7642E55D2511F19A00FC6D68 /* IndexBar */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 7642E55E2511F19A00FC6D68 /* IndexBar.swift */, 79 | 7642E55F2511F19A00FC6D68 /* IndexBarBubbleView.swift */, 80 | ); 81 | name = IndexBar; 82 | path = ../../IndexBar; 83 | sourceTree = ""; 84 | }; 85 | /* End PBXGroup section */ 86 | 87 | /* Begin PBXNativeTarget section */ 88 | 7642E5402511E6C900FC6D68 /* IndexBar */ = { 89 | isa = PBXNativeTarget; 90 | buildConfigurationList = 7642E5552511E6CB00FC6D68 /* Build configuration list for PBXNativeTarget "IndexBar" */; 91 | buildPhases = ( 92 | 7642E53D2511E6C900FC6D68 /* Sources */, 93 | 7642E53E2511E6C900FC6D68 /* Frameworks */, 94 | 7642E53F2511E6C900FC6D68 /* Resources */, 95 | ); 96 | buildRules = ( 97 | ); 98 | dependencies = ( 99 | ); 100 | name = IndexBar; 101 | productName = IndexBar; 102 | productReference = 7642E5412511E6C900FC6D68 /* IndexBar.app */; 103 | productType = "com.apple.product-type.application"; 104 | }; 105 | /* End PBXNativeTarget section */ 106 | 107 | /* Begin PBXProject section */ 108 | 7642E5392511E6C900FC6D68 /* Project object */ = { 109 | isa = PBXProject; 110 | attributes = { 111 | LastSwiftUpdateCheck = 1160; 112 | LastUpgradeCheck = 1160; 113 | ORGANIZATIONNAME = Silhorse; 114 | TargetAttributes = { 115 | 7642E5402511E6C900FC6D68 = { 116 | CreatedOnToolsVersion = 11.6; 117 | }; 118 | }; 119 | }; 120 | buildConfigurationList = 7642E53C2511E6C900FC6D68 /* Build configuration list for PBXProject "IndexBar" */; 121 | compatibilityVersion = "Xcode 9.3"; 122 | developmentRegion = en; 123 | hasScannedForEncodings = 0; 124 | knownRegions = ( 125 | en, 126 | Base, 127 | ); 128 | mainGroup = 7642E5382511E6C900FC6D68; 129 | productRefGroup = 7642E5422511E6C900FC6D68 /* Products */; 130 | projectDirPath = ""; 131 | projectRoot = ""; 132 | targets = ( 133 | 7642E5402511E6C900FC6D68 /* IndexBar */, 134 | ); 135 | }; 136 | /* End PBXProject section */ 137 | 138 | /* Begin PBXResourcesBuildPhase section */ 139 | 7642E53F2511E6C900FC6D68 /* Resources */ = { 140 | isa = PBXResourcesBuildPhase; 141 | buildActionMask = 2147483647; 142 | files = ( 143 | 7642E5512511E6CB00FC6D68 /* LaunchScreen.storyboard in Resources */, 144 | 7642E54E2511E6CB00FC6D68 /* Assets.xcassets in Resources */, 145 | 7642E54C2511E6C900FC6D68 /* Main.storyboard in Resources */, 146 | ); 147 | runOnlyForDeploymentPostprocessing = 0; 148 | }; 149 | /* End PBXResourcesBuildPhase section */ 150 | 151 | /* Begin PBXSourcesBuildPhase section */ 152 | 7642E53D2511E6C900FC6D68 /* Sources */ = { 153 | isa = PBXSourcesBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | 7642E5492511E6C900FC6D68 /* ViewController.swift in Sources */, 157 | 7642E5452511E6C900FC6D68 /* AppDelegate.swift in Sources */, 158 | 7642E5602511F19A00FC6D68 /* IndexBar.swift in Sources */, 159 | 7642E5612511F19A00FC6D68 /* IndexBarBubbleView.swift in Sources */, 160 | 7642E5472511E6C900FC6D68 /* SceneDelegate.swift in Sources */, 161 | ); 162 | runOnlyForDeploymentPostprocessing = 0; 163 | }; 164 | /* End PBXSourcesBuildPhase section */ 165 | 166 | /* Begin PBXVariantGroup section */ 167 | 7642E54A2511E6C900FC6D68 /* Main.storyboard */ = { 168 | isa = PBXVariantGroup; 169 | children = ( 170 | 7642E54B2511E6C900FC6D68 /* Base */, 171 | ); 172 | name = Main.storyboard; 173 | sourceTree = ""; 174 | }; 175 | 7642E54F2511E6CB00FC6D68 /* LaunchScreen.storyboard */ = { 176 | isa = PBXVariantGroup; 177 | children = ( 178 | 7642E5502511E6CB00FC6D68 /* Base */, 179 | ); 180 | name = LaunchScreen.storyboard; 181 | sourceTree = ""; 182 | }; 183 | /* End PBXVariantGroup section */ 184 | 185 | /* Begin XCBuildConfiguration section */ 186 | 7642E5532511E6CB00FC6D68 /* Debug */ = { 187 | isa = XCBuildConfiguration; 188 | buildSettings = { 189 | ALWAYS_SEARCH_USER_PATHS = NO; 190 | CLANG_ANALYZER_NONNULL = YES; 191 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 192 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 193 | CLANG_CXX_LIBRARY = "libc++"; 194 | CLANG_ENABLE_MODULES = YES; 195 | CLANG_ENABLE_OBJC_ARC = YES; 196 | CLANG_ENABLE_OBJC_WEAK = YES; 197 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 198 | CLANG_WARN_BOOL_CONVERSION = YES; 199 | CLANG_WARN_COMMA = YES; 200 | CLANG_WARN_CONSTANT_CONVERSION = YES; 201 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 202 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 203 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 204 | CLANG_WARN_EMPTY_BODY = YES; 205 | CLANG_WARN_ENUM_CONVERSION = YES; 206 | CLANG_WARN_INFINITE_RECURSION = YES; 207 | CLANG_WARN_INT_CONVERSION = YES; 208 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 209 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 210 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 211 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 212 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 213 | CLANG_WARN_STRICT_PROTOTYPES = YES; 214 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 215 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | COPY_PHASE_STRIP = NO; 219 | DEBUG_INFORMATION_FORMAT = dwarf; 220 | ENABLE_STRICT_OBJC_MSGSEND = YES; 221 | ENABLE_TESTABILITY = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu11; 223 | GCC_DYNAMIC_NO_PIC = NO; 224 | GCC_NO_COMMON_BLOCKS = YES; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 232 | GCC_WARN_UNDECLARED_SELECTOR = YES; 233 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 234 | GCC_WARN_UNUSED_FUNCTION = YES; 235 | GCC_WARN_UNUSED_VARIABLE = YES; 236 | IPHONEOS_DEPLOYMENT_TARGET = 13.6; 237 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 238 | MTL_FAST_MATH = YES; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 242 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 243 | }; 244 | name = Debug; 245 | }; 246 | 7642E5542511E6CB00FC6D68 /* Release */ = { 247 | isa = XCBuildConfiguration; 248 | buildSettings = { 249 | ALWAYS_SEARCH_USER_PATHS = NO; 250 | CLANG_ANALYZER_NONNULL = YES; 251 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_ENABLE_OBJC_WEAK = YES; 257 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 258 | CLANG_WARN_BOOL_CONVERSION = YES; 259 | CLANG_WARN_COMMA = YES; 260 | CLANG_WARN_CONSTANT_CONVERSION = YES; 261 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 264 | CLANG_WARN_EMPTY_BODY = YES; 265 | CLANG_WARN_ENUM_CONVERSION = YES; 266 | CLANG_WARN_INFINITE_RECURSION = YES; 267 | CLANG_WARN_INT_CONVERSION = YES; 268 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 269 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 270 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 271 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 272 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 273 | CLANG_WARN_STRICT_PROTOTYPES = YES; 274 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 275 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 276 | CLANG_WARN_UNREACHABLE_CODE = YES; 277 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 278 | COPY_PHASE_STRIP = NO; 279 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 280 | ENABLE_NS_ASSERTIONS = NO; 281 | ENABLE_STRICT_OBJC_MSGSEND = YES; 282 | GCC_C_LANGUAGE_STANDARD = gnu11; 283 | GCC_NO_COMMON_BLOCKS = YES; 284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 286 | GCC_WARN_UNDECLARED_SELECTOR = YES; 287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 288 | GCC_WARN_UNUSED_FUNCTION = YES; 289 | GCC_WARN_UNUSED_VARIABLE = YES; 290 | IPHONEOS_DEPLOYMENT_TARGET = 13.6; 291 | MTL_ENABLE_DEBUG_INFO = NO; 292 | MTL_FAST_MATH = YES; 293 | SDKROOT = iphoneos; 294 | SWIFT_COMPILATION_MODE = wholemodule; 295 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 296 | VALIDATE_PRODUCT = YES; 297 | }; 298 | name = Release; 299 | }; 300 | 7642E5562511E6CB00FC6D68 /* Debug */ = { 301 | isa = XCBuildConfiguration; 302 | buildSettings = { 303 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 304 | CODE_SIGN_STYLE = Automatic; 305 | DEVELOPMENT_TEAM = G5B4C2BMU7; 306 | INFOPLIST_FILE = IndexBar/Info.plist; 307 | LD_RUNPATH_SEARCH_PATHS = ( 308 | "$(inherited)", 309 | "@executable_path/Frameworks", 310 | ); 311 | PRODUCT_BUNDLE_IDENTIFIER = com.silhorse.IndexBar; 312 | PRODUCT_NAME = "$(TARGET_NAME)"; 313 | SWIFT_VERSION = 5.0; 314 | TARGETED_DEVICE_FAMILY = "1,2"; 315 | }; 316 | name = Debug; 317 | }; 318 | 7642E5572511E6CB00FC6D68 /* Release */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 322 | CODE_SIGN_STYLE = Automatic; 323 | DEVELOPMENT_TEAM = G5B4C2BMU7; 324 | INFOPLIST_FILE = IndexBar/Info.plist; 325 | LD_RUNPATH_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | "@executable_path/Frameworks", 328 | ); 329 | PRODUCT_BUNDLE_IDENTIFIER = com.silhorse.IndexBar; 330 | PRODUCT_NAME = "$(TARGET_NAME)"; 331 | SWIFT_VERSION = 5.0; 332 | TARGETED_DEVICE_FAMILY = "1,2"; 333 | }; 334 | name = Release; 335 | }; 336 | /* End XCBuildConfiguration section */ 337 | 338 | /* Begin XCConfigurationList section */ 339 | 7642E53C2511E6C900FC6D68 /* Build configuration list for PBXProject "IndexBar" */ = { 340 | isa = XCConfigurationList; 341 | buildConfigurations = ( 342 | 7642E5532511E6CB00FC6D68 /* Debug */, 343 | 7642E5542511E6CB00FC6D68 /* Release */, 344 | ); 345 | defaultConfigurationIsVisible = 0; 346 | defaultConfigurationName = Release; 347 | }; 348 | 7642E5552511E6CB00FC6D68 /* Build configuration list for PBXNativeTarget "IndexBar" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | 7642E5562511E6CB00FC6D68 /* Debug */, 352 | 7642E5572511E6CB00FC6D68 /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | defaultConfigurationName = Release; 356 | }; 357 | /* End XCConfigurationList section */ 358 | }; 359 | rootObject = 7642E5392511E6C900FC6D68 /* Project object */; 360 | } 361 | -------------------------------------------------------------------------------- /Example/IndexBar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/IndexBar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/IndexBar/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // IndexBar 4 | // 5 | // Created by rainedAllNight on 2020/9/16. 6 | // Copyright © 2020 Silhorse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | // Override point for customization after application launch. 18 | return true 19 | } 20 | 21 | // MARK: UISceneSession Lifecycle 22 | 23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 24 | // Called when a new scene session is being created. 25 | // Use this method to select a configuration to create the new scene with. 26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 27 | } 28 | 29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 30 | // Called when the user discards a scene session. 31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 33 | } 34 | 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Example/IndexBar/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/IndexBar/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/IndexBar/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 | -------------------------------------------------------------------------------- /Example/IndexBar/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 | -------------------------------------------------------------------------------- /Example/IndexBar/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIApplicationSceneManifest 24 | 25 | UIApplicationSupportsMultipleScenes 26 | 27 | UISceneConfigurations 28 | 29 | UIWindowSceneSessionRoleApplication 30 | 31 | 32 | UISceneConfigurationName 33 | Default Configuration 34 | UISceneDelegateClassName 35 | $(PRODUCT_MODULE_NAME).SceneDelegate 36 | UISceneStoryboardFile 37 | Main 38 | 39 | 40 | 41 | 42 | UILaunchStoryboardName 43 | LaunchScreen 44 | UIMainStoryboardFile 45 | Main 46 | UIRequiredDeviceCapabilities 47 | 48 | armv7 49 | 50 | UISupportedInterfaceOrientations 51 | 52 | UIInterfaceOrientationPortrait 53 | UIInterfaceOrientationLandscapeLeft 54 | UIInterfaceOrientationLandscapeRight 55 | 56 | UISupportedInterfaceOrientations~ipad 57 | 58 | UIInterfaceOrientationPortrait 59 | UIInterfaceOrientationPortraitUpsideDown 60 | UIInterfaceOrientationLandscapeLeft 61 | UIInterfaceOrientationLandscapeRight 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Example/IndexBar/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // IndexBar 4 | // 5 | // Created by rainedAllNight on 2020/9/16. 6 | // Copyright © 2020 Silhorse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | } 34 | 35 | func sceneWillResignActive(_ scene: UIScene) { 36 | // Called when the scene will move from an active state to an inactive state. 37 | // This may occur due to temporary interruptions (ex. an incoming phone call). 38 | } 39 | 40 | func sceneWillEnterForeground(_ scene: UIScene) { 41 | // Called as the scene transitions from the background to the foreground. 42 | // Use this method to undo the changes made on entering the background. 43 | } 44 | 45 | func sceneDidEnterBackground(_ scene: UIScene) { 46 | // Called as the scene transitions from the foreground to the background. 47 | // Use this method to save data, release shared resources, and store enough scene-specific state information 48 | // to restore the scene back to its current state. 49 | } 50 | 51 | 52 | } 53 | 54 | -------------------------------------------------------------------------------- /Example/IndexBar/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // IndexBar 4 | // 5 | // Created by rainedAllNight on 2020/9/16. 6 | // Copyright © 2020 Silhorse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view. 16 | } 17 | 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "1.0.1" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "1.0.1" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/0.0.1/IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "0.0.1" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "0.0.1" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/0.0.2/IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "0.0.2" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "0.0.2" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/0.0.3/IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "0.0.3" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "0.0.2" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/1.0.0/IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "1.0.0" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "1.0.0" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/1.0.1/IndexBar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint IndexBar.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 https://guides.cocoapods.org/syntax/podspec.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |spec| 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 | spec.name = "IndexBar" 19 | spec.version = "1.0.1" 20 | spec.summary = "A tableview index bar with Swift" 21 | 22 | # This description is used to generate tags and improve search results. 23 | # * Think: What does it do? Why did you write it? What is the focus? 24 | # * Try to keep it short, snappy and to the point. 25 | # * Write the description between the DESC delimiters below. 26 | # * Finally, don't worry about the indent, CocoaPods strips it! 27 | spec.description = <<-DESC 28 | "A tableview index bar with Swift" 29 | DESC 30 | 31 | spec.homepage = "https://github.com/rainedAllNight/IndexBar" 32 | # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" 33 | 34 | 35 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 36 | # 37 | # Licensing your code is important. See https://choosealicense.com for more info. 38 | # CocoaPods will detect a license file if there is a named LICENSE* 39 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 40 | # 41 | 42 | spec.license = "MIT" 43 | # spec.license = { :type => "MIT", :file => "FILE_LICENSE" } 44 | 45 | 46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 47 | # 48 | # Specify the authors of the library, with email addresses. Email addresses 49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 50 | # accepts just a name if you'd rather not provide an email address. 51 | # 52 | # Specify a social_media_url where others can refer to, for example a twitter 53 | # profile URL. 54 | # 55 | 56 | spec.author = { "luowei" => "1368614674@qq.com" } 57 | # Or just: spec.author = "luowei" 58 | # spec.authors = { "luowei" => "1368614674@qq.com" } 59 | # spec.social_media_url = "https://twitter.com/luowei" 60 | 61 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 62 | # 63 | # If this Pod runs only on iOS or OS X, then specify the platform and 64 | # the deployment target. You can optionally include the target after the platform. 65 | # 66 | 67 | spec.platform = :ios 68 | spec.platform = :ios, "10.0" 69 | 70 | # When using multiple platforms 71 | # spec.ios.deployment_target = "5.0" 72 | # spec.osx.deployment_target = "10.7" 73 | # spec.watchos.deployment_target = "2.0" 74 | # spec.tvos.deployment_target = "9.0" 75 | 76 | 77 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 78 | # 79 | # Specify the location from where the source should be retrieved. 80 | # Supports git, hg, bzr, svn and HTTP. 81 | # 82 | 83 | spec.source = { :git => "https://github.com/rainedAllNight/IndexBar.git", :tag => "1.0.1" } 84 | 85 | 86 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 87 | # 88 | # CocoaPods is smart about how it includes source code. For source files 89 | # giving a folder will include any swift, h, m, mm, c & cpp files. 90 | # For header files it will include any header in the folder. 91 | # Not including the public_header_files will make all headers public. 92 | # 93 | 94 | spec.source_files = "IndexBar/*" 95 | # spec.exclude_files = "Classes/Exclude" 96 | 97 | # spec.public_header_files = "Classes/**/*.h" 98 | 99 | 100 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 101 | # 102 | # A list of resources included with the Pod. These are copied into the 103 | # target bundle with a build phase script. Anything else will be cleaned. 104 | # You can preserve files from being cleaned, please don't preserve 105 | # non-essential files like tests, examples and documentation. 106 | # 107 | 108 | # spec.resource = "icon.png" 109 | # spec.resources = "Resources/*.png" 110 | 111 | # spec.preserve_paths = "FilesToSave", "MoreFilesToSave" 112 | 113 | 114 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 115 | # 116 | # Link your library with frameworks, or libraries. Libraries do not include 117 | # the lib prefix of their name. 118 | # 119 | 120 | spec.framework = "UIKit" 121 | # spec.frameworks = "SomeFramework", "AnotherFramework" 122 | 123 | # spec.library = "iconv" 124 | # spec.libraries = "iconv", "xml2" 125 | 126 | 127 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 128 | # 129 | # If your library depends on compiler flags you can set them in the xcconfig hash 130 | # where they will only apply to your library. If you depend on other Podspecs 131 | # you can include multiple dependencies to ensure it works. 132 | 133 | spec.requires_arc = true 134 | 135 | # spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 136 | # spec.dependency "JSONKit", "~> 1.4" 137 | 138 | swift_versions = "5.0" 139 | 140 | end 141 | -------------------------------------------------------------------------------- /IndexBar/IndexBar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexBar.swift 3 | // Rescue 4 | // 5 | // Created by rainedAllNight on 2020/8/17. 6 | // Copyright © 2020 luowei. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol IndexBarDelegate: class { 12 | func indexBar(_ indexBar: IndexBar, didSelected index: Int) 13 | } 14 | 15 | fileprivate enum IndexSectionState { 16 | case normal 17 | case selected 18 | } 19 | 20 | public struct IndexBarConfigure { 21 | /// section normal title color 22 | public var titleColor: UIColor = .lightGray 23 | /// section title font 24 | public var titleFont: UIFont = UIFont.systemFont(ofSize: 10) 25 | /// section selected title color 26 | public var titleColorForSelected: UIColor = .white 27 | /// section selected background color 28 | public var backgroundColorForSelected: UIColor = .blue 29 | /// section width&height 30 | public var sectionWH: CGFloat = 16 31 | /// section vertical spacing 32 | public var sectionSpacing: CGFloat = 4 33 | /// show bubble view, default is true 34 | public var showBubble = true 35 | /// the configure of the bubble view 36 | public var bubbleConfigure = BubbleConfigure() 37 | } 38 | 39 | public class IndexBar: UIView, UITableViewDelegate { 40 | 41 | @IBInspectable private var titleColor: UIColor? { 42 | willSet { 43 | guard let new = newValue else {return} 44 | _configure.titleColor = new 45 | } 46 | } 47 | @IBInspectable private var selectedTitleColor: UIColor? { 48 | willSet { 49 | guard let new = newValue else {return} 50 | _configure.titleColorForSelected = new 51 | } 52 | } 53 | @IBInspectable private var selectedBackgroundColor: UIColor? { 54 | willSet { 55 | guard let new = newValue else {return} 56 | _configure.backgroundColorForSelected = new 57 | } 58 | } 59 | @IBInspectable private var showBubble: Bool = true { 60 | willSet { 61 | _configure.showBubble = newValue 62 | } 63 | } 64 | @IBInspectable private var sectionWH: CGFloat = 0 { 65 | willSet { 66 | _configure.sectionWH = newValue 67 | } 68 | } 69 | @IBInspectable private var sectionSpacing: CGFloat = 0 { 70 | willSet { 71 | _configure.sectionSpacing = newValue 72 | } 73 | } 74 | 75 | ///if you want to listen the callback of section seleced, please set the delegate(如果想监听切换section的回调可实现此代理) 76 | public weak var delegate: IndexBarDelegate? 77 | /// configure index bar 78 | public var configure: ((inout IndexBarConfigure) -> ())? { 79 | willSet { 80 | newValue?(&_configure) 81 | initUI() 82 | } 83 | } 84 | 85 | private var dataSource = [String]() 86 | private var lastSelectedLabel: UILabel? 87 | private var lastSelectedIndex = -1 88 | private var subLabels = [UILabel]() 89 | private var tableView: UITableView? 90 | private var observe: NSKeyValueObservation? 91 | private var bubbleView: IndexBarBubbleView? 92 | private var _configure = IndexBarConfigure() 93 | 94 | // MARK: - Init data 95 | 96 | ///Use this function to init data 97 | public func setData(_ titles: [String], tableView: UITableView) { 98 | self.dataSource = titles 99 | self.tableView = tableView 100 | layoutIfNeeded() 101 | initUI() 102 | } 103 | 104 | // MARK: - UI 105 | 106 | private func initUI() { 107 | backgroundColor = .clear 108 | guard !dataSource.isEmpty else {return} 109 | reset() 110 | let redundantHeight = bounds.height - (_configure.sectionWH + _configure.sectionSpacing) * CGFloat(dataSource.count) 111 | var y: CGFloat = redundantHeight > 0 ? redundantHeight/2 : 0 112 | dataSource.forEach({ 113 | let label = UILabel(frame: CGRect(x: 0, y: y, width: _configure.sectionWH, height: _configure.sectionWH)) 114 | y += _configure.sectionWH + _configure.sectionSpacing 115 | label.text = $0 116 | label.textAlignment = .center 117 | label.layer.cornerRadius = _configure.sectionWH/2 118 | label.font = _configure.titleFont 119 | setIndexSection(label) 120 | subLabels.append(label) 121 | addSubview(label) 122 | }) 123 | ///default select first 124 | selectSection(index: 0) 125 | addObserver() 126 | addBubbleView() 127 | } 128 | 129 | private func reset() { 130 | lastSelectedIndex = -1 131 | lastSelectedLabel = nil 132 | subLabels.removeAll() 133 | observe = nil 134 | subviews.forEach({$0.removeFromSuperview()}) 135 | } 136 | 137 | private func addBubbleView() { 138 | guard _configure.showBubble else {return} 139 | self.bubbleView?.removeFromSuperview() 140 | let bubbleView = IndexBarBubbleView.init(frame: CGRect(x: -80, y: 0, width: 60, height: 60), configure: _configure.bubbleConfigure) 141 | addSubview(bubbleView) 142 | bubbleView.alpha = 0 143 | self.bubbleView = bubbleView 144 | } 145 | 146 | private func addObserver() { 147 | observe = tableView?.observe(\.contentOffset, options: .new, changeHandler: { [unowned self] (tableView, change) in 148 | guard let point = change.newValue else {return} 149 | guard let indexPath = tableView.indexPathForRow(at: point), indexPath.section < self.dataSource.count else {return} 150 | guard tableView.isDragging || tableView.isDecelerating else {return} 151 | self.selectSection(index: indexPath.section) 152 | }) 153 | } 154 | 155 | private func setIndexSection(_ label: UILabel, 156 | with state: IndexSectionState = .normal) { 157 | switch state { 158 | case .normal: 159 | label.textColor = _configure.titleColor 160 | label.layer.backgroundColor = UIColor.clear.cgColor 161 | case.selected: 162 | label.textColor = _configure.titleColorForSelected 163 | label.layer.backgroundColor = _configure.backgroundColorForSelected.cgColor 164 | lastSelectedLabel = label 165 | if let index = subLabels.firstIndex(of: label) { 166 | delegate?.indexBar(self, didSelected: index) 167 | } 168 | } 169 | } 170 | 171 | private func selectSection(point: CGPoint) { 172 | guard point.x <= bounds.width, 173 | point.y <= bounds.height, 174 | point.y > 0 else {return} 175 | var index = -1 176 | guard let label = subLabels.first(where: { 177 | index += 1 178 | return point.y < $0.frame.maxY 179 | }) else {return} 180 | if let last = lastSelectedLabel { 181 | setIndexSection(last, with: .normal) 182 | } 183 | setIndexSection(label, with: .selected) 184 | if lastSelectedIndex != index { 185 | addImpactFeedback() 186 | bubbleView?.show(label.text, on: CGPoint(x: bubbleView?.center.x ?? label.center.x, y: label.center.y)) 187 | tableView?.scrollToRow(at: IndexPath(item: 0, section: index), at: .top, animated: true) 188 | lastSelectedIndex = index 189 | } 190 | } 191 | 192 | private func selectSection(index: Int) { 193 | if let last = lastSelectedLabel { 194 | setIndexSection(last, with: .normal) 195 | } 196 | setIndexSection(subLabels[index], with: .selected) 197 | } 198 | 199 | private func addImpactFeedback() { 200 | let impact = UIImpactFeedbackGenerator(style: .light) 201 | impact.prepare() 202 | impact.impactOccurred() 203 | } 204 | 205 | // MARK: - Touch Event 206 | 207 | public override func touchesBegan(_ touches: Set, with event: UIEvent?) { 208 | super.touchesBegan(touches, with: event) 209 | } 210 | 211 | public override func touchesMoved(_ touches: Set, with event: UIEvent?) { 212 | super.touchesMoved(touches, with: event) 213 | guard let point = event?.touches(for: self)?.first?.location(in: self) else {return} 214 | selectSection(point: point) 215 | } 216 | 217 | public override func touchesEnded(_ touches: Set, with event: UIEvent?) { 218 | super.touchesEnded(touches, with: event) 219 | guard let point = event?.touches(for: self)?.first?.location(in: self) else {return} 220 | selectSection(point: point) 221 | bubbleView?.hide() 222 | } 223 | } 224 | 225 | 226 | -------------------------------------------------------------------------------- /IndexBar/IndexBarBubbleView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IndexBarBubbleView.swift 3 | // IndexBar 4 | // 5 | // Created by rainedAllNight on 2020/9/16. 6 | // Copyright © 2020 Silhorse. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public struct BubbleConfigure { 12 | public var font: UIFont = .systemFont(ofSize: 22, weight: .medium) 13 | public var textColor: UIColor = .white 14 | public var backgroundColor = UIColor.lightGray.withAlphaComponent(0.6) 15 | } 16 | 17 | class IndexBarBubbleView: UIView { 18 | 19 | private var label: UILabel? 20 | private var configure: BubbleConfigure 21 | 22 | init(frame: CGRect, configure: BubbleConfigure) { 23 | self.configure = configure 24 | super.init(frame: frame) 25 | let label = UILabel.init(frame: bounds) 26 | label.textColor = self.configure.textColor 27 | label.font = self.configure.font 28 | label.textAlignment = .center 29 | backgroundColor = .clear 30 | addSubview(label) 31 | self.label = label 32 | } 33 | 34 | public func hide() { 35 | UIView.animate(withDuration: 0.2) { 36 | self.alpha = 0 37 | } 38 | } 39 | 40 | func show(_ title: String?, on position: CGPoint) { 41 | label?.text = title 42 | center = position 43 | if alpha == 0 { 44 | alpha = 1 45 | } 46 | } 47 | 48 | required init?(coder: NSCoder) { 49 | fatalError("init(coder:) has not been implemented") 50 | } 51 | 52 | override func draw(_ rect: CGRect) { 53 | let context = UIGraphicsGetCurrentContext() 54 | context?.setLineWidth(2.0) 55 | context?.setFillColor(configure.backgroundColor.cgColor) 56 | setDrawPath(context) 57 | context?.fillPath() 58 | } 59 | 60 | private func setDrawPath(_ context: CGContext?) { 61 | guard let context = context else {return} 62 | let width = bounds.width 63 | let height = bounds.height 64 | let x = width/4 65 | let y = height/4 66 | let radius = sqrt(pow(x, 2) + pow(y, 2)) 67 | 68 | //Draw triangle 69 | context.move(to: CGPoint(x: width - x, y: height * 0.5 - y)) 70 | context.addLine(to: CGPoint(x: width, y: height * 0.5)) 71 | context.addLine(to: CGPoint(x: width - x, y: height * 0.5 + y)) 72 | 73 | //Draw semicircle 74 | context.addArc(tangent1End: CGPoint(x: width * 0.5, y: height), tangent2End: CGPoint(x: width * 0.5 - x, y: height * 0.5 + y), radius: radius) 75 | context.addArc(tangent1End: CGPoint(x: 0, y: height * 0.5), tangent2End: CGPoint(x: width * 0.5 - x, y: height * 0.5 - y), radius: radius) 76 | context.addArc(tangent1End: CGPoint(x: width * 0.5, y: 0), tangent2End: CGPoint(x: width * 0.5 + x, y: height * 0.5 - y), radius: radius) 77 | context.closePath() 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /IndexBar@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rainedAllNight/IndexBar/a8c348075255ab175ea5fb41fa3ff6ec40341ce5/IndexBar@1x.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-present Artsy, Ash Furrow 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/rainedAllNight/IndexBar/blob/master/IndexBar%401x.png) 2 | 3 | ### A index bar for tableview with Swift 4 | 5 | ### 一个tableView的索引控件,UI仿照于微信联系人页面, 使用Swift编写 6 | 7 | 8 | ## Preview 9 | 10 | ![](https://github.com/rainedAllNight/IndexBar/blob/master/%E5%9B%BE%E5%83%8F.gif) 11 | 12 | ## Installation 13 | 14 | ### Cocoapods 15 | 16 | ```` 17 | 18 | pod 'IndexBar' 19 | 20 | ```` 21 | 22 | ### Platform & Swift version 23 | 24 | * **>= iOS 10.0** 25 | * **>= Swift 5.0** 26 | 27 | ## Usage 28 | 29 | ### you can init the IndexBar with frame or start with storyBoard&xib(代码初始化或者直接在storyboard中使用) 30 | 31 | ```` 32 | let indexBar = IndexBar(frame: CGRect(x: view.bounds.width - 24, y: 0, width: 40, height: view.bounds.height)) 33 | indexBar.configure = { configure in 34 | configure.sectionWH = 16 35 | configure.titleFont = UIFont.systemFont(ofSize: 12) 36 | configure.backgroundColorForSelected = UIColor.color(withHex: "#53ED7C") 37 | } 38 | indexBar.setData(sectionTitles, tableView: tableView) 39 | view.addSubview(indexBar) 40 | 41 | ```` 42 | 43 | ### IndexBar configure(相关配置项) 44 | 45 | ``` 46 | /// section normal title color 47 | public var titleColor: UIColor = .lightGray 48 | /// section title font 49 | public var titleFont: UIFont = UIFont.systemFont(ofSize: 10) 50 | /// section selected title color 51 | public var titleColorForSelected: UIColor = .white 52 | /// section selected background color 53 | public var backgroundColorForSelected: UIColor = .blue 54 | /// section width&height 55 | public var sectionWH: CGFloat = 16 56 | /// section vertical spacing 57 | public var sectionSpacing: CGFloat = 4 58 | /// show bubble view, default is true 59 | public var showBubble = true 60 | /// the configure of the bubble view 61 | public var bubbleConfigure = BubbleConfigure() 62 | 63 | 64 | ``` 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /图像.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rainedAllNight/IndexBar/a8c348075255ab175ea5fb41fa3ff6ec40341ce5/图像.gif --------------------------------------------------------------------------------