├── README.md ├── TCTitleLoading.podspec ├── TCTitleLoading.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── Travel.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── Travel.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── TCTitleLoading.xcscheme │ └── xcschememanagement.plist └── TCTitleLoading ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── first.imageset │ ├── Contents.json │ └── first.pdf └── second.imageset │ ├── Contents.json │ └── second.pdf ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── FirstViewController.h ├── FirstViewController.m ├── Info.plist ├── SecondViewController.h ├── SecondViewController.m ├── TCTitleLoading ├── TCTitleLoadingManager.h ├── TCTitleLoadingManager.m ├── TYDotIndicatorView.h ├── TYDotIndicatorView.m ├── UINavigationController+TCTitleLoading.h ├── UINavigationController+TCTitleLoading.m ├── UIViewController+TCTitleLoading.h └── UIViewController+TCTitleLoading.m └── main.m /README.md: -------------------------------------------------------------------------------- 1 | # TCTitleLoading 2 | This is a loading in the bottom of navigation bar title area. 3 | This project is inspired by [XHLoadingNavigationItemTitleView](https://github.com/JackTeam/XHLoadingNavigationItemTitleView) 4 | 5 | ![](http://7xpujh.com1.z0.glb.clouddn.com/static/images/tctitleloading.png) 6 | 7 | Change Log 8 | ========================== 9 | #### 0.0.4 10 | 1. Support device rotation. 11 | 12 | Installation 13 | ========================== 14 | 15 | #### Cocoapod Method:- 16 | 17 | `pod 'TCTitleLoading'` 18 | 19 | #### Source Code Method:- 20 | Add files in folder TCTitleLoading to your project. 21 | 22 | ##How To Get Started 23 | 24 | 1. In your Appdelegate.m, import TCTitleLoadingManager and set custom color, you can skip this step if you want to use the default black color: 25 | 26 | ``` 27 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 28 | // Override point for customization after application launch. 29 | 30 | //Set custom color for dots 31 | [TCTitleLoadingManager setDotColor:[UIColor orangeColor]]; 32 | return YES; 33 | } 34 | ``` 35 | 36 | 2.Start the loading by calling method startAnimationTitle in your view controller: 37 | 38 | ``` 39 | [self startAnimationTitle]; 40 | ``` 41 | 42 | 3.Start the loading by calling method startAnimationTitle in your view controller: 43 | 44 | ``` 45 | [self stopAnimationTitle]; 46 | ``` 47 | 4.If you want to skip the title loading for some pages, just tell the manager: 48 | 49 | ``` 50 | [TCTitleLoadingManager SkipTitleLoadingForClass:[self class]]; 51 | ``` 52 | 53 | Thanks 54 | --- 55 | This project is inspired by [XHLoadingNavigationItemTitleView](https://github.com/JackTeam/XHLoadingNavigationItemTitleView). 56 | The dot loading view is [TYDotIndicatorView](https://github.com/itouch2/TYDotIndicatorView) 57 | 58 | LICENSE 59 | --- 60 | Distributed under the MIT License. 61 | 62 | Author 63 | --- 64 | If you wish to contact me, email at: chuchuanming@gmail.com 65 | 66 | Blog 67 | --- 68 | [http://travelchu.com](http://travelchu.com) -------------------------------------------------------------------------------- /TCTitleLoading.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "TCTitleLoading" 4 | s.version = "0.0.3" 5 | s.summary = "This is a loading in the bottom of navigation bar title area." 6 | 7 | s.description = <<-DESC 8 | Make you navigationbar has a loading view under title. You can custom the loading dots color and appoint which page to skip. 9 | DESC 10 | 11 | s.homepage = "https://github.com/TravelC/TCTitleLoading" 12 | s.screenshots = "http://travelchu.com/ImagesForProjects/TCTitleLoading.png" 13 | 14 | s.license = "MIT" 15 | 16 | s.author = { "Travel.Chu" => "chuchuanming@gmail.com" } 17 | s.social_media_url = "https://www.facebook.com/chuanming.chu" 18 | 19 | s.platform = :ios, "5.0" 20 | 21 | s.source = { :git => "https://github.com/TravelC/TCTitleLoading.git", :tag => "0.0.3" } 22 | 23 | s.source_files = "TCTitleLoading/TCTitleLoading/**/*.{h,m}" 24 | s.public_header_files = "TCTitleLoading/TCTitleLoading/**/*.h" 25 | 26 | s.frameworks = "Foundation", "UIKit" 27 | 28 | 29 | s.requires_arc = true 30 | 31 | end 32 | -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | ED05CB2D1C02F4B000FA8CC7 /* TYDotIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = ED05CB2A1C02F4B000FA8CC7 /* TYDotIndicatorView.m */; }; 11 | ED05CB311C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.m in Sources */ = {isa = PBXBuildFile; fileRef = ED05CB301C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.m */; }; 12 | ED05CB341C02F5A600FA8CC7 /* TCTitleLoadingManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ED05CB331C02F5A600FA8CC7 /* TCTitleLoadingManager.m */; }; 13 | ED5B90561C02F12600C491F8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = ED5B90551C02F12600C491F8 /* main.m */; }; 14 | ED5B90591C02F12600C491F8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = ED5B90581C02F12600C491F8 /* AppDelegate.m */; }; 15 | ED5B905C1C02F12600C491F8 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED5B905B1C02F12600C491F8 /* FirstViewController.m */; }; 16 | ED5B905F1C02F12600C491F8 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ED5B905E1C02F12600C491F8 /* SecondViewController.m */; }; 17 | ED5B90621C02F12600C491F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ED5B90601C02F12600C491F8 /* Main.storyboard */; }; 18 | ED5B90641C02F12600C491F8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = ED5B90631C02F12600C491F8 /* Assets.xcassets */; }; 19 | ED5B90671C02F12600C491F8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = ED5B90651C02F12600C491F8 /* LaunchScreen.storyboard */; }; 20 | ED9DCED51C1E8EC800718C43 /* UINavigationController+TCTitleLoading.m in Sources */ = {isa = PBXBuildFile; fileRef = ED9DCED41C1E8EC800718C43 /* UINavigationController+TCTitleLoading.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | ED05CB291C02F4B000FA8CC7 /* TYDotIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TYDotIndicatorView.h; sourceTree = ""; }; 25 | ED05CB2A1C02F4B000FA8CC7 /* TYDotIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TYDotIndicatorView.m; sourceTree = ""; }; 26 | ED05CB2F1C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+TCTitleLoading.h"; sourceTree = ""; }; 27 | ED05CB301C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+TCTitleLoading.m"; sourceTree = ""; }; 28 | ED05CB321C02F5A600FA8CC7 /* TCTitleLoadingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCTitleLoadingManager.h; sourceTree = ""; }; 29 | ED05CB331C02F5A600FA8CC7 /* TCTitleLoadingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TCTitleLoadingManager.m; sourceTree = ""; }; 30 | ED5B90511C02F12600C491F8 /* TCTitleLoading.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TCTitleLoading.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | ED5B90551C02F12600C491F8 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | ED5B90571C02F12600C491F8 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | ED5B90581C02F12600C491F8 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 34 | ED5B905A1C02F12600C491F8 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; 35 | ED5B905B1C02F12600C491F8 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; 36 | ED5B905D1C02F12600C491F8 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 37 | ED5B905E1C02F12600C491F8 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 38 | ED5B90611C02F12600C491F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 39 | ED5B90631C02F12600C491F8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 40 | ED5B90661C02F12600C491F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 41 | ED5B90681C02F12600C491F8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 42 | ED9DCED31C1E8EC800718C43 /* UINavigationController+TCTitleLoading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+TCTitleLoading.h"; sourceTree = ""; }; 43 | ED9DCED41C1E8EC800718C43 /* UINavigationController+TCTitleLoading.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+TCTitleLoading.m"; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | ED5B904E1C02F12500C491F8 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | ); 52 | runOnlyForDeploymentPostprocessing = 0; 53 | }; 54 | /* End PBXFrameworksBuildPhase section */ 55 | 56 | /* Begin PBXGroup section */ 57 | ED05CB281C02F4B000FA8CC7 /* TCTitleLoading */ = { 58 | isa = PBXGroup; 59 | children = ( 60 | ED05CB291C02F4B000FA8CC7 /* TYDotIndicatorView.h */, 61 | ED05CB2A1C02F4B000FA8CC7 /* TYDotIndicatorView.m */, 62 | ED05CB2F1C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.h */, 63 | ED05CB301C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.m */, 64 | ED9DCED31C1E8EC800718C43 /* UINavigationController+TCTitleLoading.h */, 65 | ED9DCED41C1E8EC800718C43 /* UINavigationController+TCTitleLoading.m */, 66 | ED05CB321C02F5A600FA8CC7 /* TCTitleLoadingManager.h */, 67 | ED05CB331C02F5A600FA8CC7 /* TCTitleLoadingManager.m */, 68 | ); 69 | path = TCTitleLoading; 70 | sourceTree = ""; 71 | }; 72 | ED5B90481C02F12500C491F8 = { 73 | isa = PBXGroup; 74 | children = ( 75 | ED5B90531C02F12600C491F8 /* TCTitleLoading */, 76 | ED5B90521C02F12600C491F8 /* Products */, 77 | ); 78 | sourceTree = ""; 79 | }; 80 | ED5B90521C02F12600C491F8 /* Products */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | ED5B90511C02F12600C491F8 /* TCTitleLoading.app */, 84 | ); 85 | name = Products; 86 | sourceTree = ""; 87 | }; 88 | ED5B90531C02F12600C491F8 /* TCTitleLoading */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | ED5B90571C02F12600C491F8 /* AppDelegate.h */, 92 | ED5B90581C02F12600C491F8 /* AppDelegate.m */, 93 | ED5B90601C02F12600C491F8 /* Main.storyboard */, 94 | ED05CB281C02F4B000FA8CC7 /* TCTitleLoading */, 95 | ED5B905A1C02F12600C491F8 /* FirstViewController.h */, 96 | ED5B905B1C02F12600C491F8 /* FirstViewController.m */, 97 | ED5B905D1C02F12600C491F8 /* SecondViewController.h */, 98 | ED5B905E1C02F12600C491F8 /* SecondViewController.m */, 99 | ED5B90631C02F12600C491F8 /* Assets.xcassets */, 100 | ED5B90651C02F12600C491F8 /* LaunchScreen.storyboard */, 101 | ED5B90681C02F12600C491F8 /* Info.plist */, 102 | ED5B90541C02F12600C491F8 /* Supporting Files */, 103 | ); 104 | path = TCTitleLoading; 105 | sourceTree = ""; 106 | }; 107 | ED5B90541C02F12600C491F8 /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | ED5B90551C02F12600C491F8 /* main.m */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXNativeTarget section */ 118 | ED5B90501C02F12500C491F8 /* TCTitleLoading */ = { 119 | isa = PBXNativeTarget; 120 | buildConfigurationList = ED5B906B1C02F12600C491F8 /* Build configuration list for PBXNativeTarget "TCTitleLoading" */; 121 | buildPhases = ( 122 | ED5B904D1C02F12500C491F8 /* Sources */, 123 | ED5B904E1C02F12500C491F8 /* Frameworks */, 124 | ED5B904F1C02F12500C491F8 /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = TCTitleLoading; 131 | productName = TCTitleLoading; 132 | productReference = ED5B90511C02F12600C491F8 /* TCTitleLoading.app */; 133 | productType = "com.apple.product-type.application"; 134 | }; 135 | /* End PBXNativeTarget section */ 136 | 137 | /* Begin PBXProject section */ 138 | ED5B90491C02F12500C491F8 /* Project object */ = { 139 | isa = PBXProject; 140 | attributes = { 141 | LastUpgradeCheck = 0710; 142 | ORGANIZATIONNAME = TravelChu; 143 | TargetAttributes = { 144 | ED5B90501C02F12500C491F8 = { 145 | CreatedOnToolsVersion = 7.1.1; 146 | }; 147 | }; 148 | }; 149 | buildConfigurationList = ED5B904C1C02F12500C491F8 /* Build configuration list for PBXProject "TCTitleLoading" */; 150 | compatibilityVersion = "Xcode 3.2"; 151 | developmentRegion = English; 152 | hasScannedForEncodings = 0; 153 | knownRegions = ( 154 | en, 155 | Base, 156 | ); 157 | mainGroup = ED5B90481C02F12500C491F8; 158 | productRefGroup = ED5B90521C02F12600C491F8 /* Products */; 159 | projectDirPath = ""; 160 | projectRoot = ""; 161 | targets = ( 162 | ED5B90501C02F12500C491F8 /* TCTitleLoading */, 163 | ); 164 | }; 165 | /* End PBXProject section */ 166 | 167 | /* Begin PBXResourcesBuildPhase section */ 168 | ED5B904F1C02F12500C491F8 /* Resources */ = { 169 | isa = PBXResourcesBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | ED5B90671C02F12600C491F8 /* LaunchScreen.storyboard in Resources */, 173 | ED5B90641C02F12600C491F8 /* Assets.xcassets in Resources */, 174 | ED5B90621C02F12600C491F8 /* Main.storyboard in Resources */, 175 | ); 176 | runOnlyForDeploymentPostprocessing = 0; 177 | }; 178 | /* End PBXResourcesBuildPhase section */ 179 | 180 | /* Begin PBXSourcesBuildPhase section */ 181 | ED5B904D1C02F12500C491F8 /* Sources */ = { 182 | isa = PBXSourcesBuildPhase; 183 | buildActionMask = 2147483647; 184 | files = ( 185 | ED5B905F1C02F12600C491F8 /* SecondViewController.m in Sources */, 186 | ED05CB311C02F4E300FA8CC7 /* UIViewController+TCTitleLoading.m in Sources */, 187 | ED05CB341C02F5A600FA8CC7 /* TCTitleLoadingManager.m in Sources */, 188 | ED5B90591C02F12600C491F8 /* AppDelegate.m in Sources */, 189 | ED5B905C1C02F12600C491F8 /* FirstViewController.m in Sources */, 190 | ED05CB2D1C02F4B000FA8CC7 /* TYDotIndicatorView.m in Sources */, 191 | ED9DCED51C1E8EC800718C43 /* UINavigationController+TCTitleLoading.m in Sources */, 192 | ED5B90561C02F12600C491F8 /* main.m in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin PBXVariantGroup section */ 199 | ED5B90601C02F12600C491F8 /* Main.storyboard */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | ED5B90611C02F12600C491F8 /* Base */, 203 | ); 204 | name = Main.storyboard; 205 | sourceTree = ""; 206 | }; 207 | ED5B90651C02F12600C491F8 /* LaunchScreen.storyboard */ = { 208 | isa = PBXVariantGroup; 209 | children = ( 210 | ED5B90661C02F12600C491F8 /* Base */, 211 | ); 212 | name = LaunchScreen.storyboard; 213 | sourceTree = ""; 214 | }; 215 | /* End PBXVariantGroup section */ 216 | 217 | /* Begin XCBuildConfiguration section */ 218 | ED5B90691C02F12600C491F8 /* Debug */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_MODULES = YES; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_CONSTANT_CONVERSION = YES; 228 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INT_CONVERSION = YES; 232 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 233 | CLANG_WARN_UNREACHABLE_CODE = YES; 234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 235 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 236 | COPY_PHASE_STRIP = NO; 237 | DEBUG_INFORMATION_FORMAT = dwarf; 238 | ENABLE_STRICT_OBJC_MSGSEND = YES; 239 | ENABLE_TESTABILITY = YES; 240 | GCC_C_LANGUAGE_STANDARD = gnu99; 241 | GCC_DYNAMIC_NO_PIC = NO; 242 | GCC_NO_COMMON_BLOCKS = YES; 243 | GCC_OPTIMIZATION_LEVEL = 0; 244 | GCC_PREPROCESSOR_DEFINITIONS = ( 245 | "DEBUG=1", 246 | "$(inherited)", 247 | ); 248 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 249 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 250 | GCC_WARN_UNDECLARED_SELECTOR = YES; 251 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 252 | GCC_WARN_UNUSED_FUNCTION = YES; 253 | GCC_WARN_UNUSED_VARIABLE = YES; 254 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 255 | MTL_ENABLE_DEBUG_INFO = YES; 256 | ONLY_ACTIVE_ARCH = YES; 257 | SDKROOT = iphoneos; 258 | }; 259 | name = Debug; 260 | }; 261 | ED5B906A1C02F12600C491F8 /* Release */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ALWAYS_SEARCH_USER_PATHS = NO; 265 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 266 | CLANG_CXX_LIBRARY = "libc++"; 267 | CLANG_ENABLE_MODULES = YES; 268 | CLANG_ENABLE_OBJC_ARC = YES; 269 | CLANG_WARN_BOOL_CONVERSION = YES; 270 | CLANG_WARN_CONSTANT_CONVERSION = YES; 271 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 272 | CLANG_WARN_EMPTY_BODY = YES; 273 | CLANG_WARN_ENUM_CONVERSION = YES; 274 | CLANG_WARN_INT_CONVERSION = YES; 275 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 276 | CLANG_WARN_UNREACHABLE_CODE = YES; 277 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 278 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 279 | COPY_PHASE_STRIP = NO; 280 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 281 | ENABLE_NS_ASSERTIONS = NO; 282 | ENABLE_STRICT_OBJC_MSGSEND = YES; 283 | GCC_C_LANGUAGE_STANDARD = gnu99; 284 | GCC_NO_COMMON_BLOCKS = YES; 285 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 286 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 287 | GCC_WARN_UNDECLARED_SELECTOR = YES; 288 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 289 | GCC_WARN_UNUSED_FUNCTION = YES; 290 | GCC_WARN_UNUSED_VARIABLE = YES; 291 | IPHONEOS_DEPLOYMENT_TARGET = 9.1; 292 | MTL_ENABLE_DEBUG_INFO = NO; 293 | SDKROOT = iphoneos; 294 | VALIDATE_PRODUCT = YES; 295 | }; 296 | name = Release; 297 | }; 298 | ED5B906C1C02F12600C491F8 /* Debug */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 302 | INFOPLIST_FILE = TCTitleLoading/Info.plist; 303 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 304 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 305 | PRODUCT_BUNDLE_IDENTIFIER = com.travelchu.TCTitleLoading; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | TARGETED_DEVICE_FAMILY = "1,2"; 308 | }; 309 | name = Debug; 310 | }; 311 | ED5B906D1C02F12600C491F8 /* Release */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 315 | INFOPLIST_FILE = TCTitleLoading/Info.plist; 316 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 317 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 318 | PRODUCT_BUNDLE_IDENTIFIER = com.travelchu.TCTitleLoading; 319 | PRODUCT_NAME = "$(TARGET_NAME)"; 320 | TARGETED_DEVICE_FAMILY = "1,2"; 321 | }; 322 | name = Release; 323 | }; 324 | /* End XCBuildConfiguration section */ 325 | 326 | /* Begin XCConfigurationList section */ 327 | ED5B904C1C02F12500C491F8 /* Build configuration list for PBXProject "TCTitleLoading" */ = { 328 | isa = XCConfigurationList; 329 | buildConfigurations = ( 330 | ED5B90691C02F12600C491F8 /* Debug */, 331 | ED5B906A1C02F12600C491F8 /* Release */, 332 | ); 333 | defaultConfigurationIsVisible = 0; 334 | defaultConfigurationName = Release; 335 | }; 336 | ED5B906B1C02F12600C491F8 /* Build configuration list for PBXNativeTarget "TCTitleLoading" */ = { 337 | isa = XCConfigurationList; 338 | buildConfigurations = ( 339 | ED5B906C1C02F12600C491F8 /* Debug */, 340 | ED5B906D1C02F12600C491F8 /* Release */, 341 | ); 342 | defaultConfigurationIsVisible = 0; 343 | defaultConfigurationName = Release; 344 | }; 345 | /* End XCConfigurationList section */ 346 | }; 347 | rootObject = ED5B90491C02F12500C491F8 /* Project object */; 348 | } 349 | -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/project.xcworkspace/xcuserdata/Travel.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TravelC/TCTitleLoading/89fa907f14162bb310b47c3a82be5262511bd0ad/TCTitleLoading.xcodeproj/project.xcworkspace/xcuserdata/Travel.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/xcuserdata/Travel.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/xcuserdata/Travel.xcuserdatad/xcschemes/TCTitleLoading.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /TCTitleLoading.xcodeproj/xcuserdata/Travel.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TCTitleLoading.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | ED5B90501C02F12500C491F8 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /TCTitleLoading/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. 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 | -------------------------------------------------------------------------------- /TCTitleLoading/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "TCTitleLoadingManager.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | //Set custom color for dots 23 | [TCTitleLoadingManager setDotColor:[UIColor orangeColor]]; 24 | //iOS特殊编程姿势,哈哈哈哈 25 | 26 | 27 | return YES; 28 | } 29 | 30 | - (void)applicationWillResignActive:(UIApplication *)application { 31 | // 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. 32 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | } 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | - (void)applicationWillEnterForeground:(UIApplication *)application { 41 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 42 | } 43 | 44 | - (void)applicationDidBecomeActive:(UIApplication *)application { 45 | // 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. 46 | } 47 | 48 | - (void)applicationWillTerminate:(UIApplication *)application { 49 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /TCTitleLoading/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 | } -------------------------------------------------------------------------------- /TCTitleLoading/Assets.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "first.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /TCTitleLoading/Assets.xcassets/first.imageset/first.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TravelC/TCTitleLoading/89fa907f14162bb310b47c3a82be5262511bd0ad/TCTitleLoading/Assets.xcassets/first.imageset/first.pdf -------------------------------------------------------------------------------- /TCTitleLoading/Assets.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "second.pdf" 6 | } 7 | ], 8 | "info" : { 9 | "version" : 1, 10 | "author" : "xcode" 11 | } 12 | } -------------------------------------------------------------------------------- /TCTitleLoading/Assets.xcassets/second.imageset/second.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TravelC/TCTitleLoading/89fa907f14162bb310b47c3a82be5262511bd0ad/TCTitleLoading/Assets.xcassets/second.imageset/second.pdf -------------------------------------------------------------------------------- /TCTitleLoading/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 | -------------------------------------------------------------------------------- /TCTitleLoading/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 28 | 35 | 46 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 98 | 108 | 119 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /TCTitleLoading/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FirstViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /TCTitleLoading/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | #import "UIViewController+TCTitleLoading.h" 11 | 12 | @interface FirstViewController () 13 | 14 | @end 15 | 16 | @implementation FirstViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | 29 | - (IBAction)startLoading:(id)sender { 30 | [self startAnimationTitle]; 31 | } 32 | 33 | - (IBAction)stopLoading:(id)sender { 34 | [self stopAnimationTitle]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /TCTitleLoading/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 | 0.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarTintParameters 34 | 35 | UINavigationBar 36 | 37 | Style 38 | UIBarStyleDefault 39 | Translucent 40 | 41 | 42 | 43 | UISupportedInterfaceOrientations 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /TCTitleLoading/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SecondViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /TCTitleLoading/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | #import "UIViewController+TCTitleLoading.h" 11 | #import "TCTitleLoadingManager.h" 12 | 13 | @interface SecondViewController () 14 | @property (weak, nonatomic) IBOutlet UIActivityIndicatorView *loadingView; 15 | 16 | @end 17 | 18 | @implementation SecondViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | // Skip title loading for this page 23 | [TCTitleLoadingManager skipTitleLoadingForClass:[self class]]; 24 | } 25 | 26 | - (void)didReceiveMemoryWarning { 27 | [super didReceiveMemoryWarning]; 28 | // Dispose of any resources that can be recreated. 29 | } 30 | 31 | - (IBAction)startLoading:(id)sender { 32 | [self startAnimationTitle]; 33 | [self.loadingView startAnimating]; 34 | } 35 | 36 | - (IBAction)stopLoading:(id)sender { 37 | [self stopAnimationTitle]; 38 | [self.loadingView stopAnimating]; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/TCTitleLoadingManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // TCTitleLoadingManager.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface TCTitleLoadingManager : NSObject 13 | 14 | /** 15 | * Add the class to the skip list 16 | * 17 | * @param classToSkip the class to skip title loading 18 | */ 19 | + (void)skipTitleLoadingForClass:(nonnull Class)classToSkip; 20 | 21 | /** 22 | * Check is the class is in the skip list 23 | * 24 | * @param aClass the class to check 25 | * 26 | * @return Yes for in the list, no for the opposite 27 | */ 28 | + (BOOL)shouldSkipForClass:(nonnull Class)aClass; 29 | 30 | /** 31 | * Set custom color for dots default is black color 32 | * 33 | * @param dotColor custom color for dots 34 | */ 35 | + (void)setDotColor:(nullable UIColor*)dotColor; 36 | 37 | /** 38 | * Get current dot color 39 | * 40 | * @return current dot color 41 | */ 42 | + (nonnull UIColor*)dotColorForLoadingDot; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/TCTitleLoadingManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // TCTitleLoadingManager.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "TCTitleLoadingManager.h" 10 | 11 | @interface TCTitleLoadingManager () 12 | @property (nonatomic, strong) NSMutableSet *skipSet; 13 | @property (nonatomic, strong) UIColor *dotColor; 14 | @end 15 | 16 | @implementation TCTitleLoadingManager 17 | 18 | + (TCTitleLoadingManager *)manager { 19 | static dispatch_once_t once; 20 | static TCTitleLoadingManager *sharedInstance; 21 | dispatch_once(&once, ^{ 22 | sharedInstance = [[self alloc] init]; 23 | }); 24 | 25 | return sharedInstance; 26 | } 27 | 28 | + (void)skipTitleLoadingForClass:(nonnull Class)classToSkip { 29 | if (![TCTitleLoadingManager manager].skipSet) { 30 | [TCTitleLoadingManager manager].skipSet = [NSMutableSet set]; 31 | } 32 | [[TCTitleLoadingManager manager].skipSet addObject:classToSkip]; 33 | } 34 | + (BOOL)shouldSkipForClass:(nonnull Class)aClass { 35 | if ([[TCTitleLoadingManager manager].skipSet containsObject:aClass]) { 36 | return YES; 37 | } 38 | return NO; 39 | } 40 | 41 | + (void)setDotColor:(nullable UIColor *)dotColor{ 42 | if (dotColor) { 43 | [TCTitleLoadingManager manager].dotColor = dotColor; 44 | } 45 | } 46 | 47 | + (UIColor*)dotColorForLoadingDot{ 48 | if ([TCTitleLoadingManager manager].dotColor) { 49 | return [TCTitleLoadingManager manager].dotColor; 50 | } 51 | return [UIColor blackColor]; 52 | } 53 | @end 54 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/TYDotIndicatorView.h: -------------------------------------------------------------------------------- 1 | // 2 | // TYDotIndicatorView.h 3 | // TYDotIndicatorView 4 | // 5 | // Created by Tu You on 14-1-12. 6 | // Copyright (c) 2014年 Tu You. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM (NSInteger, TYDotIndicatorViewStyle){ 12 | TYDotIndicatorViewStyleSquare, 13 | TYDotIndicatorViewStyleRound, 14 | TYDotIndicatorViewStyleCircle 15 | }; 16 | @protocol TYDotIndicatorViewDelegate 17 | 18 | @required 19 | - (void)tcUpdateFrame; 20 | 21 | @end 22 | 23 | @interface TYDotIndicatorView : UIView 24 | 25 | @property (nonatomic, assign) BOOL hidesWhenStopped; 26 | @property (nonatomic, weak) id delegate; 27 | 28 | - (id)initWithFrame:(CGRect)frame 29 | dotStyle:(TYDotIndicatorViewStyle)style 30 | dotColor:(UIColor *)dotColor 31 | dotSize:(CGSize)dotSize; 32 | 33 | - (void)startAnimating; 34 | - (void)stopAnimating; 35 | - (BOOL)isAnimating; 36 | 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/TYDotIndicatorView.m: -------------------------------------------------------------------------------- 1 | // 2 | // TYDotIndicatorView.m 3 | // TYDotIndicatorView 4 | // 5 | // Created by Tu You on 14-1-12. 6 | // Copyright (c) 2014年 Tu You. All rights reserved. 7 | // 8 | 9 | #import "TYDotIndicatorView.h" 10 | 11 | static const NSUInteger dotNumber = 3; 12 | static const CGFloat dotSeparatorDistance = 12.0f; 13 | 14 | @interface TYDotIndicatorView () 15 | 16 | @property (nonatomic, assign) TYDotIndicatorViewStyle dotStyle; 17 | @property (nonatomic, assign) CGSize dotSize; 18 | @property (nonatomic, retain) NSMutableArray *dots; 19 | @property (nonatomic, assign) BOOL animating; 20 | 21 | @end 22 | 23 | @implementation TYDotIndicatorView 24 | 25 | - (void)dealloc { 26 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 27 | } 28 | 29 | #pragma mark - 30 | - (void)deviceOrientationDidChanged { 31 | if (self.delegate && [self.delegate respondsToSelector:@selector(tcUpdateFrame)]) { 32 | [self.delegate tcUpdateFrame]; 33 | } 34 | } 35 | 36 | #pragma mark - 37 | - (id)initWithFrame:(CGRect)frame 38 | dotStyle:(TYDotIndicatorViewStyle)style 39 | dotColor:(UIColor *)dotColor 40 | dotSize:(CGSize)dotSize { 41 | self = [super initWithFrame:frame]; 42 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChanged) name:UIDeviceOrientationDidChangeNotification object:nil]; 43 | if (self) { 44 | self.alpha = 0.0; 45 | _dotStyle = style; 46 | _dotSize = dotSize; 47 | _hidesWhenStopped = YES; 48 | 49 | _dots = [[NSMutableArray alloc] init]; 50 | 51 | CGFloat xPos = CGRectGetWidth(frame) / 2 - dotSize.width * 3 / 2 - dotSeparatorDistance; 52 | CGFloat yPos = CGRectGetHeight(frame) / 2 - _dotSize.height / 2; 53 | 54 | for (int i = 0; i < dotNumber; i++) { 55 | CAShapeLayer *dot = [CAShapeLayer new]; 56 | dot.path = [self createDotPath].CGPath; 57 | dot.frame = CGRectMake(xPos, yPos, _dotSize.width, _dotSize.height); 58 | dot.opacity = 0.3 * i; 59 | dot.fillColor = dotColor.CGColor; 60 | 61 | [self.layer addSublayer:dot]; 62 | 63 | [_dots addObject:dot]; 64 | 65 | xPos = xPos + (dotSeparatorDistance + _dotSize.width); 66 | } 67 | 68 | } 69 | return self; 70 | } 71 | 72 | - (UIBezierPath *)createDotPath { 73 | CGFloat cornerRadius = 0.0f; 74 | if (_dotStyle == TYDotIndicatorViewStyleSquare) { 75 | cornerRadius = 0.0f; 76 | } else if (_dotStyle == TYDotIndicatorViewStyleRound) { 77 | cornerRadius = 2; 78 | } else if (_dotStyle == TYDotIndicatorViewStyleCircle) { 79 | cornerRadius = self.dotSize.width / 2; 80 | } 81 | 82 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height) cornerRadius:cornerRadius]; 83 | 84 | return bezierPath; 85 | } 86 | 87 | - (CAAnimation *)fadeInAnimation:(CFTimeInterval)delay { 88 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 89 | animation.fromValue = @(0.3f); 90 | animation.toValue = @(1.0f); 91 | animation.duration = 0.5f; 92 | animation.beginTime = CACurrentMediaTime() + delay; 93 | animation.autoreverses = YES; 94 | animation.repeatCount = HUGE_VAL; 95 | return animation; 96 | } 97 | 98 | - (void)startAnimating { 99 | if (_animating) { 100 | return; 101 | } 102 | [UIView animateWithDuration:0.1 animations:^{ 103 | self.alpha = 1.0; 104 | }]; 105 | 106 | for (int i = 0; i < _dots.count; i++) { 107 | [_dots[i] addAnimation:[self fadeInAnimation:i * 0.25] forKey:@"fadeIn"]; 108 | } 109 | 110 | _animating = YES; 111 | } 112 | 113 | - (void)stopAnimating { 114 | if (!_animating) { 115 | if (self.alpha > 10e-5) { 116 | self.alpha = 0.0; 117 | } 118 | return; 119 | } 120 | 121 | // fade in to disappear 122 | [UIView animateWithDuration:0.2 animations:^{ 123 | self.alpha = 0.; 124 | } completion:NULL]; 125 | 126 | for (int i = 0; i < _dots.count; i++) { 127 | [_dots[i] addAnimation:[self fadeInAnimation:i * 0.25] forKey:@"fadeIn"]; 128 | } 129 | 130 | _animating = NO; 131 | if (_hidesWhenStopped) { 132 | // fade in to disappear 133 | [UIView animateWithDuration:0.2 animations:^{ 134 | self.alpha = 0.0f; 135 | } completion:^(BOOL finished) { 136 | [self removeFromSuperview]; 137 | }]; 138 | } 139 | } 140 | 141 | - (BOOL)isAnimating { 142 | return _animating; 143 | } 144 | 145 | - (void)removeFromSuperview { 146 | [self stopAnimating]; 147 | 148 | [super removeFromSuperview]; 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/UINavigationController+TCTitleLoading.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+TCTitleLoading.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/12/14. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TYDotIndicatorView.h" 11 | 12 | @interface UINavigationController (TCTitleLoading) 13 | @property (nonatomic, strong) TYDotIndicatorView *tcIndicatorView; 14 | @end 15 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/UINavigationController+TCTitleLoading.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationController+TCTitleLoading.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/12/14. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "UINavigationController+TCTitleLoading.h" 10 | #import 11 | 12 | static NSString * const kTCTYDotIndicatorViewKey = @"kTCTYDotIndicatorViewKey"; 13 | 14 | @implementation UINavigationController (TCTitleLoading) 15 | - (void)setTcIndicatorView:(TYDotIndicatorView *)tcIndicatorView { 16 | objc_setAssociatedObject(self, &kTCTYDotIndicatorViewKey, tcIndicatorView, OBJC_ASSOCIATION_RETAIN); 17 | } 18 | 19 | - (TYDotIndicatorView *)tcIndicatorView { 20 | return objc_getAssociatedObject(self, &kTCTYDotIndicatorViewKey); 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/UIViewController+TCTitleLoading.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TCTitleLoading.h 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "TYDotIndicatorView.h" 11 | 12 | @interface UIViewController (TCTitleLoading) 13 | 14 | /** 15 | * Start the loading animation 16 | */ 17 | - (void)startAnimationTitle; 18 | /** 19 | * Stop the loading animation 20 | */ 21 | - (void)stopAnimationTitle; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /TCTitleLoading/TCTitleLoading/UIViewController+TCTitleLoading.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+TCTitleLoading.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+TCTitleLoading.h" 10 | #import "UINavigationController+TCTitleLoading.h" 11 | #import "TCTitleLoadingManager.h" 12 | 13 | static const CGFloat IndicatorViewHeight = 8.0f; 14 | @interface UIViewController () 15 | 16 | 17 | @end 18 | 19 | @implementation UIViewController (TCTitleLoading) 20 | 21 | - (CGRect)indicatorFrame { 22 | CGRect indicatorViewFrame = self.navigationController.navigationBar.bounds; 23 | indicatorViewFrame.size.height = IndicatorViewHeight; 24 | indicatorViewFrame.origin.y = CGRectGetHeight(self.navigationController.navigationBar.bounds)-IndicatorViewHeight-5.0; 25 | NSLog(@"%@", NSStringFromCGRect(indicatorViewFrame)); 26 | return indicatorViewFrame; 27 | } 28 | 29 | - (void)startAnimationTitle { 30 | if ([TCTitleLoadingManager shouldSkipForClass:[self class]]) { 31 | return; 32 | } 33 | if (!self.navigationController.tcIndicatorView) { 34 | 35 | self.navigationController.tcIndicatorView = [[TYDotIndicatorView alloc] initWithFrame:[self indicatorFrame] dotStyle:TYDotIndicatorViewStyleCircle dotColor:[TCTitleLoadingManager dotColorForLoadingDot] dotSize:CGSizeMake(7.0, 7.0)]; 36 | self.navigationController.tcIndicatorView.backgroundColor = [UIColor clearColor]; 37 | self.navigationController.tcIndicatorView.hidesWhenStopped = NO; 38 | [self.navigationController.navigationBar addSubview:self.navigationController.tcIndicatorView]; 39 | self.navigationController.tcIndicatorView.delegate = self; 40 | } 41 | [self.navigationController.navigationBar setTitleVerticalPositionAdjustment:-IndicatorViewHeight forBarMetrics:UIBarMetricsDefault]; 42 | [self.navigationController.tcIndicatorView startAnimating]; 43 | } 44 | 45 | - (void)stopAnimationTitle { 46 | if ([TCTitleLoadingManager shouldSkipForClass:[self class]]) { 47 | return; 48 | } 49 | [self.navigationController.tcIndicatorView stopAnimating]; 50 | [self.navigationController.navigationBar setTitleVerticalPositionAdjustment:0.0 forBarMetrics:UIBarMetricsDefault]; 51 | } 52 | 53 | #pragma mark - TYDotIndicatorViewDelegate 54 | - (void)tcUpdateFrame { 55 | BOOL isAnimating = NO; 56 | if (self.navigationController.tcIndicatorView) { 57 | isAnimating = self.navigationController.tcIndicatorView.isAnimating; 58 | [self.navigationController.tcIndicatorView removeFromSuperview]; 59 | self.navigationController.tcIndicatorView = nil; 60 | } 61 | if (isAnimating) { 62 | [self startAnimationTitle]; 63 | } 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /TCTitleLoading/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TCTitleLoading 4 | // 5 | // Created by Travel Chu on 15/11/23. 6 | // Copyright © 2015年 TravelChu. 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 | --------------------------------------------------------------------------------