├── OC.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── Study Manual For iOS.xccheckout │ └── xcuserdata │ │ └── apple.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── apple.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Study Manual For iOS.xcscheme │ └── xcschememanagement.plist ├── OC.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── apple.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── Podfile ├── Podfile.lock ├── Pods ├── Headers │ ├── Private │ │ ├── MBProgressHUD │ │ │ └── MBProgressHUD.h │ │ └── UITableView+FDTemplateLayoutCell │ │ │ └── UITableView+FDTemplateLayoutCell.h │ └── Public │ │ ├── MBProgressHUD │ │ └── MBProgressHUD.h │ │ └── UITableView+FDTemplateLayoutCell │ │ └── UITableView+FDTemplateLayoutCell.h ├── MBProgressHUD │ ├── LICENSE │ ├── MBProgressHUD.h │ ├── MBProgressHUD.m │ └── README.mdown ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── apple.xcuserdatad │ │ └── xcschemes │ │ ├── MBProgressHUD.xcscheme │ │ ├── Pods.xcscheme │ │ ├── UITableView+FDTemplateLayoutCell.xcscheme │ │ └── xcschememanagement.plist ├── Target Support Files │ ├── MBProgressHUD │ │ ├── MBProgressHUD-Private.xcconfig │ │ ├── MBProgressHUD-dummy.m │ │ ├── MBProgressHUD-prefix.pch │ │ └── MBProgressHUD.xcconfig │ ├── Pods │ │ ├── Pods-acknowledgements.markdown │ │ ├── Pods-acknowledgements.plist │ │ ├── Pods-dummy.m │ │ ├── Pods-resources.sh │ │ ├── Pods.debug.xcconfig │ │ └── Pods.release.xcconfig │ └── UITableView+FDTemplateLayoutCell │ │ ├── UITableView+FDTemplateLayoutCell-Private.xcconfig │ │ ├── UITableView+FDTemplateLayoutCell-dummy.m │ │ ├── UITableView+FDTemplateLayoutCell-prefix.pch │ │ └── UITableView+FDTemplateLayoutCell.xcconfig └── UITableView+FDTemplateLayoutCell │ ├── Classes │ ├── UITableView+FDTemplateLayoutCell.h │ └── UITableView+FDTemplateLayoutCell.m │ ├── LICENSE │ └── README.md ├── Study Manual For iOS ├── 1.png ├── 2.png ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── 1.png │ │ ├── Contents.json │ │ └── logo.png │ ├── Contents.json │ ├── LaunchImage.launchimage │ │ ├── 1.png │ │ ├── 2.png │ │ └── Contents.json │ ├── nav_backbtn.imageset │ │ ├── Contents.json │ │ └── nav_backbtn.png │ ├── tabbar_discover_selected.imageset │ │ ├── Contents.json │ │ └── tabbar_discover_selected@2x.png │ ├── tabbar_home.imageset │ │ ├── Contents.json │ │ └── tabbar_home@2x.png │ └── tabbar_profile_selected.imageset │ │ ├── Contents.json │ │ └── tabbar_profile_selected@2x.png ├── Info.plist ├── Main │ ├── Model │ │ ├── FDFeedCell.h │ │ ├── FDFeedCell.m │ │ ├── FDFeedEntity.h │ │ └── FDFeedEntity.m │ └── ViewController │ │ ├── DetailMainTableViewControlelr.h │ │ ├── DetailMainTableViewControlelr.m │ │ ├── FDFeedViewController.h │ │ ├── FDFeedViewController.m │ │ ├── MainViewController.h │ │ ├── MainViewController.m │ │ └── data.json ├── PrefixHeader.pch ├── SubItem │ ├── iOSBlog │ │ └── ViewController │ │ │ ├── iOSBlogPlist.plist │ │ │ ├── iOSBlogSearchResultsTableViewController.h │ │ │ ├── iOSBlogSearchResultsTableViewController.m │ │ │ ├── iOSBlogTableViewController.h │ │ │ ├── iOSBlogTableViewController.m │ │ │ ├── iOSBlogWebViewViewController.h │ │ │ └── iOSBlogWebViewViewController.m │ ├── iOSOpenSource │ │ ├── ViewController │ │ │ ├── SearchResultsTableViewController.h │ │ │ ├── SearchResultsTableViewController.m │ │ │ ├── iOSOpenSourceViewController.h │ │ │ ├── iOSOpenSourceViewController.m │ │ │ ├── iOSOpenSourceWebKitViewController.h │ │ │ └── iOSOpenSourceWebKitViewController.m │ │ └── iOSOpenSourcePlist.plist │ └── iOSWeiXin │ │ └── WeiXinHao.json ├── Util │ ├── GlobalResource │ │ ├── GlobalResource.h │ │ └── GlobalResource.m │ ├── Toast │ │ ├── Toast+UIView.h │ │ └── Toast+UIView.m │ └── WebKit │ │ ├── Reachability.h │ │ └── Reachability.m ├── logo.png └── main.m └── Study Manual For iOSTests ├── Info.plist └── Study_Manual_For_iOSTests.m /OC.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /OC.xcodeproj/project.xcworkspace/xcshareddata/Study Manual For iOS.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 77D77016-E1FE-43DF-BD67-770E07349B6F 9 | IDESourceControlProjectName 10 | Study Manual For iOS 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 519794BE62CB6B53CF16CA7042F8A5B5BB8D311C 14 | https://github.com/cnbin/iOSManual.git 15 | 16 | IDESourceControlProjectPath 17 | Study Manual For iOS.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 519794BE62CB6B53CF16CA7042F8A5B5BB8D311C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/cnbin/iOSManual.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 519794BE62CB6B53CF16CA7042F8A5B5BB8D311C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 519794BE62CB6B53CF16CA7042F8A5B5BB8D311C 36 | IDESourceControlWCCName 37 | Study%20Manual%20For%20iOS 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /OC.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/OC.xcodeproj/project.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /OC.xcodeproj/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /OC.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/Study Manual For iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 99 | 105 | 106 | 107 | 108 | 110 | 111 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /OC.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Study Manual For iOS.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 186B5FC41BA6790A002B2222 16 | 17 | primary 18 | 19 | 20 | 186B5FDD1BA6790A002B2222 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /OC.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OC.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/OC.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '8.1' 2 | pod 'MBProgressHUD', '~> 0.9.1' 3 | pod 'UITableView+FDTemplateLayoutCell', '~> 1.3' -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MBProgressHUD (0.9.1) 3 | - UITableView+FDTemplateLayoutCell (1.3) 4 | 5 | DEPENDENCIES: 6 | - MBProgressHUD (~> 0.9.1) 7 | - UITableView+FDTemplateLayoutCell (~> 1.3) 8 | 9 | SPEC CHECKSUMS: 10 | MBProgressHUD: c47f2c166c126cf2ce36498d80f33e754d4e93ad 11 | UITableView+FDTemplateLayoutCell: d5be6056b5060313f5955a2590ecd33142ad713d 12 | 13 | COCOAPODS: 0.38.2 14 | -------------------------------------------------------------------------------- /Pods/Headers/Private/MBProgressHUD/MBProgressHUD.h: -------------------------------------------------------------------------------- 1 | ../../../MBProgressHUD/MBProgressHUD.h -------------------------------------------------------------------------------- /Pods/Headers/Private/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.h: -------------------------------------------------------------------------------- 1 | ../../../UITableView+FDTemplateLayoutCell/Classes/UITableView+FDTemplateLayoutCell.h -------------------------------------------------------------------------------- /Pods/Headers/Public/MBProgressHUD/MBProgressHUD.h: -------------------------------------------------------------------------------- 1 | ../../../MBProgressHUD/MBProgressHUD.h -------------------------------------------------------------------------------- /Pods/Headers/Public/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.h: -------------------------------------------------------------------------------- 1 | ../../../UITableView+FDTemplateLayoutCell/Classes/UITableView+FDTemplateLayoutCell.h -------------------------------------------------------------------------------- /Pods/MBProgressHUD/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2015 Matej Bukovinski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Pods/MBProgressHUD/MBProgressHUD.h: -------------------------------------------------------------------------------- 1 | // 2 | // MBProgressHUD.h 3 | // Version 0.9.1 4 | // Created by Matej Bukovinski on 2.4.09. 5 | // 6 | 7 | // This code is distributed under the terms and conditions of the MIT license. 8 | 9 | // Copyright (c) 2009-2015 Matej Bukovinski 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import 30 | #import 31 | #import 32 | 33 | @protocol MBProgressHUDDelegate; 34 | 35 | 36 | typedef NS_ENUM(NSInteger, MBProgressHUDMode) { 37 | /** Progress is shown using an UIActivityIndicatorView. This is the default. */ 38 | MBProgressHUDModeIndeterminate, 39 | /** Progress is shown using a round, pie-chart like, progress view. */ 40 | MBProgressHUDModeDeterminate, 41 | /** Progress is shown using a horizontal progress bar */ 42 | MBProgressHUDModeDeterminateHorizontalBar, 43 | /** Progress is shown using a ring-shaped progress view. */ 44 | MBProgressHUDModeAnnularDeterminate, 45 | /** Shows a custom view */ 46 | MBProgressHUDModeCustomView, 47 | /** Shows only labels */ 48 | MBProgressHUDModeText 49 | }; 50 | 51 | typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) { 52 | /** Opacity animation */ 53 | MBProgressHUDAnimationFade, 54 | /** Opacity + scale animation */ 55 | MBProgressHUDAnimationZoom, 56 | MBProgressHUDAnimationZoomOut = MBProgressHUDAnimationZoom, 57 | MBProgressHUDAnimationZoomIn 58 | }; 59 | 60 | 61 | #ifndef MB_INSTANCETYPE 62 | #if __has_feature(objc_instancetype) 63 | #define MB_INSTANCETYPE instancetype 64 | #else 65 | #define MB_INSTANCETYPE id 66 | #endif 67 | #endif 68 | 69 | #ifndef MB_STRONG 70 | #if __has_feature(objc_arc) 71 | #define MB_STRONG strong 72 | #else 73 | #define MB_STRONG retain 74 | #endif 75 | #endif 76 | 77 | #ifndef MB_WEAK 78 | #if __has_feature(objc_arc_weak) 79 | #define MB_WEAK weak 80 | #elif __has_feature(objc_arc) 81 | #define MB_WEAK unsafe_unretained 82 | #else 83 | #define MB_WEAK assign 84 | #endif 85 | #endif 86 | 87 | #if NS_BLOCKS_AVAILABLE 88 | typedef void (^MBProgressHUDCompletionBlock)(); 89 | #endif 90 | 91 | 92 | /** 93 | * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. 94 | * 95 | * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class. 96 | * The MBProgressHUD window spans over the entire space given to it by the initWithFrame constructor and catches all 97 | * user input on this region, thereby preventing the user operations on components below the view. The HUD itself is 98 | * drawn centered as a rounded semi-transparent view which resizes depending on the user specified content. 99 | * 100 | * This view supports four modes of operation: 101 | * - MBProgressHUDModeIndeterminate - shows a UIActivityIndicatorView 102 | * - MBProgressHUDModeDeterminate - shows a custom round progress indicator 103 | * - MBProgressHUDModeAnnularDeterminate - shows a custom annular progress indicator 104 | * - MBProgressHUDModeCustomView - shows an arbitrary, user specified view (@see customView) 105 | * 106 | * All three modes can have optional labels assigned: 107 | * - If the labelText property is set and non-empty then a label containing the provided content is placed below the 108 | * indicator view. 109 | * - If also the detailsLabelText property is set then another label is placed below the first label. 110 | */ 111 | @interface MBProgressHUD : UIView 112 | 113 | /** 114 | * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. 115 | * 116 | * @param view The view that the HUD will be added to 117 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use 118 | * animations while appearing. 119 | * @return A reference to the created HUD. 120 | * 121 | * @see hideHUDForView:animated: 122 | * @see animationType 123 | */ 124 | + (MB_INSTANCETYPE)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; 125 | 126 | /** 127 | * Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:. 128 | * 129 | * @param view The view that is going to be searched for a HUD subview. 130 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 131 | * animations while disappearing. 132 | * @return YES if a HUD was found and removed, NO otherwise. 133 | * 134 | * @see showHUDAddedTo:animated: 135 | * @see animationType 136 | */ 137 | + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; 138 | 139 | /** 140 | * Finds all the HUD subviews and hides them. 141 | * 142 | * @param view The view that is going to be searched for HUD subviews. 143 | * @param animated If set to YES the HUDs will disappear using the current animationType. If set to NO the HUDs will not use 144 | * animations while disappearing. 145 | * @return the number of HUDs found and removed. 146 | * 147 | * @see hideHUDForView:animated: 148 | * @see animationType 149 | */ 150 | + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated; 151 | 152 | /** 153 | * Finds the top-most HUD subview and returns it. 154 | * 155 | * @param view The view that is going to be searched. 156 | * @return A reference to the last HUD subview discovered. 157 | */ 158 | + (MB_INSTANCETYPE)HUDForView:(UIView *)view; 159 | 160 | /** 161 | * Finds all HUD subviews and returns them. 162 | * 163 | * @param view The view that is going to be searched. 164 | * @return All found HUD views (array of MBProgressHUD objects). 165 | */ 166 | + (NSArray *)allHUDsForView:(UIView *)view; 167 | 168 | /** 169 | * A convenience constructor that initializes the HUD with the window's bounds. Calls the designated constructor with 170 | * window.bounds as the parameter. 171 | * 172 | * @param window The window instance that will provide the bounds for the HUD. Should be the same instance as 173 | * the HUD's superview (i.e., the window that the HUD will be added to). 174 | */ 175 | - (id)initWithWindow:(UIWindow *)window; 176 | 177 | /** 178 | * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with 179 | * view.bounds as the parameter 180 | * 181 | * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as 182 | * the HUD's superview (i.e., the view that the HUD will be added to). 183 | */ 184 | - (id)initWithView:(UIView *)view; 185 | 186 | /** 187 | * Display the HUD. You need to make sure that the main thread completes its run loop soon after this method call so 188 | * the user interface can be updated. Call this method when your task is already set-up to be executed in a new thread 189 | * (e.g., when using something like NSOperation or calling an asynchronous call like NSURLRequest). 190 | * 191 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use 192 | * animations while appearing. 193 | * 194 | * @see animationType 195 | */ 196 | - (void)show:(BOOL)animated; 197 | 198 | /** 199 | * Hide the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to 200 | * hide the HUD when your task completes. 201 | * 202 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 203 | * animations while disappearing. 204 | * 205 | * @see animationType 206 | */ 207 | - (void)hide:(BOOL)animated; 208 | 209 | /** 210 | * Hide the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to 211 | * hide the HUD when your task completes. 212 | * 213 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use 214 | * animations while disappearing. 215 | * @param delay Delay in seconds until the HUD is hidden. 216 | * 217 | * @see animationType 218 | */ 219 | - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay; 220 | 221 | /** 222 | * Shows the HUD while a background task is executing in a new thread, then hides the HUD. 223 | * 224 | * This method also takes care of autorelease pools so your method does not have to be concerned with setting up a 225 | * pool. 226 | * 227 | * @param method The method to be executed while the HUD is shown. This method will be executed in a new thread. 228 | * @param target The object that the target method belongs to. 229 | * @param object An optional object to be passed to the method. 230 | * @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will not use 231 | * animations while (dis)appearing. 232 | */ 233 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated; 234 | 235 | #if NS_BLOCKS_AVAILABLE 236 | 237 | /** 238 | * Shows the HUD while a block is executing on a background queue, then hides the HUD. 239 | * 240 | * @see showAnimated:whileExecutingBlock:onQueue:completionBlock: 241 | */ 242 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block; 243 | 244 | /** 245 | * Shows the HUD while a block is executing on a background queue, then hides the HUD. 246 | * 247 | * @see showAnimated:whileExecutingBlock:onQueue:completionBlock: 248 | */ 249 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(MBProgressHUDCompletionBlock)completion; 250 | 251 | /** 252 | * Shows the HUD while a block is executing on the specified dispatch queue, then hides the HUD. 253 | * 254 | * @see showAnimated:whileExecutingBlock:onQueue:completionBlock: 255 | */ 256 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue; 257 | 258 | /** 259 | * Shows the HUD while a block is executing on the specified dispatch queue, executes completion block on the main queue, and then hides the HUD. 260 | * 261 | * @param animated If set to YES the HUD will (dis)appear using the current animationType. If set to NO the HUD will 262 | * not use animations while (dis)appearing. 263 | * @param block The block to be executed while the HUD is shown. 264 | * @param queue The dispatch queue on which the block should be executed. 265 | * @param completion The block to be executed on completion. 266 | * 267 | * @see completionBlock 268 | */ 269 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue 270 | completionBlock:(MBProgressHUDCompletionBlock)completion; 271 | 272 | /** 273 | * A block that gets called after the HUD was completely hidden. 274 | */ 275 | @property (copy) MBProgressHUDCompletionBlock completionBlock; 276 | 277 | #endif 278 | 279 | /** 280 | * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate. 281 | * 282 | * @see MBProgressHUDMode 283 | */ 284 | @property (assign) MBProgressHUDMode mode; 285 | 286 | /** 287 | * The animation type that should be used when the HUD is shown and hidden. 288 | * 289 | * @see MBProgressHUDAnimation 290 | */ 291 | @property (assign) MBProgressHUDAnimation animationType; 292 | 293 | /** 294 | * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView. 295 | * For best results use a 37 by 37 pixel view (so the bounds match the built in indicator bounds). 296 | */ 297 | @property (MB_STRONG) UIView *customView; 298 | 299 | /** 300 | * The HUD delegate object. 301 | * 302 | * @see MBProgressHUDDelegate 303 | */ 304 | @property (MB_WEAK) id delegate; 305 | 306 | /** 307 | * An optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit 308 | * the entire text. If the text is too long it will get clipped by displaying "..." at the end. If left unchanged or 309 | * set to @"", then no message is displayed. 310 | */ 311 | @property (copy) NSString *labelText; 312 | 313 | /** 314 | * An optional details message displayed below the labelText message. This message is displayed only if the labelText 315 | * property is also set and is different from an empty string (@""). The details text can span multiple lines. 316 | */ 317 | @property (copy) NSString *detailsLabelText; 318 | 319 | /** 320 | * The opacity of the HUD window. Defaults to 0.8 (80% opacity). 321 | */ 322 | @property (assign) float opacity; 323 | 324 | /** 325 | * The color of the HUD window. Defaults to black. If this property is set, color is set using 326 | * this UIColor and the opacity property is not used. using retain because performing copy on 327 | * UIColor base colors (like [UIColor greenColor]) cause problems with the copyZone. 328 | */ 329 | @property (MB_STRONG) UIColor *color; 330 | 331 | /** 332 | * The x-axis offset of the HUD relative to the centre of the superview. 333 | */ 334 | @property (assign) float xOffset; 335 | 336 | /** 337 | * The y-axis offset of the HUD relative to the centre of the superview. 338 | */ 339 | @property (assign) float yOffset; 340 | 341 | /** 342 | * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views). 343 | * Defaults to 20.0 344 | */ 345 | @property (assign) float margin; 346 | 347 | /** 348 | * The corner radius for the HUD 349 | * Defaults to 10.0 350 | */ 351 | @property (assign) float cornerRadius; 352 | 353 | /** 354 | * Cover the HUD background view with a radial gradient. 355 | */ 356 | @property (assign) BOOL dimBackground; 357 | 358 | /* 359 | * Grace period is the time (in seconds) that the invoked method may be run without 360 | * showing the HUD. If the task finishes before the grace time runs out, the HUD will 361 | * not be shown at all. 362 | * This may be used to prevent HUD display for very short tasks. 363 | * Defaults to 0 (no grace time). 364 | * Grace time functionality is only supported when the task status is known! 365 | * @see taskInProgress 366 | */ 367 | @property (assign) float graceTime; 368 | 369 | /** 370 | * The minimum time (in seconds) that the HUD is shown. 371 | * This avoids the problem of the HUD being shown and than instantly hidden. 372 | * Defaults to 0 (no minimum show time). 373 | */ 374 | @property (assign) float minShowTime; 375 | 376 | /** 377 | * Indicates that the executed operation is in progress. Needed for correct graceTime operation. 378 | * If you don't set a graceTime (different than 0.0) this does nothing. 379 | * This property is automatically set when using showWhileExecuting:onTarget:withObject:animated:. 380 | * When threading is done outside of the HUD (i.e., when the show: and hide: methods are used directly), 381 | * you need to set this property when your task starts and completes in order to have normal graceTime 382 | * functionality. 383 | */ 384 | @property (assign) BOOL taskInProgress; 385 | 386 | /** 387 | * Removes the HUD from its parent view when hidden. 388 | * Defaults to NO. 389 | */ 390 | @property (assign) BOOL removeFromSuperViewOnHide; 391 | 392 | /** 393 | * Font to be used for the main label. Set this property if the default is not adequate. 394 | */ 395 | @property (MB_STRONG) UIFont* labelFont; 396 | 397 | /** 398 | * Color to be used for the main label. Set this property if the default is not adequate. 399 | */ 400 | @property (MB_STRONG) UIColor* labelColor; 401 | 402 | /** 403 | * Font to be used for the details label. Set this property if the default is not adequate. 404 | */ 405 | @property (MB_STRONG) UIFont* detailsLabelFont; 406 | 407 | /** 408 | * Color to be used for the details label. Set this property if the default is not adequate. 409 | */ 410 | @property (MB_STRONG) UIColor* detailsLabelColor; 411 | 412 | /** 413 | * The color of the activity indicator. Defaults to [UIColor whiteColor] 414 | * Does nothing on pre iOS 5. 415 | */ 416 | @property (MB_STRONG) UIColor *activityIndicatorColor; 417 | 418 | /** 419 | * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. 420 | */ 421 | @property (assign) float progress; 422 | 423 | /** 424 | * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size). 425 | */ 426 | @property (assign) CGSize minSize; 427 | 428 | 429 | /** 430 | * The actual size of the HUD bezel. 431 | * You can use this to limit touch handling on the bezel aria only. 432 | * @see https://github.com/jdg/MBProgressHUD/pull/200 433 | */ 434 | @property (atomic, assign, readonly) CGSize size; 435 | 436 | 437 | /** 438 | * Force the HUD dimensions to be equal if possible. 439 | */ 440 | @property (assign, getter = isSquare) BOOL square; 441 | 442 | @end 443 | 444 | 445 | @protocol MBProgressHUDDelegate 446 | 447 | @optional 448 | 449 | /** 450 | * Called after the HUD was fully hidden from the screen. 451 | */ 452 | - (void)hudWasHidden:(MBProgressHUD *)hud; 453 | 454 | @end 455 | 456 | 457 | /** 458 | * A progress view for showing definite progress by filling up a circle (pie chart). 459 | */ 460 | @interface MBRoundProgressView : UIView 461 | 462 | /** 463 | * Progress (0.0 to 1.0) 464 | */ 465 | @property (nonatomic, assign) float progress; 466 | 467 | /** 468 | * Indicator progress color. 469 | * Defaults to white [UIColor whiteColor] 470 | */ 471 | @property (nonatomic, MB_STRONG) UIColor *progressTintColor; 472 | 473 | /** 474 | * Indicator background (non-progress) color. 475 | * Defaults to translucent white (alpha 0.1) 476 | */ 477 | @property (nonatomic, MB_STRONG) UIColor *backgroundTintColor; 478 | 479 | /* 480 | * Display mode - NO = round or YES = annular. Defaults to round. 481 | */ 482 | @property (nonatomic, assign, getter = isAnnular) BOOL annular; 483 | 484 | @end 485 | 486 | 487 | /** 488 | * A flat bar progress view. 489 | */ 490 | @interface MBBarProgressView : UIView 491 | 492 | /** 493 | * Progress (0.0 to 1.0) 494 | */ 495 | @property (nonatomic, assign) float progress; 496 | 497 | /** 498 | * Bar border line color. 499 | * Defaults to white [UIColor whiteColor]. 500 | */ 501 | @property (nonatomic, MB_STRONG) UIColor *lineColor; 502 | 503 | /** 504 | * Bar background color. 505 | * Defaults to clear [UIColor clearColor]; 506 | */ 507 | @property (nonatomic, MB_STRONG) UIColor *progressRemainingColor; 508 | 509 | /** 510 | * Bar progress color. 511 | * Defaults to white [UIColor whiteColor]. 512 | */ 513 | @property (nonatomic, MB_STRONG) UIColor *progressColor; 514 | 515 | @end 516 | -------------------------------------------------------------------------------- /Pods/MBProgressHUD/README.mdown: -------------------------------------------------------------------------------- 1 | # MBProgressHUD [![Build Status](https://travis-ci.org/matej/MBProgressHUD.svg?branch=master)](https://travis-ci.org/matej/MBProgressHUD) 2 | 3 | MBProgressHUD is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private UIKit UIProgressHUD with some additional features. 4 | 5 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/1-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/1.png) 6 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/2-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/2.png) 7 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/3-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/3.png) 8 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/4-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/4.png) 9 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/5-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/5.png) 10 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/6-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/6.png) 11 | [![](http://dl.dropbox.com/u/378729/MBProgressHUD/7-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/7.png) 12 | 13 | ## Requirements 14 | 15 | MBProgressHUD works on any iOS version and is compatible with both ARC and non-ARC projects. It depends on the following Apple frameworks, which should already be included with most Xcode templates: 16 | 17 | * Foundation.framework 18 | * UIKit.framework 19 | * CoreGraphics.framework 20 | 21 | You will need the latest developer tools in order to build MBProgressHUD. Old Xcode versions might work, but compatibility will not be explicitly maintained. 22 | 23 | ## Adding MBProgressHUD to your project 24 | 25 | ### Cocoapods 26 | 27 | [CocoaPods](http://cocoapods.org) is the recommended way to add MBProgressHUD to your project. 28 | 29 | 1. Add a pod entry for MBProgressHUD to your Podfile `pod 'MBProgressHUD', '~> 0.9.1'` 30 | 2. Install the pod(s) by running `pod install`. 31 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. 32 | 33 | ### Source files 34 | 35 | Alternatively you can directly add the `MBProgressHUD.h` and `MBProgressHUD.m` source files to your project. 36 | 37 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/archive/master.zip) or add the repository as a git submodule to your git-tracked project. 38 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. 39 | 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. 40 | 41 | ### Static library 42 | 43 | You can also add MBProgressHUD as a static library to your project or workspace. 44 | 45 | 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/downloads) or add the repository as a git submodule to your git-tracked project. 46 | 2. Open your project in Xcode, then drag and drop `MBProgressHUD.xcodeproj` onto your project or workspace (use the "Product Navigator view"). 47 | 3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add `libMBProgressHUD.a`. You might also need to add `MBProgressHUD` to the Target Dependencies list. 48 | 4. Include MBProgressHUD wherever you need it with `#import `. 49 | 50 | ## Usage 51 | 52 | The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread. 53 | 54 | ```objective-c 55 | [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 56 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 57 | // Do something... 58 | dispatch_async(dispatch_get_main_queue(), ^{ 59 | [MBProgressHUD hideHUDForView:self.view animated:YES]; 60 | }); 61 | }); 62 | ``` 63 | 64 | If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns. 65 | 66 | ```objective-c 67 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 68 | hud.mode = MBProgressHUDModeAnnularDeterminate; 69 | hud.labelText = @"Loading"; 70 | [self doSomethingInBackgroundWithProgressCallback:^(float progress) { 71 | hud.progress = progress; 72 | } completionCallback:^{ 73 | [hud hide:YES]; 74 | }]; 75 | ``` 76 | 77 | UI updates should always be done on the main thread. Some MBProgressHUD setters are however considered "thread safe" and can be called from background threads. Those also include `setMode:`, `setCustomView:`, `setLabelText:`, `setLabelFont:`, `setDetailsLabelText:`, `setDetailsLabelFont:` and `setProgress:`. 78 | 79 | If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task. 80 | 81 | ```objective-c 82 | [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 83 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC); 84 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 85 | // Do something... 86 | [MBProgressHUD hideHUDForView:self.view animated:YES]; 87 | }); 88 | ``` 89 | 90 | You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes. 91 | 92 | For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h). 93 | 94 | 95 | ## License 96 | 97 | This code is distributed under the terms and conditions of the [MIT license](LICENSE). 98 | 99 | ## Change-log 100 | 101 | A brief summary of each MBProgressHUD release can be found on the [wiki](https://github.com/matej/MBProgressHUD/wiki/Change-log). 102 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - MBProgressHUD (0.9.1) 3 | - UITableView+FDTemplateLayoutCell (1.3) 4 | 5 | DEPENDENCIES: 6 | - MBProgressHUD (~> 0.9.1) 7 | - UITableView+FDTemplateLayoutCell (~> 1.3) 8 | 9 | SPEC CHECKSUMS: 10 | MBProgressHUD: c47f2c166c126cf2ce36498d80f33e754d4e93ad 11 | UITableView+FDTemplateLayoutCell: d5be6056b5060313f5955a2590ecd33142ad713d 12 | 13 | COCOAPODS: 0.38.2 14 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/MBProgressHUD.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/Pods.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/UITableView+FDTemplateLayoutCell.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MBProgressHUD.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods.xcscheme 13 | 14 | isShown 15 | 16 | 17 | UITableView+FDTemplateLayoutCell.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 3E49A49392441097A3D88EC2E5D516C7 26 | 27 | primary 28 | 29 | 30 | 4BEFE2E830988B01E0B6C655994918F8 31 | 32 | primary 33 | 34 | 35 | 60352B752823DC294E4B9FE33688D009 36 | 37 | primary 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MBProgressHUD/MBProgressHUD-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "MBProgressHUD.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/MBProgressHUD" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 4 | OTHER_LDFLAGS = ${MBPROGRESSHUD_OTHER_LDFLAGS} 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_MBProgressHUD : NSObject 3 | @end 4 | @implementation PodsDummy_MBProgressHUD 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/MBProgressHUD/MBProgressHUD.xcconfig: -------------------------------------------------------------------------------- 1 | MBPROGRESSHUD_OTHER_LDFLAGS = -framework "CoreGraphics" -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## MBProgressHUD 5 | 6 | Copyright (c) 2009-2015 Matej Bukovinski 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | ## UITableView+FDTemplateLayoutCell 27 | 28 | The MIT License (MIT) 29 | 30 | Copyright (c) 2015 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is 37 | furnished to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 48 | SOFTWARE. 49 | 50 | 51 | Generated by CocoaPods - http://cocoapods.org 52 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2009-2015 Matej Bukovinski 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | Title 37 | MBProgressHUD 38 | Type 39 | PSGroupSpecifier 40 | 41 | 42 | FooterText 43 | The MIT License (MIT) 44 | 45 | Copyright (c) 2015 46 | 47 | Permission is hereby granted, free of charge, to any person obtaining a copy 48 | of this software and associated documentation files (the "Software"), to deal 49 | in the Software without restriction, including without limitation the rights 50 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 51 | copies of the Software, and to permit persons to whom the Software is 52 | furnished to do so, subject to the following conditions: 53 | 54 | The above copyright notice and this permission notice shall be included in all 55 | copies or substantial portions of the Software. 56 | 57 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 58 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 59 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 60 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 61 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 62 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 63 | SOFTWARE. 64 | 65 | 66 | Title 67 | UITableView+FDTemplateLayoutCell 68 | Type 69 | PSGroupSpecifier 70 | 71 | 72 | FooterText 73 | Generated by CocoaPods - http://cocoapods.org 74 | Title 75 | 76 | Type 77 | PSGroupSpecifier 78 | 79 | 80 | StringsTable 81 | Acknowledgements 82 | Title 83 | Acknowledgements 84 | 85 | 86 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 63 | if [[ "${ACTION}" == "install" ]]; then 64 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 65 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 66 | fi 67 | rm -f "$RESOURCES_TO_COPY" 68 | 69 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 70 | then 71 | case "${TARGETED_DEVICE_FAMILY}" in 72 | 1,2) 73 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 74 | ;; 75 | 1) 76 | TARGET_DEVICE_ARGS="--target-device iphone" 77 | ;; 78 | 2) 79 | TARGET_DEVICE_ARGS="--target-device ipad" 80 | ;; 81 | *) 82 | TARGET_DEVICE_ARGS="--target-device mac" 83 | ;; 84 | esac 85 | 86 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 87 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 88 | while read line; do 89 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 90 | XCASSET_FILES+=("$line") 91 | fi 92 | done <<<"$OTHER_XCASSETS" 93 | 94 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 95 | fi 96 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MBProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MBProgressHUD" -l"UITableView+FDTemplateLayoutCell" -framework "CoreGraphics" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/MBProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"MBProgressHUD" -l"UITableView+FDTemplateLayoutCell" -framework "CoreGraphics" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Pods/Target Support Files/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "UITableView+FDTemplateLayoutCell.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/UITableView+FDTemplateLayoutCell" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/MBProgressHUD" "${PODS_ROOT}/Headers/Public/UITableView+FDTemplateLayoutCell" 4 | PODS_ROOT = ${SRCROOT} 5 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Pods/Target Support Files/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_UITableView_FDTemplateLayoutCell : NSObject 3 | @end 4 | @implementation PodsDummy_UITableView_FDTemplateLayoutCell 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.xcconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Pods/Target Support Files/UITableView+FDTemplateLayoutCell/UITableView+FDTemplateLayoutCell.xcconfig -------------------------------------------------------------------------------- /Pods/UITableView+FDTemplateLayoutCell/Classes/UITableView+FDTemplateLayoutCell.h: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2015-2016 forkingdog ( https://github.com/forkingdog ) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | 23 | #import 24 | 25 | @interface UITableView (FDTemplateLayoutCell) 26 | 27 | /// Returns height of cell of type specifed by a reuse identifier and configured 28 | /// by the configuration block. 29 | /// 30 | /// The cell would be layed out on a fixed-width, vertically expanding basis with 31 | /// respect to its dynamic content, using auto layout. Thus, it is imperative that 32 | /// the cell was set up to be self-satisfied, i.e. its content always determines 33 | /// its height given the width is equal to the tableview's. 34 | /// 35 | /// @param identifier A string identifier for retrieving and maintaining template 36 | /// cells with system's "-dequeueReusableCellWithIdentifier:" call. 37 | /// @param configuration An optional block for configuring and providing content 38 | /// to the template cell. The configuration should be minimal for scrolling 39 | /// performance yet sufficient for calculating cell's height. 40 | /// 41 | - (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier configuration:(void (^)(id cell))configuration; 42 | 43 | /// This method does what "-fd_heightForCellWithIdentifier:configuration" does, and 44 | /// calculated height will be cached by its index path, returns a cached height 45 | /// when needed. Therefore lots of extra height calculations could be saved. 46 | /// 47 | /// No need to worry about invalidating cached heights when data source changes, it 48 | /// will be done automatically when you call "-reloadData" or any method that triggers 49 | /// UITableView's reloading. 50 | /// 51 | /// @param indexPath where this cell's height cache belongs. 52 | /// 53 | - (CGFloat)fd_heightForCellWithIdentifier:(NSString *)identifier cacheByIndexPath:(NSIndexPath *)indexPath configuration:(void (^)(id cell))configuration; 54 | 55 | /// Helps to debug or inspect what is this "FDTemplateLayoutCell" extention doing, 56 | /// turning on to print logs when "creating", "calculating", "precaching" or "hitting cache". 57 | /// 58 | /// Default to "NO", log by "NSLog". 59 | /// 60 | @property (nonatomic, assign) BOOL fd_debugLogEnabled; 61 | 62 | @end 63 | 64 | @interface UITableViewCell (FDTemplateLayoutCell) 65 | 66 | /// Indicate this is a template layout cell for calculation only. 67 | /// You may need this when there are non-UI side effects when configure a cell. 68 | /// Like: 69 | /// - (void)configureCell:(FooCell *)cell atIndexPath:(NSIndexPath *)indexPath { 70 | /// cell.entity = [self entityAtIndexPath:indexPath]; 71 | /// if (!cell.fd_isTemplateLayoutCell) { 72 | /// [self notifySomething]; // non-UI side effects 73 | /// } 74 | /// } 75 | /// 76 | @property (nonatomic, assign) BOOL fd_isTemplateLayoutCell; 77 | 78 | /// Enable to enforce this template layout cell to use "frame layout" rather than "auto layout", 79 | /// and will ask cell's height by calling "-sizeThatFits:", so you must override this method. 80 | /// Note: 81 | /// If no layout constraints have been added to cell's content view, it will automatically 82 | /// switch to "frame layout" mode. Use this property only when you want to manually control 83 | /// this template layout cell's height calculation mode. Default to NO. 84 | /// 85 | @property (nonatomic, assign) BOOL fd_enforceFrameLayout; 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /Pods/UITableView+FDTemplateLayoutCell/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Pods/UITableView+FDTemplateLayoutCell/README.md: -------------------------------------------------------------------------------- 1 | # UITableView-FDTemplateLayoutCell 2 | 3 | 4 | ## Overview 5 | Template auto layout cell for **automatically** UITableViewCell height calculating. 6 | 7 | ![Demo Overview](https://github.com/forkingdog/UITableView-FDTemplateLayoutCell/blob/master/Sceenshots/screenshot2.gif) 8 | 9 | ## Basic usage 10 | 11 | If you have a **self-satisfied** cell, then all you have to do is: 12 | 13 | ``` objc 14 | #import "UITableView+FDTemplateLayoutCell.h" 15 | 16 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 17 | { 18 | return [tableView fd_heightForCellWithIdentifier:@"reuse identifer" configuration:^(id cell) { 19 | // Configure this cell with data, same as what you've done in "-tableView:cellForRowAtIndexPath:" 20 | // Like: 21 | // cell.entity = self.feedEntities[indexPath.row]; 22 | }]; 23 | } 24 | ``` 25 | 26 | ## Height Caching API 27 | 28 | Since iOS8, `-tableView:heightForRowAtIndexPath:` will be called more times than we expect, we can feel these extra calculations when scrolling. So we provide another API with caches: 29 | 30 | ``` objc 31 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 32 | { 33 | return [tableView fd_heightForCellWithIdentifier:@"identifer" cacheByIndexPath:indexPath configuration:^(id cell) { 34 | // configurations 35 | }]; 36 | } 37 | ``` 38 | 39 | ### Auto cache invalidation 40 | 41 | Extra calculations will be saved if a height at an index path has been cached, besides, **NO NEED** to worry about invalidating cached heights when data source changes, it will be done **automatically** when you call "-reloadData" or any method that triggers UITableView's reloading. 42 | 43 | ## Precache 44 | 45 | Pre-cache is an advanced function which helps to cache the rest of offscreen UITableViewCells automatically, just in **"idle"** time. It helps to improve scroll performance, because no extra height calculating will be used when scrolls. It's enabled by default if you use "fd_heightForCellWithIdentifier:cacheByIndexPath:configuation:" API. 46 | 47 | ## About estimatedRowHeight 48 | `estimatedRowHeight` helps to delay all cells' height calculation from load time to scroll time. Feel free to set it or not when you're using FDTemplateLayoutCell. If you use "cacheByIndexPath" API, setting this estimatedRowHeight property is a better practice for imporve load time, and it **DOES NO LONGER** affect scroll performance because of "precache". 49 | ``` objc 50 | self.tableView.estimatedRowHeight = 200; 51 | ``` 52 | ## Frame layout mode 53 | 54 | `FDTemplateLayoutCell` offers 2 modes for asking cell's height. 55 | 56 | 1. Auto layout mode using "-systemLayoutSizeFittingSize:" 57 | 2. Frame layout mode using "-sizeThatFits:" 58 | 59 | Generally, no need to care about modes, it will **automatically** choose a proper mode by whether you have set auto layout constrants on cell's content view. If you want to enforce frame layout mode, enable this property in your cell's configuration block: 60 | 61 | ``` objc 62 | cell.fd_enforceFrameLayout = YES; 63 | ``` 64 | And if you're using frame layout mode, you must override `-sizeThatFits:` in your customized cell and return content view's height (separator excluded) 65 | 66 | ``` 67 | - (CGSize)sizeThatFits:(CGSize)size 68 | { 69 | return CGSizeMake(size.width, A+B+C+D+E+....); 70 | } 71 | ``` 72 | 73 | ## Debug log 74 | 75 | Debug log helps to debug or inspect what is this "FDTemplateLayoutCell" extention doing, turning on to print logs when "calculating", "precaching" or "hitting cache".Default to "NO", log by "NSLog". 76 | 77 | ``` objc 78 | self.tableView.fd_debugLogEnabled = YES; 79 | ``` 80 | 81 | It will print like this: 82 | 83 | ``` objc 84 | ** FDTemplateLayoutCell ** layout cell created - FDFeedCell 85 | ** FDTemplateLayoutCell ** calculate - [0:0] 233.5 86 | ** FDTemplateLayoutCell ** calculate - [0:1] 155.5 87 | ** FDTemplateLayoutCell ** calculate - [0:2] 258 88 | ** FDTemplateLayoutCell ** calculate - [0:3] 284 89 | ** FDTemplateLayoutCell ** precached - [0:3] 284 90 | ** FDTemplateLayoutCell ** calculate - [0:4] 278.5 91 | ** FDTemplateLayoutCell ** precached - [0:4] 278.5 92 | ** FDTemplateLayoutCell ** hit cache - [0:3] 284 93 | ** FDTemplateLayoutCell ** hit cache - [0:4] 278.5 94 | ** FDTemplateLayoutCell ** hit cache - [0:5] 156 95 | ** FDTemplateLayoutCell ** hit cache - [0:6] 165 96 | ``` 97 | 98 | ## About self-satisfied cell 99 | 100 | a fully **self-satisfied** cell is constrainted by auto layout and each edge("top", "left", "bottom", "right") has at least one layout constraint against it. It's the same concept introduced as "self-sizing cell" in iOS8 using auto layout. 101 | 102 | A bad one :( - missing right and bottom 103 | ![non-self-satisfied](https://github.com/forkingdog/UITableView-FDTemplateLayoutCell/blob/master/Sceenshots/screenshot0.png) 104 | 105 | A good one :) 106 | ![self-satisfied](https://github.com/forkingdog/UITableView-FDTemplateLayoutCell/blob/master/Sceenshots/screenshot1.png) 107 | 108 | ## Note 109 | 110 | A template layout cell is created by `-dequeueReusableCellWithIdentifier:` method, it means that you MUST have registered this cell reuse identifier by one of: 111 | 112 | - A prototype cell of UITableView in storyboard. 113 | - Use `-registerNib:forCellReuseIdentifier:` 114 | - Use `-registerClass:forCellReuseIdentifier:` 115 | 116 | ## 如果你在天朝 117 | 可以看这篇中文博客: 118 | [http://blog.sunnyxx.com/2015/05/17/cell-height-calculation/](http://blog.sunnyxx.com/2015/05/17/cell-height-calculation/) 119 | 120 | ## Installation 121 | 122 | Latest version: **1.3** 123 | 124 | ``` 125 | pod search UITableView+FDTemplateLayoutCell 126 | ``` 127 | If you cannot search out the latest version, try: 128 | 129 | ``` 130 | pod setup 131 | ``` 132 | 133 | ## Release Notes 134 | 135 | We recommend to use the latest release in cocoapods. 136 | 137 | - 1.3 138 | Frame layout mode, handle cell's accessory view/type 139 | 140 | - 1.2 141 | Precache and auto cache invalidation 142 | 143 | - 1.1 144 | Height cache 145 | 146 | - 1.0 147 | Basic automatically height calculation 148 | 149 | ## License 150 | MIT 151 | -------------------------------------------------------------------------------- /Study Manual For iOS/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/1.png -------------------------------------------------------------------------------- /Study Manual For iOS/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/2.png -------------------------------------------------------------------------------- /Study Manual For iOS/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "MainViewController.h" 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Study Manual For iOS/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "MainViewController.h" 11 | #import "iOSOpenSourceViewController.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | 22 | [[UINavigationBar appearance]setBarTintColor:SystemThemeColor]; 23 | [[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];//系统返回键的颜色 24 | [NSThread sleepForTimeInterval:2.0];//设置启动页面时间 25 | 26 | return YES; 27 | } 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application { 30 | // 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. 31 | // 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. 32 | } 33 | 34 | - (void)applicationDidEnterBackground:(UIApplication *)application { 35 | // 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. 36 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 37 | } 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application { 40 | // 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. 41 | } 42 | 43 | - (void)applicationDidBecomeActive:(UIApplication *)application { 44 | // 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. 45 | } 46 | 47 | - (void)applicationWillTerminate:(UIApplication *)application { 48 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Study Manual For iOS/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/AppIcon.appiconset/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/AppIcon.appiconset/1.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.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 | "size" : "40x40", 15 | "idiom" : "iphone", 16 | "filename" : "1.png", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "idiom" : "iphone", 21 | "size" : "40x40", 22 | "scale" : "3x" 23 | }, 24 | { 25 | "size" : "60x60", 26 | "idiom" : "iphone", 27 | "filename" : "logo.png", 28 | "scale" : "2x" 29 | }, 30 | { 31 | "idiom" : "iphone", 32 | "size" : "60x60", 33 | "scale" : "3x" 34 | } 35 | ], 36 | "info" : { 37 | "version" : 1, 38 | "author" : "xcode" 39 | } 40 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/AppIcon.appiconset/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/AppIcon.appiconset/logo.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/LaunchImage.launchimage/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/LaunchImage.launchimage/1.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/LaunchImage.launchimage/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/LaunchImage.launchimage/2.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "orientation" : "landscape", 13 | "idiom" : "iphone", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "8.0", 16 | "subtype" : "736h", 17 | "scale" : "3x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "iphone", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "8.0", 24 | "subtype" : "667h", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "orientation" : "portrait", 29 | "idiom" : "iphone", 30 | "filename" : "1.png", 31 | "extent" : "full-screen", 32 | "minimum-system-version" : "7.0", 33 | "scale" : "2x" 34 | }, 35 | { 36 | "extent" : "full-screen", 37 | "idiom" : "iphone", 38 | "subtype" : "retina4", 39 | "filename" : "2.png", 40 | "minimum-system-version" : "7.0", 41 | "orientation" : "portrait", 42 | "scale" : "2x" 43 | }, 44 | { 45 | "orientation" : "portrait", 46 | "idiom" : "iphone", 47 | "extent" : "full-screen", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "orientation" : "portrait", 52 | "idiom" : "iphone", 53 | "extent" : "full-screen", 54 | "scale" : "2x" 55 | }, 56 | { 57 | "orientation" : "portrait", 58 | "idiom" : "iphone", 59 | "extent" : "full-screen", 60 | "subtype" : "retina4", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/nav_backbtn.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "nav_backbtn.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/nav_backbtn.imageset/nav_backbtn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/nav_backbtn.imageset/nav_backbtn.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_discover_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "tabbar_discover_selected@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_discover_selected.imageset/tabbar_discover_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/tabbar_discover_selected.imageset/tabbar_discover_selected@2x.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_home.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "scale" : "2x", 10 | "filename" : "tabbar_home@2x.png" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_home.imageset/tabbar_home@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/tabbar_home.imageset/tabbar_home@2x.png -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_profile_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "tabbar_profile_selected@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Images.xcassets/tabbar_profile_selected.imageset/tabbar_profile_selected@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/Images.xcassets/tabbar_profile_selected.imageset/tabbar_profile_selected@2x.png -------------------------------------------------------------------------------- /Study Manual For iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | cc.huaxun.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeRight 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/Model/FDFeedCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FDFeedCell.h 3 | // Demo 4 | // 5 | // Created by sunnyxx on 15/4/17. 6 | // Copyright (c) 2015年 forkingdog. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FDFeedEntity.h" 11 | 12 | @interface FDFeedCell : UITableViewCell 13 | 14 | @property (nonatomic, strong) FDFeedEntity *entity; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/Model/FDFeedCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FDFeedCell.m 3 | // Demo 4 | // 5 | // Created by sunnyxx on 15/4/17. 6 | // Copyright (c) 2015年 forkingdog. All rights reserved. 7 | // 8 | 9 | #import "FDFeedCell.h" 10 | 11 | @interface FDFeedCell () 12 | 13 | @property (strong, nonatomic) IBOutlet UILabel *titleLabel; 14 | @property (strong, nonatomic) IBOutlet UILabel *contentLabel; 15 | @property (strong, nonatomic) IBOutlet UIImageView *contentImageView; 16 | @property (strong, nonatomic) IBOutlet UILabel *usernameLabel; 17 | @property (strong, nonatomic) IBOutlet UILabel *timeLabel; 18 | 19 | @end 20 | 21 | @implementation FDFeedCell 22 | 23 | - (void)awakeFromNib 24 | { 25 | [super awakeFromNib]; 26 | 27 | // Fix the bug in iOS7 - initial constraints warning 28 | self.contentView.bounds = [UIScreen mainScreen].bounds; 29 | } 30 | 31 | - (void)setEntity:(FDFeedEntity *)entity 32 | { 33 | _entity = entity; 34 | self.titleLabel.text = entity.title; 35 | self.contentLabel.text = entity.content; 36 | // self.contentImageView.image = entity.imageName.length > 0 ? [UIImage imageNamed:entity.imageName] : nil; 37 | // self.usernameLabel.text = entity.username; 38 | // self.timeLabel.text = entity.time; 39 | self.userInteractionEnabled = YES; 40 | 41 | } 42 | 43 | #if 0 44 | 45 | // If you are not using auto layout, override this method 46 | - (CGSize)sizeThatFits:(CGSize)size 47 | { 48 | CGFloat totalHeight = 0; 49 | totalHeight += [self.titleLabel sizeThatFits:size].height; 50 | totalHeight += [self.contentLabel sizeThatFits:size].height; 51 | totalHeight += [self.contentImageView sizeThatFits:size].height; 52 | totalHeight += [self.usernameLabel sizeThatFits:size].height; 53 | totalHeight += 40; // margins 54 | return CGSizeMake(size.width, totalHeight); 55 | } 56 | 57 | #endif 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/Model/FDFeedEntity.h: -------------------------------------------------------------------------------- 1 | // 2 | // FDFeedEntity.h 3 | // Demo 4 | // 5 | // Created by sunnyxx on 15/4/16. 6 | // Copyright (c) 2015年 forkingdog. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FDFeedEntity : NSObject 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dictionary; 14 | 15 | @property (nonatomic, copy) NSString *title; 16 | @property (nonatomic, copy) NSString *content; 17 | //@property (nonatomic, copy) NSString *username; 18 | //@property (nonatomic, copy) NSString *time; 19 | //@property (nonatomic, copy) NSString *imageName; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/Model/FDFeedEntity.m: -------------------------------------------------------------------------------- 1 | // 2 | // FDFeedEntity.m 3 | // Demo 4 | // 5 | // Created by sunnyxx on 15/4/16. 6 | // Copyright (c) 2015年 forkingdog. All rights reserved. 7 | // 8 | 9 | #import "FDFeedEntity.h" 10 | 11 | @implementation FDFeedEntity 12 | 13 | - (instancetype)initWithDictionary:(NSDictionary *)dictionary 14 | { 15 | self = super.init; 16 | if (self) { 17 | self.title = dictionary[@"Dname"]; 18 | self.content = dictionary[@"Dtext"]; 19 | // self.username = dictionary[@"username"]; 20 | // self.time = dictionary[@"time"]; 21 | // self.imageName = dictionary[@"imageName"]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/DetailMainTableViewControlelr.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailMainTableViewControlelr.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/16/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailMainTableViewControlelr : UITableViewController 12 | 13 | @property (nonatomic,assign) NSInteger detailtag; 14 | @property (nonatomic,strong) NSString * detailTitle; 15 | @property (nonatomic,strong) NSString * feedTitle; 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/DetailMainTableViewControlelr.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailMainTableViewControlelr.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/16/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "DetailMainTableViewControlelr.h" 10 | #import "FDFeedViewController.h" 11 | 12 | @interface DetailMainTableViewControlelr () 13 | 14 | @end 15 | 16 | @implementation DetailMainTableViewControlelr 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | 21 | self.title = self.detailTitle; 22 | } 23 | 24 | - (void)didReceiveMemoryWarning { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | #pragma mark - Table view data source 30 | 31 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 32 | // Return the number of sections. 33 | return 1; 34 | } 35 | 36 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 37 | 38 | // Return the number of rows in the section. 39 | return [GlobalResource sharedInstance].detailArray.count; 40 | } 41 | 42 | 43 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 44 | 45 | static NSString *CellIdentifier = @"detailCellIdentifier"; 46 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 47 | if (cell == nil) { 48 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 49 | } 50 | 51 | cell.textLabel.text = [[GlobalResource sharedInstance].detailArray objectAtIndex:indexPath.row]; 52 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 53 | 54 | return cell; 55 | 56 | } 57 | 58 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 59 | { 60 | 61 | if (self.detailtag == 0) { 62 | 63 | [GlobalResource sharedInstance].jsonString = @"XcodeChaJian"; 64 | _feedTitle = @"Xcode插件"; 65 | } 66 | 67 | if (self.detailtag == 1) { 68 | switch ([indexPath row]) { 69 | case 0: 70 | { 71 | [GlobalResource sharedInstance].jsonString = @"XiaLaShuaXin"; 72 | _feedTitle = @"下拉刷新"; 73 | 74 | } 75 | break; 76 | case 1: 77 | { 78 | [GlobalResource sharedInstance].jsonString = @"MoHuXiaoGuo"; 79 | _feedTitle = @"模糊效果"; 80 | 81 | } 82 | break; 83 | case 2: 84 | { 85 | [GlobalResource sharedInstance].jsonString = @"AutoLayout"; 86 | _feedTitle = @"AutoLayout"; 87 | 88 | } 89 | break; 90 | case 3: 91 | { 92 | [GlobalResource sharedInstance].jsonString = @"FuWenBen"; 93 | _feedTitle = @"富文本"; 94 | 95 | } 96 | break; 97 | case 4: 98 | { 99 | [GlobalResource sharedInstance].jsonString = @"TuBiao"; 100 | _feedTitle = @"图表"; 101 | 102 | } 103 | break; 104 | case 5: 105 | { 106 | [GlobalResource sharedInstance].jsonString = @"BiaoXiangGuan"; 107 | _feedTitle = @"表相关"; 108 | 109 | } 110 | break; 111 | case 6: 112 | { 113 | [GlobalResource sharedInstance].jsonString = @"YinCangYuXianShi"; 114 | _feedTitle = @"隐藏与显示"; 115 | 116 | } 117 | break; 118 | case 7: 119 | { 120 | [GlobalResource sharedInstance].jsonString = @"HUDYuToast"; 121 | _feedTitle = @"HUD与Toast"; 122 | 123 | } 124 | break; 125 | case 8: 126 | { 127 | [GlobalResource sharedInstance].jsonString = @"DuiHuaKuang"; 128 | _feedTitle = @"对话框"; 129 | 130 | } 131 | break; 132 | case 9: 133 | { 134 | [GlobalResource sharedInstance].jsonString = @"QiTaUI"; 135 | _feedTitle = @"其他UI"; 136 | 137 | } 138 | break; 139 | 140 | } 141 | 142 | } 143 | 144 | if (self.detailtag == 2) { 145 | 146 | switch ([indexPath row]) { 147 | case 0: 148 | { 149 | [GlobalResource sharedInstance].jsonString = @"DongHua"; 150 | _feedTitle = @"动画"; 151 | 152 | } 153 | break; 154 | case 1: 155 | { 156 | [GlobalResource sharedInstance].jsonString = @"CeHuaYuYouHuaFanHui"; 157 | _feedTitle = @"侧滑与右滑返回手势"; 158 | 159 | } 160 | break; 161 | case 2: 162 | { 163 | [GlobalResource sharedInstance].jsonString = @"GifDongHua"; 164 | _feedTitle = @"Gif 动画"; 165 | 166 | } 167 | break; 168 | case 3: 169 | { 170 | [GlobalResource sharedInstance].jsonString = @"QiTaDongHua"; 171 | _feedTitle = @"其他动画"; 172 | 173 | } 174 | break; 175 | 176 | } 177 | } 178 | if (self.detailtag == 3) { 179 | 180 | switch ([indexPath row]) { 181 | case 0: 182 | { 183 | [GlobalResource sharedInstance].jsonString = @"WangLuoLianJie"; 184 | _feedTitle = @"网络连接"; 185 | 186 | } 187 | break; 188 | case 1: 189 | { 190 | [GlobalResource sharedInstance].jsonString = @"WangLuoCeShi"; 191 | _feedTitle = @"网络测试"; 192 | 193 | } 194 | break; 195 | case 2: 196 | { 197 | [GlobalResource sharedInstance].jsonString = @"TuXiangHuoQu"; 198 | _feedTitle = @"图像获取"; 199 | 200 | } 201 | break; 202 | case 3: 203 | { 204 | [GlobalResource sharedInstance].jsonString = @"WangLuoLiaoTian"; 205 | _feedTitle = @"网络聊天"; 206 | 207 | } 208 | break; 209 | case 4: 210 | { 211 | [GlobalResource sharedInstance].jsonString = @"WebView"; 212 | _feedTitle = @"WebView"; 213 | 214 | } 215 | break; 216 | 217 | } 218 | } 219 | if (self.detailtag == 4) { 220 | 221 | [GlobalResource sharedInstance].jsonString = @"Model"; 222 | _feedTitle = @"Model"; 223 | 224 | } 225 | 226 | if (self.detailtag == 5) { 227 | [GlobalResource sharedInstance].jsonString = @"QiTa"; 228 | _feedTitle = @"其他"; 229 | 230 | } 231 | if (self.detailtag == 6) { 232 | [GlobalResource sharedInstance].jsonString = @"ShuJuKu"; 233 | _feedTitle = @"数据库"; 234 | 235 | } 236 | if (self.detailtag == 7) { 237 | [GlobalResource sharedInstance].jsonString = @"HuanChunChuLi"; 238 | _feedTitle = @"缓存处理"; 239 | 240 | } 241 | if (self.detailtag == 8) { 242 | [GlobalResource sharedInstance].jsonString = @"PDF"; 243 | _feedTitle = @"PDF"; 244 | 245 | } 246 | if (self.detailtag == 9) { 247 | [GlobalResource sharedInstance].jsonString = @"TuXiangLiuLanJiChuLi"; 248 | _feedTitle = @"图像浏览及处理"; 249 | 250 | } 251 | if (self.detailtag == 10) { 252 | [GlobalResource sharedInstance].jsonString = @"SheXiangPaiZhaoShiPinYinPinChuLi"; 253 | _feedTitle = @"摄像拍照视频音频处理"; 254 | 255 | } 256 | if (self.detailtag == 11) { 257 | [GlobalResource sharedInstance].jsonString = @"XiangYingShiKuangJia"; 258 | _feedTitle = @"响应式框架"; 259 | 260 | } 261 | if (self.detailtag == 12) { 262 | switch ([indexPath row]) { 263 | 264 | case 0: 265 | { 266 | [GlobalResource sharedInstance].jsonString = @"XiaoXiTuiSongKeHuDuan"; 267 | _feedTitle = @"消息推送客户端"; 268 | 269 | 270 | } 271 | break; 272 | case 1: 273 | { 274 | [GlobalResource sharedInstance].jsonString = @"XiaoXiTuiSongFuWuDuan"; 275 | _feedTitle = @"消息推送服务端"; 276 | 277 | } 278 | break; 279 | case 2: 280 | { 281 | [GlobalResource sharedInstance].jsonString = @"TongZhiXiangGuan"; 282 | _feedTitle = @"通知相关"; 283 | 284 | } 285 | break; 286 | } 287 | 288 | } 289 | if (self.detailtag == 13) { 290 | [GlobalResource sharedInstance].jsonString = @"BanBenXinAPIDeDemo"; 291 | _feedTitle = @"版本新API的Demo"; 292 | 293 | } 294 | if (self.detailtag == 14) { 295 | [GlobalResource sharedInstance].jsonString = @"DaiMaAnQuanYuMiMa"; 296 | _feedTitle = @"代码安全与密码"; 297 | 298 | } 299 | if (self.detailtag == 15) { 300 | [GlobalResource sharedInstance].jsonString = @"CeShiYuTiaoShi"; 301 | _feedTitle = @"测试与调试"; 302 | 303 | } 304 | if (self.detailtag == 16) { 305 | [GlobalResource sharedInstance].jsonString = @"AppleWatch"; 306 | _feedTitle = @"AppleWatch"; 307 | 308 | } 309 | if (self.detailtag == 17) { 310 | [GlobalResource sharedInstance].jsonString = @"WanZhengXiangMu"; 311 | _feedTitle = @"完整项目"; 312 | 313 | } 314 | if (self.detailtag == 18) { 315 | [GlobalResource sharedInstance].jsonString = @"HaoDeWenZhang"; 316 | _feedTitle = @"好的文章"; 317 | 318 | } 319 | if (self.detailtag == 19) { 320 | [GlobalResource sharedInstance].jsonString = @"VPN"; 321 | _feedTitle = @"VPN"; 322 | 323 | } 324 | if (self.detailtag == 20) { 325 | [GlobalResource sharedInstance].jsonString = @"MeiGongZiYuan"; 326 | _feedTitle = @"美工资源"; 327 | 328 | } 329 | if (self.detailtag == 21) { 330 | 331 | switch ([indexPath row]) { 332 | 333 | case 0: 334 | { 335 | [GlobalResource sharedInstance].jsonString = @"KaiFaZiLiao"; 336 | _feedTitle = @"开发资料"; 337 | 338 | } 339 | break; 340 | case 1: 341 | { 342 | [GlobalResource sharedInstance].jsonString = @"swift"; 343 | _feedTitle = @"swift"; 344 | 345 | } 346 | break; 347 | case 2: 348 | { 349 | [GlobalResource sharedInstance].jsonString = @"TaRenKaiYuanZongJie"; 350 | _feedTitle = @"他人开源总结"; 351 | 352 | } 353 | break; 354 | } 355 | } 356 | 357 | [self performSegueWithIdentifier:@"feedSegue" sender:nil]; 358 | } 359 | 360 | #pragma mark - Navigation 361 | 362 | 363 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 364 | 365 | if ([segue.identifier isEqualToString:@"feedSegue"]) { 366 | 367 | FDFeedViewController * fd = segue.destinationViewController; 368 | fd.feedTitle = _feedTitle; 369 | } 370 | 371 | } 372 | 373 | @end 374 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/FDFeedViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FDFeedViewController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSArray *feedDicts; 14 | @property (nonatomic, strong) NSString * feedTitle; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/FDFeedViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "FDFeedViewController.h" 10 | #import "UITableView+FDTemplateLayoutCell.h" 11 | #import "FDFeedEntity.h" 12 | #import "FDFeedCell.h" 13 | 14 | @interface FDFeedViewController () 15 | @property (nonatomic, copy) NSArray *prototypeEntitiesFromJSON; 16 | @property (nonatomic, strong) NSMutableArray *feedEntitySections; // 2d array 17 | @property (nonatomic, assign) BOOL cellHeightCacheEnabled; 18 | @end 19 | 20 | @implementation FDFeedViewController 21 | 22 | - (void)viewDidLoad 23 | { 24 | self.title = self.feedTitle; 25 | [super viewDidLoad]; 26 | 27 | self.tableView.estimatedRowHeight = 200; 28 | self.tableView.fd_debugLogEnabled = NO; 29 | 30 | self.cellHeightCacheEnabled = YES; 31 | 32 | [self buildTestDataThen:^{ 33 | self.feedEntitySections = @[].mutableCopy; 34 | [self.feedEntitySections addObject:self.prototypeEntitiesFromJSON.mutableCopy]; 35 | [self.tableView reloadData]; 36 | }]; 37 | 38 | } 39 | 40 | - (void)buildTestDataThen:(void (^)(void))then 41 | { 42 | // Simulate an async request 43 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 44 | 45 | // Data from `data.json` 46 | NSString *dataFilePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"]; 47 | NSData *data = [NSData dataWithContentsOfFile:dataFilePath]; 48 | NSDictionary *rootDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil]; 49 | 50 | self.feedDicts= rootDict[[GlobalResource sharedInstance].jsonString]; 51 | 52 | // Convert to `FDFeedEntity` 53 | NSMutableArray *entities = @[].mutableCopy; 54 | [self.feedDicts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 55 | [entities addObject:[[FDFeedEntity alloc] initWithDictionary:obj]]; 56 | }]; 57 | self.prototypeEntitiesFromJSON = entities; 58 | 59 | // Callback 60 | dispatch_async(dispatch_get_main_queue(), ^{ 61 | !then ?: then(); 62 | }); 63 | }); 64 | } 65 | 66 | #pragma mark - UITableViewDataSource 67 | 68 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 69 | { 70 | return self.feedEntitySections.count; 71 | } 72 | 73 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 74 | { 75 | return [self.feedEntitySections[section] count]; 76 | } 77 | 78 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 79 | { 80 | FDFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FDFeedCell" forIndexPath:indexPath]; 81 | [self configureCell:cell atIndexPath:indexPath]; 82 | return cell; 83 | } 84 | 85 | - (void)configureCell:(FDFeedCell *)cell atIndexPath:(NSIndexPath *)indexPath 86 | { 87 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 88 | cell.entity = self.feedEntitySections[indexPath.section][indexPath.row]; 89 | } 90 | 91 | #pragma mark - UITableViewDelegate 92 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 93 | { 94 | 95 | NSUInteger row = [indexPath row]; 96 | NSDictionary *rowDict = [self.feedDicts objectAtIndex:row]; 97 | [GlobalResource sharedInstance].iOSOpenSourceURL = [rowDict objectForKey:@"Durl"]; 98 | [GlobalResource sharedInstance].iOSOpenSourceURLName = [rowDict objectForKey:@"Dname"]; 99 | 100 | iOSOpenSourceWebKitViewController * iOSopenSourceWebKitViewController = [[iOSOpenSourceWebKitViewController alloc]init]; 101 | 102 | [self.navigationController pushViewController: iOSopenSourceWebKitViewController animated:YES]; 103 | 104 | } 105 | 106 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 107 | { 108 | if (self.cellHeightCacheEnabled) { 109 | return [tableView fd_heightForCellWithIdentifier:@"FDFeedCell" cacheByIndexPath:indexPath configuration:^(FDFeedCell *cell) { 110 | [self configureCell:cell atIndexPath:indexPath]; 111 | }]; 112 | } else { 113 | return [tableView fd_heightForCellWithIdentifier:@"FDFeedCell" configuration:^(FDFeedCell *cell) { 114 | [self configureCell:cell atIndexPath:indexPath]; 115 | }]; 116 | } 117 | } 118 | 119 | - (IBAction)backButton:(id)sender { 120 | 121 | [self dismissViewControllerAnimated:YES completion:nil];} 122 | @end 123 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/MainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface MainViewController : UITableViewController 13 | 14 | @property (nonatomic,strong) NSMutableArray * titleArray; 15 | @property (nonatomic,strong) UIButton * btn1; 16 | @property (nonatomic,strong) NSMutableArray * detailArray; 17 | @property (nonatomic,assign) NSInteger tag; 18 | @property (nonatomic,strong) NSString * detailTitle; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Study Manual For iOS/Main/ViewController/MainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "MainViewController.h" 10 | #import "iOSOpenSourceViewController.h" 11 | #import "iOSBlogTableViewController.h" 12 | #import "DetailMainTableViewControlelr.h" 13 | #import "FDFeedViewController.h" 14 | 15 | @interface MainViewController () 16 | 17 | @end 18 | 19 | @implementation MainViewController 20 | 21 | - (void)viewDidLoad { 22 | 23 | [super viewDidLoad]; 24 | self.title = @"开源库"; 25 | 26 | _titleArray = [[NSMutableArray alloc]initWithObjects: 27 | @"Xcode 插件", 28 | @"UI", 29 | @"动画", 30 | @"网络相关", 31 | @"Model", 32 | @"其他", 33 | @"数据库", 34 | @"缓存处理", 35 | @"PDF", 36 | @"图像浏览及处理", 37 | @"摄像照相视频音频处理", 38 | @"响应式框架", 39 | @"消息相关", 40 | @"版本新 API 的 Demo", 41 | @"代码安全与密码", 42 | @"测试及调试", 43 | @"AppleWatch", 44 | @"完整项目", 45 | @"好的文章", 46 | @"VPN", 47 | @"美工资源", 48 | @"开发资源", 49 | nil]; 50 | 51 | } 52 | 53 | #pragma mark - Table view data source 54 | 55 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 56 | 57 | return 1; 58 | } 59 | 60 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 61 | 62 | return [_titleArray count]; 63 | } 64 | 65 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 66 | 67 | static NSString *CellIdentifier = @"CellIdentifier"; 68 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 69 | if (cell == nil) { 70 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 71 | } 72 | 73 | cell.textLabel.text = [_titleArray objectAtIndex:indexPath.row]; 74 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 75 | 76 | return cell; 77 | } 78 | 79 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 80 | switch ([indexPath row]) { 81 | 82 | case 0: 83 | { 84 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"Xcode插件",nil]; 85 | self.tag =0; 86 | self.detailTitle = [_titleArray objectAtIndex:0]; 87 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 88 | } 89 | break; 90 | case 1: 91 | { 92 | _detailArray = [[NSMutableArray alloc]initWithObjects: 93 | @"下拉刷新", 94 | @"模糊效果", 95 | @"AutoLayout", 96 | @"富文本", 97 | @"图表", 98 | @"表相关", 99 | @"隐藏与显示", 100 | @"HUD与Toast", 101 | @"对话框", 102 | @"其他UI",nil]; 103 | self.tag =1; 104 | self.detailTitle = [_titleArray objectAtIndex:1]; 105 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 106 | } 107 | break; 108 | case 2: 109 | { 110 | _detailArray = [[NSMutableArray alloc]initWithObjects: 111 | @"动画", 112 | @"侧滑与右滑返回", 113 | @"gif动画", 114 | @"其他动画",nil]; 115 | self.tag =2; 116 | self.detailTitle = [_titleArray objectAtIndex:2]; 117 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 118 | } 119 | break; 120 | case 3: 121 | { 122 | _detailArray = [[NSMutableArray alloc]initWithObjects: 123 | @"网络连接", 124 | @"网络测试", 125 | @"图像获取", 126 | @"网络聊天", 127 | @"WebView",nil]; 128 | self.tag =3; 129 | self.detailTitle = [_titleArray objectAtIndex:3]; 130 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 131 | } 132 | break; 133 | 134 | case 4: 135 | { 136 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"Model",nil]; 137 | self.tag =4; 138 | self.detailTitle = [_titleArray objectAtIndex:4]; 139 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 140 | } 141 | break; 142 | 143 | case 5: 144 | { 145 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"其他",nil]; 146 | self.tag =5; 147 | self.detailTitle = [_titleArray objectAtIndex:5]; 148 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 149 | } 150 | break; 151 | 152 | case 6: 153 | { 154 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"数据库",nil]; 155 | self.tag =6; 156 | self.detailTitle = [_titleArray objectAtIndex:6]; 157 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 158 | } 159 | break; 160 | case 7: 161 | { 162 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"缓存处理",nil]; 163 | self.tag =7; 164 | self.detailTitle = [_titleArray objectAtIndex:7]; 165 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 166 | } 167 | break; 168 | case 8: 169 | { 170 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"PDF",nil]; 171 | self.tag =8; 172 | self.detailTitle = [_titleArray objectAtIndex:8]; 173 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 174 | } 175 | break; 176 | case 9: 177 | { 178 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"图像浏览及处理",nil]; 179 | self.tag =9; 180 | self.detailTitle = [_titleArray objectAtIndex:9]; 181 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 182 | } 183 | break; 184 | case 10: 185 | { 186 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"摄像照相视频音频处理",nil]; 187 | self.tag =10; 188 | self.detailTitle = [_titleArray objectAtIndex:10]; 189 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 190 | } 191 | break; 192 | case 11: 193 | { 194 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"响应式框架",nil]; 195 | self.tag =11; 196 | self.detailTitle = [_titleArray objectAtIndex:11]; 197 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 198 | } 199 | break; 200 | case 12: 201 | { 202 | _detailArray = [[NSMutableArray alloc]initWithObjects: 203 | @"消息推送客户端", 204 | @"消息推送服务端", 205 | @"通知相关", 206 | nil]; 207 | self.tag =12; 208 | self.detailTitle = [_titleArray objectAtIndex:12]; 209 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 210 | } 211 | break; 212 | case 13: 213 | { 214 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"版本新API的Demo",nil]; 215 | self.tag =13; 216 | self.detailTitle = [_titleArray objectAtIndex:13]; 217 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 218 | } 219 | break; 220 | case 14: 221 | { 222 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"代码安全与密码",nil]; 223 | self.tag =14; 224 | self.detailTitle = [_titleArray objectAtIndex:14]; 225 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 226 | } 227 | break; 228 | case 15: 229 | { 230 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"测试与调试",nil]; 231 | self.tag =15; 232 | self.detailTitle = [_titleArray objectAtIndex:15]; 233 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 234 | } 235 | break; 236 | 237 | case 16: 238 | { 239 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"AppleWatch",nil]; 240 | self.tag =16; 241 | self.detailTitle = [_titleArray objectAtIndex:16]; 242 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 243 | } 244 | break; 245 | 246 | case 17: 247 | { 248 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"完整项目",nil]; 249 | self.tag =17; 250 | self.detailTitle = [_titleArray objectAtIndex:17]; 251 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 252 | } 253 | break; 254 | case 18: 255 | { 256 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"好的文章",nil]; 257 | self.tag =18; 258 | self.detailTitle = [_titleArray objectAtIndex:18]; 259 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 260 | } 261 | break; 262 | case 19: 263 | { 264 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"VPN",nil]; 265 | self.tag =19; 266 | self.detailTitle = [_titleArray objectAtIndex:19]; 267 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 268 | } 269 | break; 270 | case 20: 271 | { 272 | _detailArray = [[NSMutableArray alloc]initWithObjects:@"美工资源",nil]; 273 | self.tag =20; 274 | self.detailTitle = [_titleArray objectAtIndex:20]; 275 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 276 | } 277 | break; 278 | case 21: 279 | { 280 | _detailArray = [[NSMutableArray alloc]initWithObjects: 281 | @"开发资料", 282 | @"swift", 283 | @"他人开源总结", 284 | nil]; 285 | self.tag =21; 286 | self.detailTitle = [_titleArray objectAtIndex:21]; 287 | [self performSegueWithIdentifier:@"detailSegue" sender:nil]; 288 | } 289 | break; 290 | 291 | default: 292 | break; 293 | } 294 | 295 | } 296 | 297 | #pragma mark - Navigation 298 | 299 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 300 | 301 | if ([segue.identifier isEqualToString:@"detailSegue"]){ 302 | [GlobalResource sharedInstance].detailArray = _detailArray; 303 | DetailMainTableViewControlelr * de = segue.destinationViewController; 304 | de.detailtag = self.tag; 305 | de.detailTitle = self.detailTitle; 306 | } 307 | 308 | } 309 | 310 | @end 311 | -------------------------------------------------------------------------------- /Study Manual For iOS/PrefixHeader.pch: -------------------------------------------------------------------------------- 1 | // 2 | // PrefixHeader.pch 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import "Util/GlobalResource/GlobalResource.h" 14 | #import "Util/Toast/Toast+UIView.h" 15 | #import "Util/WebKit/Reachability.h" 16 | #import "iOSOpenSourceWebKitViewController.h" 17 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogPlist.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | url 7 | http://cnbin.github.io 8 | name 9 | 陈斌彬的技术博客 10 | 11 | 12 | name 13 | OneV's Den 14 | url 15 | http://onevcat.com 16 | 17 | 18 | name 19 | 破船之家 20 | url 21 | http://beyondvincent.com 22 | 23 | 24 | name 25 | NSHipster 26 | url 27 | http://nshipster.cn 28 | 29 | 30 | name 31 | Limboy 无网不剩 32 | url 33 | http://blog.leezhong.com/ 34 | 35 | 36 | name 37 | 唐巧的技术博客 38 | url 39 | http://blog.devtang.com 40 | 41 | 42 | name 43 | Lex Tang 44 | url 45 | http://lexrus.com/ 46 | 47 | 48 | name 49 | 念茜的博客 50 | url 51 | http://nianxi.net 52 | 53 | 54 | name 55 | Xcode Dev 56 | url 57 | http://blog.xcodev.com 58 | 59 | 60 | name 61 | Ted's Homepage 62 | url 63 | http://wufawei.com/ 64 | 65 | 66 | name 67 | txx's blog 68 | url 69 | http://blog.t-xx.me 70 | 71 | 72 | name 73 | Kevin Blog 74 | url 75 | http://zhowkev.in 76 | 77 | 78 | name 79 | 阿毛的蛋疼地 80 | url 81 | http://www.xiangwangfeng.com 82 | 83 | 84 | name 85 | 亚庆的 Blog 86 | url 87 | http://billwang1990.github.io 88 | 89 | 90 | name 91 | Nonomori 92 | url 93 | http://nonomori.farbox.com 94 | 95 | 96 | name 97 | 言无不尽 98 | url 99 | http://tang3w.com 100 | 101 | 102 | name 103 | Wonderffee's Blog 104 | url 105 | http://wonderffee.github.io 106 | 107 | 108 | name 109 | I'm TualatriX 110 | url 111 | http://imtx.me 112 | 113 | 114 | name 115 | Cocoabit 116 | url 117 | http://blog.cocoabit.com 118 | 119 | 120 | name 121 | nixzhu on scriptogr.am 122 | url 123 | http://nixzhu.me 124 | 125 | 126 | name 127 | 不会开机的男孩 128 | url 129 | http://studentdeng.github.io 130 | 131 | 132 | name 133 | Nico 134 | url 135 | http://blog.inico.me 136 | 137 | 138 | name 139 | 阿峰的技术窝窝 140 | url 141 | http://hufeng825.github.io 142 | 143 | 144 | name 145 | answer_huang 146 | url 147 | http://answerhuang.duapp.com 148 | 149 | 150 | name 151 | webfrogs 152 | url 153 | http://blog.nswebfrog.com/ 154 | 155 | 156 | name 157 | 代码手工艺人 158 | url 159 | http://joeyio.com 160 | 161 | 162 | name 163 | Lancy's Blog 164 | url 165 | http://gracelancy.com 166 | 167 | 168 | name 169 | I'm Allen 170 | url 171 | http://www.imallen.com 172 | 173 | 174 | name 175 | Travis' Blog 176 | url 177 | http://imi.im/ 178 | 179 | 180 | name 181 | 王中周的技术博客 182 | url 183 | http://wangzz.github.io/ 184 | 185 | 186 | name 187 | 会写代码的猪 188 | url 189 | http://jiajun.org/ 190 | 191 | 192 | name 193 | 克伟的博客 194 | url 195 | http://wangkewei.cnblogs.com/ 196 | 197 | 198 | name 199 | 摇滚诗人 200 | url 201 | http://cnblogs.com/biosli 202 | 203 | 204 | name 205 | Luke's Homepage 206 | url 207 | http://geeklu.com/ 208 | 209 | 210 | name 211 | 萧宸宇 212 | url 213 | http://iiiyu.com/ 214 | 215 | 216 | name 217 | Yuan博客 218 | url 219 | http://www.heyuan110.com/ 220 | 221 | 222 | name 223 | Shining IO 224 | url 225 | http://shiningio.com/ 226 | 227 | 228 | name 229 | YIFEIYANG--易飞扬的博客 230 | url 231 | http://www.yifeiyang.net/ 232 | 233 | 234 | name 235 | KooFrank's Blog 236 | url 237 | ttp://koofrank.com/ 238 | 239 | 240 | name 241 | hello it works 242 | url 243 | http://helloitworks.com 244 | 245 | 246 | name 247 | 码农人生 248 | url 249 | http://msching.github.io/ 250 | 251 | 252 | name 253 | 玉令天下的Blog 254 | url 255 | http://yulingtianxia.com 256 | 257 | 258 | name 259 | 不掏蜂窝的熊 260 | url 261 | http://www.hotobear.com/ 262 | 263 | 264 | name 265 | 猫·仁波切 266 | url 267 | https://andelf.github.io/ 268 | 269 | 270 | name 271 | 煲仔饭 272 | url 273 | http://ivoryxiong.org/ 274 | 275 | 276 | name 277 | 里脊串的开发随笔 278 | url 279 | http://adad184.com 280 | 281 | 282 | name 283 | Chun Tips 284 | url 285 | http://chun.tips/ 286 | 287 | 288 | name 289 | Why's blog - 汪海的实验室 290 | url 291 | http://blog.callmewhy.com/ 292 | 293 | 294 | name 295 | 土土哥的技术Blog 296 | url 297 | http://tutuge.me/ 298 | 299 | 300 | name 301 | 庞海礁的个人空间 302 | url 303 | http://www.olinone.com/ 304 | 305 | 306 | name 307 | Casa Taloyum 308 | url 309 | http://casatwy.com/ 310 | 311 | 312 | name 313 | Kenshin Cui's Blog 314 | url 315 | http://www.cnblogs.com/kenshincui/ 316 | 317 | 318 | name 319 | 技术哥的博客 320 | url 321 | http://suenblog.duapp.com/ 322 | 323 | 324 | name 325 | 老谭笔记 326 | url 327 | http://www.tanhao.me/ 328 | 329 | 330 | name 331 | coderyi 332 | url 333 | http://www.coderyi.com/ 334 | 335 | 336 | name 337 | 雷纯锋的技术博客 338 | url 339 | http://blog.leichunfeng.com) 340 | 341 | 342 | 343 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogSearchResultsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogSearchResultsTableViewController.h 3 | // OC 4 | // 5 | // Created by Apple on 9/28/15. 6 | // Copyright © 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSBlogSearchResultsTableViewController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSMutableArray *searchResults; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogSearchResultsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogSearchResultsTableViewController.m 3 | // OC 4 | // 5 | // Created by Apple on 9/28/15. 6 | // Copyright © 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "iOSBlogSearchResultsTableViewController.h" 10 | #import "iOSBlogWebViewViewController.h" 11 | 12 | @interface iOSBlogSearchResultsTableViewController () 13 | 14 | @end 15 | 16 | @implementation iOSBlogSearchResultsTableViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 28 | 29 | return [self.searchResults count]; 30 | } 31 | 32 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 33 | 34 | static NSString *CellIdentifier = @"iOSBlogSearchResultCell"; 35 | 36 | NSUInteger row = [indexPath row]; 37 | 38 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 39 | 40 | if (cell == nil) { 41 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 42 | } 43 | 44 | cell.textLabel.text = [self.searchResults[row] objectForKey:@"name"]; 45 | 46 | return cell; 47 | } 48 | 49 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 50 | [GlobalResource sharedInstance].iOSOpenSourceURLName = [self.searchResults[indexPath.row]objectForKey:@"name"]; 51 | 52 | [GlobalResource sharedInstance].iOSOpenSourceURL = [self.searchResults[indexPath.row]objectForKey:@"url"]; 53 | 54 | iOSBlogWebViewViewController * iOSblogWebViewViewController =[[iOSBlogWebViewViewController alloc]init]; 55 | [self presentViewController:[[UINavigationController alloc] initWithRootViewController: iOSblogWebViewViewController] animated:YES completion:nil]; 56 | 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogTableViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSBlogTableViewController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSArray *dataList; 14 | @property (nonatomic, strong) NSMutableArray *searchResults; 15 | @property (nonatomic, strong) UISearchController *searchController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogTableViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "iOSBlogTableViewController.h" 10 | #import "iOSBlogWebViewViewController.h" 11 | #import "iOSBlogSearchResultsTableViewController.h" 12 | 13 | @interface iOSBlogTableViewController () 14 | 15 | @end 16 | 17 | @implementation iOSBlogTableViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.title = @"博客"; 22 | 23 | NSBundle *bundle = [NSBundle mainBundle]; 24 | NSString *plistPath = [bundle pathForResource:@"iOSBlogPlist" 25 | ofType:@"plist"]; 26 | 27 | // 获取属性列表文件中的全部数据 28 | self.dataList = [[NSArray alloc] initWithContentsOfFile:plistPath]; 29 | 30 | 31 | // There's no transition in our storyboard to our search results tableview or navigation controller 32 | // so we'll have to grab it using the instantiateViewControllerWithIdentifier: method 33 | 34 | UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:@"iOSBlogSearchResultsTableSearchResultsNavController"]; 35 | 36 | // Our instance of UISearchController will use searchResults 37 | self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController]; 38 | 39 | // The searchcontroller's searchResultsUpdater property will contain our tableView. 40 | self.searchController.searchResultsUpdater = self; 41 | 42 | // The searchBar contained in XCode's storyboard is a leftover from UISearchDisplayController. 43 | // Don't use this. Instead, we'll create the searchBar programatically. 44 | self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, 45 | self.searchController.searchBar.frame.origin.y, 46 | self.searchController.searchBar.frame.size.width, 44.0); 47 | 48 | self.tableView.tableHeaderView = self.searchController.searchBar; 49 | 50 | } 51 | 52 | #pragma mark - Table view data source 53 | 54 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 55 | 56 | return 1; 57 | } 58 | 59 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 60 | 61 | return [self.dataList count]; 62 | 63 | } 64 | 65 | #pragma mark - UISearchControllerDelegate & UISearchResultsDelegate 66 | 67 | // Called when the search bar becomes first responder 68 | - (void)updateSearchResultsForSearchController:(UISearchController *)searchController { 69 | // Set searchString equal to what's typed into the searchbar 70 | NSString *searchString = self.searchController.searchBar.text; 71 | 72 | [self updateFilteredContentForAirlineName:searchString]; 73 | 74 | // If searchResultsController 75 | if (self.searchController.searchResultsController) { 76 | 77 | UINavigationController *navController = (UINavigationController *)self.searchController.searchResultsController; 78 | 79 | // Present SearchResultsTableViewController as the topViewController 80 | iOSBlogSearchResultsTableViewController *vc = (iOSBlogSearchResultsTableViewController *)navController.topViewController; 81 | 82 | // Update searchResults 83 | vc.searchResults = self.searchResults; 84 | 85 | // And reload the tableView with the new data 86 | [vc.tableView reloadData]; 87 | } 88 | } 89 | 90 | // Update self.searchResults based on searchString, which is the argument in passed to this method 91 | - (void)updateFilteredContentForAirlineName:(NSString *)airlineName { 92 | if (airlineName == nil) { 93 | 94 | // If empty the search results are the same as the original data 95 | self.searchResults = [self.dataList mutableCopy]; 96 | 97 | } else { 98 | 99 | NSMutableArray *searchResults = [[NSMutableArray alloc] init]; 100 | // NSMutableArray *searchResultsURL = [[NSMutableArray alloc] init]; 101 | 102 | // Else if the airline's name is 103 | for (NSDictionary *airline in self.dataList) { 104 | if ([airline[@"name"] containsString:airlineName]) { 105 | 106 | [searchResults addObject:airline]; 107 | } 108 | 109 | self.searchResults = searchResults; 110 | } 111 | } 112 | } 113 | 114 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 115 | 116 | static NSString *CellIdentifier = @"iOSBlogCellIdentifier"; 117 | 118 | NSUInteger row = [indexPath row]; 119 | 120 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 121 | 122 | if (cell == nil) { 123 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 124 | } 125 | 126 | NSDictionary *rowDict = [self.dataList objectAtIndex:row]; 127 | cell.textLabel.text = [rowDict objectForKey:@"name"]; 128 | // cell.detailTextLabel.text = [rowDict objectForKey:@"url"]; 129 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 130 | 131 | return cell; 132 | } 133 | 134 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 135 | 136 | NSDictionary *rowDict = [self.dataList objectAtIndex:indexPath.row]; 137 | [GlobalResource sharedInstance].iOSOpenSourceURL = [rowDict objectForKey:@"url"]; 138 | [GlobalResource sharedInstance].iOSOpenSourceURLName = [rowDict objectForKey:@"name"]; 139 | 140 | iOSBlogWebViewViewController * iOSblogWebViewViewController = [[iOSBlogWebViewViewController alloc]init]; 141 | 142 | [self presentViewController:[[UINavigationController alloc] initWithRootViewController: iOSblogWebViewViewController] animated:YES completion:nil]; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogWebViewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogWebViewViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/18/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSBlogWebViewViewController : UIViewController 12 | 13 | @property (nonatomic,strong) WKWebView * webView; 14 | 15 | @end -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSBlog/ViewController/iOSBlogWebViewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSBlogWebViewViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/18/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "iOSBlogWebViewViewController.h" 10 | #import "MBProgressHUD.h" 11 | 12 | @interface iOSBlogWebViewViewController () 13 | 14 | @end 15 | 16 | @implementation iOSBlogWebViewViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | self.title = [GlobalResource sharedInstance].iOSOpenSourceURLName; 21 | UIBarButtonItem *buttonImage = [[ UIBarButtonItem alloc ] initWithImage: 22 | [ UIImage imageNamed:@"nav_backbtn"] 23 | style: UIBarButtonItemStylePlain 24 | target: self 25 | action: @selector(navback:) 26 | ]; 27 | 28 | self.navigationItem.leftBarButtonItem = buttonImage; 29 | 30 | self.webView = [[WKWebView alloc]init]; 31 | self.webView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) ; 32 | [self.view addSubview:self.webView]; 33 | 34 | [self ReachabilityTest]; 35 | 36 | NSString * urlString= [GlobalResource sharedInstance].iOSOpenSourceURL; 37 | NSURL *url =[NSURL URLWithString:urlString]; 38 | NSURLRequest *request =[NSURLRequest requestWithURL:url]; 39 | [self.webView loadRequest:request]; 40 | self.webView.navigationDelegate = self; 41 | 42 | } 43 | 44 | -(void)navback:(UIButton *)button { 45 | [self dismissViewControllerAnimated:YES completion:nil]; 46 | } 47 | 48 | -(void)ReachabilityTest { 49 | if (![Reachability networkAvailable]) { 50 | [self.view makeToast:@"当前网络不可用,请检查网络设置" duration:5.0 position:@"center"]; 51 | } 52 | 53 | } 54 | 55 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 56 | 57 | [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 58 | } 59 | 60 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 61 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 62 | // Do something... 63 | dispatch_async(dispatch_get_main_queue(), ^{ 64 | [MBProgressHUD hideHUDForView:self.view animated:YES]; 65 | }); 66 | }); 67 | 68 | } 69 | 70 | - (void)didReceiveMemoryWarning { 71 | [super didReceiveMemoryWarning]; 72 | // Dispose of any resources that can be recreated. 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/SearchResultsTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SearchResultsTableViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/15/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SearchResultsTableViewController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSMutableArray *searchResults; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/SearchResultsTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SearchResultsTableViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/15/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "SearchResultsTableViewController.h" 10 | #import "iOSOpenSourceWebKitViewController.h" 11 | #import "iOSBlogWebViewViewController.h" 12 | 13 | @interface SearchResultsTableViewController () 14 | 15 | @end 16 | 17 | @implementation SearchResultsTableViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | 22 | } 23 | 24 | - (void)didReceiveMemoryWarning { 25 | [super didReceiveMemoryWarning]; 26 | // Dispose of any resources that can be recreated. 27 | } 28 | 29 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 30 | 31 | return [self.searchResults count]; 32 | } 33 | 34 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 35 | 36 | static NSString *CellIdentifier = @"SearchResultCell"; 37 | 38 | NSUInteger row = [indexPath row]; 39 | 40 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 41 | 42 | if (cell == nil) { 43 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 44 | } 45 | 46 | cell.textLabel.text = [self.searchResults[row] objectForKey:@"name"]; 47 | 48 | return cell; 49 | } 50 | 51 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 52 | [GlobalResource sharedInstance].iOSOpenSourceURLName = [self.searchResults[indexPath.row]objectForKey:@"name"]; 53 | 54 | [GlobalResource sharedInstance].iOSOpenSourceURL = [self.searchResults[indexPath.row]objectForKey:@"url"]; 55 | 56 | 57 | iOSBlogWebViewViewController * iOSblogWebViewViewController =[[iOSBlogWebViewViewController alloc]init]; 58 | [self presentViewController:[[UINavigationController alloc] initWithRootViewController: iOSblogWebViewViewController] animated:YES completion:nil]; 59 | 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/iOSOpenSourceViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSOpenSourceViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSOpenSourceViewController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSArray *dataList; 14 | @property (nonatomic, strong) NSMutableArray *searchResults; 15 | @property (nonatomic, strong) UISearchController *searchController; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/iOSOpenSourceViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSOpenSourceViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "iOSOpenSourceViewController.h" 10 | #import "iOSBlogWebViewViewController.h" 11 | #import "SearchResultsTableViewController.h" 12 | 13 | @interface iOSOpenSourceViewController () 14 | 15 | @end 16 | 17 | @implementation iOSOpenSourceViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.title = @"查询"; 22 | 23 | NSBundle *bundle = [NSBundle mainBundle]; 24 | NSString *plistPath = [bundle pathForResource:@"iOSOpenSourcePlist" 25 | ofType:@"plist"]; 26 | 27 | // 获取属性列表文件中的全部数据 28 | self.dataList = [[NSArray alloc] initWithContentsOfFile:plistPath]; 29 | 30 | 31 | // There's no transition in our storyboard to our search results tableview or navigation controller 32 | // so we'll have to grab it using the instantiateViewControllerWithIdentifier: method 33 | 34 | UINavigationController *searchResultsController = [[self storyboard] instantiateViewControllerWithIdentifier:@"TableSearchResultsNavController"]; 35 | 36 | // Our instance of UISearchController will use searchResults 37 | self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsController]; 38 | 39 | // The searchcontroller's searchResultsUpdater property will contain our tableView. 40 | self.searchController.searchResultsUpdater = self; 41 | 42 | // The searchBar contained in XCode's storyboard is a leftover from UISearchDisplayController. 43 | // Don't use this. Instead, we'll create the searchBar programatically. 44 | self.searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, 45 | self.searchController.searchBar.frame.origin.y, 46 | self.searchController.searchBar.frame.size.width, 44.0); 47 | 48 | self.tableView.tableHeaderView = self.searchController.searchBar; 49 | 50 | } 51 | 52 | #pragma mark - Table view data source 53 | 54 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 55 | 56 | return 1; 57 | } 58 | 59 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 60 | 61 | return [self.dataList count]; 62 | 63 | } 64 | 65 | #pragma mark - UISearchControllerDelegate & UISearchResultsDelegate 66 | 67 | // Called when the search bar becomes first responder 68 | - (void)updateSearchResultsForSearchController:(UISearchController *)searchController { 69 | // Set searchString equal to what's typed into the searchbar 70 | NSString *searchString = self.searchController.searchBar.text; 71 | 72 | [self updateFilteredContentForAirlineName:searchString]; 73 | 74 | // If searchResultsController 75 | if (self.searchController.searchResultsController) { 76 | 77 | UINavigationController *navController = (UINavigationController *)self.searchController.searchResultsController; 78 | 79 | // // Present SearchResultsTableViewController as the topViewController 80 | SearchResultsTableViewController *vc = (SearchResultsTableViewController *)navController.topViewController; 81 | // 82 | // // Update searchResults 83 | vc.searchResults = self.searchResults; 84 | // 85 | // // And reload the tableView with the new data 86 | [vc.tableView reloadData]; 87 | } 88 | } 89 | 90 | // Update self.searchResults based on searchString, which is the argument in passed to this method 91 | - (void)updateFilteredContentForAirlineName:(NSString *)airlineName { 92 | if (airlineName == nil) { 93 | 94 | // If empty the search results are the same as the original data 95 | self.searchResults = [self.dataList mutableCopy]; 96 | 97 | } else { 98 | 99 | NSMutableArray *searchResults = [[NSMutableArray alloc] init]; 100 | // NSMutableArray *searchResultsURL = [[NSMutableArray alloc] init]; 101 | 102 | // Else if the airline's name is 103 | for (NSDictionary *airline in self.dataList) { 104 | if ([airline[@"name"] containsString:airlineName]) { 105 | 106 | [searchResults addObject:airline]; 107 | } 108 | 109 | self.searchResults = searchResults; 110 | } 111 | } 112 | } 113 | 114 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 115 | 116 | static NSString *CellIdentifier = @"iOSOpenSourceCellIdentifier"; 117 | 118 | NSUInteger row = [indexPath row]; 119 | 120 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 121 | 122 | if (cell == nil) { 123 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 124 | } 125 | 126 | NSDictionary *rowDict = [self.dataList objectAtIndex:row]; 127 | cell.textLabel.text = [rowDict objectForKey:@"name"]; 128 | cell.detailTextLabel.text = [rowDict objectForKey:@"url"]; 129 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 130 | 131 | return cell; 132 | } 133 | 134 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 135 | 136 | NSDictionary *rowDict = [self.dataList objectAtIndex:indexPath.row]; 137 | [GlobalResource sharedInstance].iOSOpenSourceURL = [rowDict objectForKey:@"url"]; 138 | [GlobalResource sharedInstance].iOSOpenSourceURLName = [rowDict objectForKey:@"name"]; 139 | 140 | 141 | iOSBlogWebViewViewController * iOSblogWebViewViewController = [[iOSBlogWebViewViewController alloc]init]; 142 | 143 | [self presentViewController:[[UINavigationController alloc] initWithRootViewController: iOSblogWebViewViewController] animated:YES completion:nil]; 144 | 145 | 146 | } 147 | 148 | #pragma mark - Navigation 149 | 150 | // In a storyboard-based application, you will often want to do a little preparation before navigation 151 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 152 | 153 | } 154 | 155 | - (void)didReceiveMemoryWarning { 156 | [super didReceiveMemoryWarning]; 157 | // Dispose of any resources that can be recreated. 158 | } 159 | 160 | @end 161 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/iOSOpenSourceWebKitViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // iOSOpenSourceWebKitViewController.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface iOSOpenSourceWebKitViewController : UIViewController 12 | 13 | @property (nonatomic,strong) WKWebView * webView; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSOpenSource/ViewController/iOSOpenSourceWebKitViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // iOSOpenSourceWebKitViewController.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "iOSOpenSourceWebKitViewController.h" 10 | #import "MBProgressHUD.h" 11 | 12 | @interface iOSOpenSourceWebKitViewController () 13 | 14 | @end 15 | 16 | @implementation iOSOpenSourceWebKitViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | self.title = [GlobalResource sharedInstance].iOSOpenSourceURLName; 22 | 23 | self.webView = [[WKWebView alloc]init]; 24 | self.webView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 25 | [self.view addSubview:self.webView]; 26 | 27 | [self ReachabilityTest]; 28 | 29 | NSString * urlString= [GlobalResource sharedInstance].iOSOpenSourceURL; 30 | NSURL *url =[NSURL URLWithString:urlString]; 31 | NSURLRequest *request =[NSURLRequest requestWithURL:url]; 32 | [self.webView loadRequest:request]; 33 | self.webView.navigationDelegate = self; 34 | 35 | } 36 | 37 | -(void)ReachabilityTest{ 38 | if (![Reachability networkAvailable]) { 39 | [self.view makeToast:@"当前网络不可用,请检查网络设置" duration:5.0 position:@"center"]; 40 | } 41 | 42 | } 43 | 44 | - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation { 45 | 46 | [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 47 | 48 | } 49 | 50 | - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation { 51 | dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 52 | // Do something... 53 | dispatch_async(dispatch_get_main_queue(), ^{ 54 | [MBProgressHUD hideHUDForView:self.view animated:YES]; 55 | }); 56 | }); 57 | 58 | } 59 | 60 | - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{ 61 | 62 | } 63 | 64 | - (void)didReceiveMemoryWarning { 65 | [super didReceiveMemoryWarning]; 66 | // Dispose of any resources that can be recreated. 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Study Manual For iOS/SubItem/iOSWeiXin/WeiXinHao.json: -------------------------------------------------------------------------------- 1 | { 2 | "WeiXin" : [ 3 | { 4 | "Text": "CocoaChina 苹果开发中文社区官方微信,提供教程资源、app 推广营销、招聘、外包及培训信息、各类沙龙交流活动以及更多开发者服务。", 5 | "WeiXinHao":"cocoachinabbs" 6 | }, 7 | { 8 | "Text": "程序员的那些事是最受欢迎的程序员、IT 技术和 IT 行业相关的微信公众号之一,分享最新编程技术、经典技术分享、IT行业动态、热门编程课程、高薪技术职位、程序员的日常,更有难得一见的 IT 相亲活动。", 9 | "WeiXinHao": "iProgrammer" 10 | }, 11 | { 12 | "Text": "iOS 大全专注分享 iOS 和 Mac 相关内容,包括 iOS 和 Swift 开发技术文章、工具资源、产品设计、营销推广和行业资讯。", 13 | "WeiXinHao": "iOShub" 14 | }, 15 | { 16 | "Text": "Linux 爱好者专注分享 Linux/Unix 相关内容,包括:工具资源、使用技巧、课程、书籍等。", 17 | "WeiXinHao": "LinuxHub" 18 | }, 19 | { 20 | "Text": "", 21 | "WeiXinHao": "" 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /Study Manual For iOS/Util/GlobalResource/GlobalResource.h: -------------------------------------------------------------------------------- 1 | // 2 | // GlobalResource.h 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface GlobalResource : NSObject 13 | #define SystemThemeColor [UIColor colorWithRed:0 green:199.0f/255.0f blue:140.0f/255.0f alpha:1.0f] 14 | + (instancetype)sharedInstance; 15 | @property (nonatomic,strong) NSString * iOSOpenSourceURL; 16 | @property (nonatomic,strong) NSString * iOSOpenSourceURLName; 17 | 18 | @property (nonatomic,strong) NSMutableArray * detailArray; 19 | @property (nonatomic,strong) NSString * jsonString; 20 | @end 21 | -------------------------------------------------------------------------------- /Study Manual For iOS/Util/GlobalResource/GlobalResource.m: -------------------------------------------------------------------------------- 1 | // 2 | // GlobalResource.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import "GlobalResource.h" 10 | 11 | @implementation GlobalResource 12 | 13 | __strong static GlobalResource *share = nil; 14 | 15 | + (instancetype)sharedInstance 16 | { 17 | static dispatch_once_t pred = 0; 18 | dispatch_once(&pred, ^{ 19 | share = [[super allocWithZone:NULL] init]; 20 | }); 21 | return share; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Study Manual For iOS/Util/Toast/Toast+UIView.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | 3 | Toast+UIView.h 4 | Toast 5 | Version 2.2 6 | 7 | Copyright (c) 2013 Charles Scalesse. 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a 10 | copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | ***************************************************************************/ 29 | 30 | 31 | #import 32 | 33 | @interface UIView (Toast) 34 | 35 | // each makeToast method creates a view and displays it as toast 36 | - (void)makeToast:(NSString *)message; 37 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position; 38 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position image:(UIImage *)image; 39 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title; 40 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)interval position:(id)position title:(NSString *)title image:(UIImage *)image; 41 | 42 | // displays toast with an activity spinner 43 | - (void)makeToastActivity; 44 | - (void)makeToastActivity:(id)position; 45 | - (void)hideToastActivity; 46 | 47 | // the showToast methods display any view as toast 48 | - (void)showToast:(UIView *)toast; 49 | - (void)showToast:(UIView *)toast duration:(NSTimeInterval)interval position:(id)point; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Study Manual For iOS/Util/Toast/Toast+UIView.m: -------------------------------------------------------------------------------- 1 | // 2 | // Toast+UIView.m 3 | // Toast 4 | // Version 2.2 5 | // 6 | // Copyright 2013 Charles Scalesse. 7 | // 8 | 9 | #import "Toast+UIView.h" 10 | #import 11 | #import 12 | 13 | /* 14 | * CONFIGURE THESE VALUES TO ADJUST LOOK & FEEL, 15 | * DISPLAY DURATION, ETC. 16 | */ 17 | 18 | // general appearance 19 | static const CGFloat CSToastMaxWidth = 0.8; // 80% of parent view width 20 | static const CGFloat CSToastMaxHeight = 0.8; // 80% of parent view height 21 | static const CGFloat CSToastHorizontalPadding = 10.0; 22 | static const CGFloat CSToastVerticalPadding = 10.0; 23 | static const CGFloat CSToastCornerRadius = 10.0; 24 | static const CGFloat CSToastOpacity = 0.8; 25 | static const CGFloat CSToastFontSize = 16.0; 26 | static const CGFloat CSToastMaxTitleLines = 0; 27 | static const CGFloat CSToastMaxMessageLines = 0; 28 | static const NSTimeInterval CSToastFadeDuration = 0.2; 29 | 30 | // shadow appearance 31 | static const CGFloat CSToastShadowOpacity = 0.8; 32 | static const CGFloat CSToastShadowRadius = 6.0; 33 | static const CGSize CSToastShadowOffset = { 4.0, 4.0 }; 34 | static const BOOL CSToastDisplayShadow = YES; 35 | 36 | // display duration and position 37 | static const NSString * CSToastDefaultPosition = @"bottom"; 38 | static const NSTimeInterval CSToastDefaultDuration = 3.0; 39 | 40 | // image view size 41 | static const CGFloat CSToastImageViewWidth = 80.0; 42 | static const CGFloat CSToastImageViewHeight = 80.0; 43 | 44 | // activity 45 | static const CGFloat CSToastActivityWidth = 100.0; 46 | static const CGFloat CSToastActivityHeight = 100.0; 47 | static const NSString * CSToastActivityDefaultPosition = @"center"; 48 | 49 | // interaction 50 | static const BOOL CSToastHidesOnTap = YES; // excludes activity views 51 | 52 | // associative reference keys 53 | static const NSString * CSToastTimerKey = @"CSToastTimerKey"; 54 | static const NSString * CSToastActivityViewKey = @"CSToastActivityViewKey"; 55 | 56 | @interface UIView (ToastPrivate) 57 | 58 | - (void)hideToast:(UIView *)toast; 59 | - (void)toastTimerDidFinish:(NSTimer *)timer; 60 | - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer; 61 | - (CGPoint)centerPointForPosition:(id)position withToast:(UIView *)toast; 62 | - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image; 63 | - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode; 64 | 65 | @end 66 | 67 | 68 | @implementation UIView (Toast) 69 | 70 | #pragma mark - Toast Methods 71 | 72 | - (void)makeToast:(NSString *)message { 73 | [self makeToast:message duration:CSToastDefaultDuration position:CSToastDefaultPosition]; 74 | } 75 | 76 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position { 77 | UIView *toast = [self viewForMessage:message title:nil image:nil]; 78 | [self showToast:toast duration:duration position:position]; 79 | } 80 | 81 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title { 82 | UIView *toast = [self viewForMessage:message title:title image:nil]; 83 | [self showToast:toast duration:duration position:position]; 84 | } 85 | 86 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position image:(UIImage *)image { 87 | UIView *toast = [self viewForMessage:message title:nil image:image]; 88 | [self showToast:toast duration:duration position:position]; 89 | } 90 | 91 | - (void)makeToast:(NSString *)message duration:(NSTimeInterval)duration position:(id)position title:(NSString *)title image:(UIImage *)image { 92 | UIView *toast = [self viewForMessage:message title:title image:image]; 93 | [self showToast:toast duration:duration position:position]; 94 | } 95 | 96 | - (void)showToast:(UIView *)toast { 97 | [self showToast:toast duration:CSToastDefaultDuration position:CSToastDefaultPosition]; 98 | } 99 | 100 | - (void)showToast:(UIView *)toast duration:(NSTimeInterval)duration position:(id)point { 101 | toast.center = [self centerPointForPosition:point withToast:toast]; 102 | toast.alpha = 0.0; 103 | 104 | if (CSToastHidesOnTap) { 105 | UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:toast action:@selector(handleToastTapped:)]; 106 | [toast addGestureRecognizer:recognizer]; 107 | toast.userInteractionEnabled = YES; 108 | toast.exclusiveTouch = YES; 109 | } 110 | 111 | [self addSubview:toast]; 112 | 113 | [UIView animateWithDuration:CSToastFadeDuration 114 | delay:0.0 115 | options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) 116 | animations:^{ 117 | toast.alpha = 1.0; 118 | } completion:^(BOOL finished) { 119 | NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(toastTimerDidFinish:) userInfo:toast repeats:NO]; 120 | // associate the timer with the toast view 121 | objc_setAssociatedObject (toast, &CSToastTimerKey, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 122 | }]; 123 | 124 | } 125 | 126 | - (void)hideToast:(UIView *)toast { 127 | [UIView animateWithDuration:CSToastFadeDuration 128 | delay:0.0 129 | options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) 130 | animations:^{ 131 | toast.alpha = 0.0; 132 | } completion:^(BOOL finished) { 133 | [toast removeFromSuperview]; 134 | }]; 135 | } 136 | 137 | #pragma mark - Events 138 | 139 | - (void)toastTimerDidFinish:(NSTimer *)timer { 140 | [self hideToast:(UIView *)timer.userInfo]; 141 | } 142 | 143 | - (void)handleToastTapped:(UITapGestureRecognizer *)recognizer { 144 | NSTimer *timer = (NSTimer *)objc_getAssociatedObject(self, &CSToastTimerKey); 145 | [timer invalidate]; 146 | 147 | [self hideToast:recognizer.view]; 148 | } 149 | 150 | #pragma mark - Toast Activity Methods 151 | 152 | - (void)makeToastActivity { 153 | [self makeToastActivity:CSToastActivityDefaultPosition]; 154 | } 155 | 156 | - (void)makeToastActivity:(id)position { 157 | // sanity 158 | UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); 159 | if (existingActivityView != nil) return; 160 | 161 | UIView *activityView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CSToastActivityWidth, CSToastActivityHeight)]; 162 | activityView.center = [self centerPointForPosition:position withToast:activityView]; 163 | activityView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity]; 164 | activityView.alpha = 0.0; 165 | activityView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); 166 | activityView.layer.cornerRadius = CSToastCornerRadius; 167 | 168 | if (CSToastDisplayShadow) { 169 | activityView.layer.shadowColor = [UIColor blackColor].CGColor; 170 | activityView.layer.shadowOpacity = CSToastShadowOpacity; 171 | activityView.layer.shadowRadius = CSToastShadowRadius; 172 | activityView.layer.shadowOffset = CSToastShadowOffset; 173 | } 174 | 175 | UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 176 | activityIndicatorView.center = CGPointMake(activityView.bounds.size.width / 2, activityView.bounds.size.height / 2); 177 | [activityView addSubview:activityIndicatorView]; 178 | [activityIndicatorView startAnimating]; 179 | 180 | // associate the activity view with self 181 | objc_setAssociatedObject (self, &CSToastActivityViewKey, activityView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 182 | 183 | [self addSubview:activityView]; 184 | 185 | [UIView animateWithDuration:CSToastFadeDuration 186 | delay:0.0 187 | options:UIViewAnimationOptionCurveEaseOut 188 | animations:^{ 189 | activityView.alpha = 0.6; 190 | } completion:nil]; 191 | } 192 | 193 | - (void)hideToastActivity { 194 | UIView *existingActivityView = (UIView *)objc_getAssociatedObject(self, &CSToastActivityViewKey); 195 | if (existingActivityView != nil) { 196 | [UIView animateWithDuration:CSToastFadeDuration 197 | delay:0.0 198 | options:(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) 199 | animations:^{ 200 | existingActivityView.alpha = 0.0; 201 | } completion:^(BOOL finished) { 202 | [existingActivityView removeFromSuperview]; 203 | objc_setAssociatedObject (self, &CSToastActivityViewKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 204 | }]; 205 | } 206 | } 207 | 208 | #pragma mark - Helpers 209 | 210 | - (CGPoint)centerPointForPosition:(id)point withToast:(UIView *)toast { 211 | if([point isKindOfClass:[NSString class]]) { 212 | // convert string literals @"top", @"bottom", @"center", or any point wrapped in an NSValue object into a CGPoint 213 | if([point caseInsensitiveCompare:@"top"] == NSOrderedSame) { 214 | return CGPointMake(self.bounds.size.width/2, (toast.frame.size.height / 2) + CSToastVerticalPadding); 215 | } else if([point caseInsensitiveCompare:@"bottom"] == NSOrderedSame) { 216 | return CGPointMake(self.bounds.size.width/2, (self.bounds.size.height - (toast.frame.size.height / 2)) - CSToastVerticalPadding); 217 | } else if([point caseInsensitiveCompare:@"center"] == NSOrderedSame) { 218 | return CGPointMake(self.bounds.size.width / 2, self.bounds.size.height / 2); 219 | } 220 | } else if ([point isKindOfClass:[NSValue class]]) { 221 | return [point CGPointValue]; 222 | } 223 | 224 | NSLog(@"Warning: Invalid position for toast."); 225 | return [self centerPointForPosition:CSToastDefaultPosition withToast:toast]; 226 | } 227 | //修改为新的方法 228 | - (CGSize)sizeForString:(NSString *)string font:(UIFont *)font constrainedToSize:(CGSize)constrainedSize lineBreakMode:(NSLineBreakMode)lineBreakMode { 229 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 230 | paragraphStyle.lineBreakMode = lineBreakMode; 231 | NSDictionary *attributes = @{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraphStyle}; 232 | CGRect boundingRect = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil]; 233 | return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height)); 234 | } 235 | 236 | - (UIView *)viewForMessage:(NSString *)message title:(NSString *)title image:(UIImage *)image { 237 | // sanity 238 | if((message == nil) && (title == nil) && (image == nil)) return nil; 239 | 240 | // dynamically build a toast view with any combination of message, title, & image. 241 | UILabel *messageLabel = nil; 242 | UILabel *titleLabel = nil; 243 | UIImageView *imageView = nil; 244 | 245 | // create the parent view 246 | UIView *wrapperView = [[UIView alloc] init]; 247 | wrapperView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); 248 | wrapperView.layer.cornerRadius = CSToastCornerRadius; 249 | 250 | if (CSToastDisplayShadow) { 251 | wrapperView.layer.shadowColor = [UIColor blackColor].CGColor; 252 | wrapperView.layer.shadowOpacity = CSToastShadowOpacity; 253 | wrapperView.layer.shadowRadius = CSToastShadowRadius; 254 | wrapperView.layer.shadowOffset = CSToastShadowOffset; 255 | } 256 | 257 | wrapperView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:CSToastOpacity]; 258 | 259 | if(image != nil) { 260 | imageView = [[UIImageView alloc] initWithImage:image]; 261 | imageView.contentMode = UIViewContentModeScaleAspectFit; 262 | imageView.frame = CGRectMake(CSToastHorizontalPadding, CSToastVerticalPadding, CSToastImageViewWidth, CSToastImageViewHeight); 263 | } 264 | 265 | CGFloat imageWidth, imageHeight, imageLeft; 266 | 267 | // the imageView frame values will be used to size & position the other views 268 | if(imageView != nil) { 269 | imageWidth = imageView.bounds.size.width; 270 | imageHeight = imageView.bounds.size.height; 271 | imageLeft = CSToastHorizontalPadding; 272 | } else { 273 | imageWidth = imageHeight = imageLeft = 0.0; 274 | } 275 | 276 | if (title != nil) { 277 | titleLabel = [[UILabel alloc] init]; 278 | titleLabel.numberOfLines = CSToastMaxTitleLines; 279 | titleLabel.font = [UIFont boldSystemFontOfSize:CSToastFontSize]; 280 | titleLabel.textAlignment = NSTextAlignmentLeft; 281 | titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 282 | titleLabel.textColor = [UIColor whiteColor]; 283 | titleLabel.backgroundColor = [UIColor clearColor]; 284 | titleLabel.alpha = 1.0; 285 | titleLabel.text = title; 286 | 287 | // size the title label according to the length of the text 288 | CGSize maxSizeTitle = CGSizeMake((self.bounds.size.width * CSToastMaxWidth) - imageWidth, self.bounds.size.height * CSToastMaxHeight); 289 | CGSize expectedSizeTitle = [self sizeForString:title font:titleLabel.font constrainedToSize:maxSizeTitle lineBreakMode:titleLabel.lineBreakMode]; 290 | titleLabel.frame = CGRectMake(0.0, 0.0, expectedSizeTitle.width, expectedSizeTitle.height); 291 | } 292 | 293 | if (message != nil) { 294 | messageLabel = [[UILabel alloc] init]; 295 | messageLabel.numberOfLines = CSToastMaxMessageLines; 296 | messageLabel.font = [UIFont systemFontOfSize:CSToastFontSize]; 297 | messageLabel.lineBreakMode = NSLineBreakByWordWrapping; 298 | messageLabel.textColor = [UIColor whiteColor]; 299 | messageLabel.backgroundColor = [UIColor clearColor]; 300 | messageLabel.alpha = 1.0; 301 | messageLabel.text = message; 302 | 303 | // size the message label according to the length of the text 304 | CGSize maxSizeMessage = CGSizeMake((self.bounds.size.width * CSToastMaxWidth) - imageWidth, self.bounds.size.height * CSToastMaxHeight); 305 | CGSize expectedSizeMessage = [self sizeForString:message font:messageLabel.font constrainedToSize:maxSizeMessage lineBreakMode:messageLabel.lineBreakMode]; 306 | messageLabel.frame = CGRectMake(0.0, 0.0, expectedSizeMessage.width, expectedSizeMessage.height); 307 | } 308 | 309 | // titleLabel frame values 310 | CGFloat titleWidth, titleHeight, titleTop, titleLeft; 311 | 312 | if(titleLabel != nil) { 313 | titleWidth = titleLabel.bounds.size.width; 314 | titleHeight = titleLabel.bounds.size.height; 315 | titleTop = CSToastVerticalPadding; 316 | titleLeft = imageLeft + imageWidth + CSToastHorizontalPadding; 317 | } else { 318 | titleWidth = titleHeight = titleTop = titleLeft = 0.0; 319 | } 320 | 321 | // messageLabel frame values 322 | CGFloat messageWidth, messageHeight, messageLeft, messageTop; 323 | 324 | if(messageLabel != nil) { 325 | messageWidth = messageLabel.bounds.size.width; 326 | messageHeight = messageLabel.bounds.size.height; 327 | messageLeft = imageLeft + imageWidth + CSToastHorizontalPadding; 328 | messageTop = titleTop + titleHeight + CSToastVerticalPadding; 329 | } else { 330 | messageWidth = messageHeight = messageLeft = messageTop = 0.0; 331 | } 332 | 333 | CGFloat longerWidth = MAX(titleWidth, messageWidth); 334 | CGFloat longerLeft = MAX(titleLeft, messageLeft); 335 | 336 | // wrapper width uses the longerWidth or the image width, whatever is larger. same logic applies to the wrapper height 337 | CGFloat wrapperWidth = MAX((imageWidth + (CSToastHorizontalPadding * 2)), (longerLeft + longerWidth + CSToastHorizontalPadding)); 338 | CGFloat wrapperHeight = MAX((messageTop + messageHeight + CSToastVerticalPadding), (imageHeight + (CSToastVerticalPadding * 2))); 339 | 340 | wrapperView.frame = CGRectMake(0.0, 0.0, wrapperWidth, wrapperHeight); 341 | 342 | if(titleLabel != nil) { 343 | titleLabel.frame = CGRectMake(titleLeft, titleTop, titleWidth, titleHeight); 344 | [wrapperView addSubview:titleLabel]; 345 | } 346 | 347 | if(messageLabel != nil) { 348 | messageLabel.frame = CGRectMake(messageLeft, messageTop, messageWidth, messageHeight); 349 | [wrapperView addSubview:messageLabel]; 350 | } 351 | 352 | if(imageView != nil) { 353 | [wrapperView addSubview:imageView]; 354 | } 355 | 356 | return wrapperView; 357 | } 358 | 359 | @end 360 | -------------------------------------------------------------------------------- /Study Manual For iOS/Util/WebKit/Reachability.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Tony Million. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import 29 | #import 30 | 31 | #import 32 | #import 33 | #import 34 | #import 35 | #import 36 | #import 37 | 38 | /** 39 | * Does ARC support GCD objects? 40 | * It does if the minimum deployment target is iOS 6+ or Mac OS X 8+ 41 | * 42 | * @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h 43 | **/ 44 | #if OS_OBJECT_USE_OBJC 45 | #define NEEDS_DISPATCH_RETAIN_RELEASE 0 46 | #else 47 | #define NEEDS_DISPATCH_RETAIN_RELEASE 1 48 | #endif 49 | 50 | /** 51 | * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. 52 | * 53 | * @see http://nshipster.com/ns_enum-ns_options/ 54 | **/ 55 | #ifndef NS_ENUM 56 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 57 | #endif 58 | 59 | extern NSString *const kReachabilityChangedNotification; 60 | 61 | typedef NS_ENUM(NSInteger, NetworkStatus) { 62 | // Apple NetworkStatus Compatible Names. 63 | NotReachable = 0, 64 | ReachableViaWiFi = 2, 65 | ReachableViaWWAN = 1 66 | }; 67 | 68 | @class Reachability; 69 | 70 | typedef void (^NetworkReachable)(Reachability * reachability); 71 | typedef void (^NetworkUnreachable)(Reachability * reachability); 72 | 73 | @interface Reachability : NSObject 74 | 75 | @property (nonatomic, copy) NetworkReachable reachableBlock; 76 | @property (nonatomic, copy) NetworkUnreachable unreachableBlock; 77 | 78 | 79 | @property (nonatomic, assign) BOOL reachableOnWWAN; 80 | 81 | +(Reachability*)reachabilityWithHostname:(NSString*)hostname; 82 | // This is identical to the function above, but is here to maintain 83 | //compatibility with Apples original code. (see .m) 84 | +(Reachability*)reachabilityWithHostName:(NSString*)hostname; 85 | +(Reachability*)reachabilityForInternetConnection; 86 | +(Reachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress; 87 | +(Reachability*)reachabilityForLocalWiFi; 88 | +(BOOL)networkAvailable; 89 | -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref; 90 | 91 | -(BOOL)startNotifier; 92 | -(void)stopNotifier; 93 | 94 | -(BOOL)isReachable; 95 | -(BOOL)isReachableViaWWAN; 96 | -(BOOL)isReachableViaWiFi; 97 | 98 | // WWAN may be available, but not active until a connection has been established. 99 | // WiFi may require a connection for VPN on Demand. 100 | -(BOOL)isConnectionRequired; // Identical DDG variant. 101 | -(BOOL)connectionRequired; // Apple's routine. 102 | // Dynamic, on demand connection? 103 | -(BOOL)isConnectionOnDemand; 104 | // Is user intervention required? 105 | -(BOOL)isInterventionRequired; 106 | 107 | -(NetworkStatus)currentReachabilityStatus; 108 | -(SCNetworkReachabilityFlags)reachabilityFlags; 109 | -(NSString*)currentReachabilityString; 110 | -(NSString*)currentReachabilityFlags; 111 | 112 | @end 113 | -------------------------------------------------------------------------------- /Study Manual For iOS/Util/WebKit/Reachability.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2011, Tony Million. 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 | POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #import "Reachability.h" 29 | 30 | 31 | NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification"; 32 | 33 | @interface Reachability () 34 | 35 | @property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef; 36 | 37 | 38 | #if NEEDS_DISPATCH_RETAIN_RELEASE 39 | @property (nonatomic, assign) dispatch_queue_t reachabilitySerialQueue; 40 | #else 41 | @property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue; 42 | #endif 43 | 44 | 45 | @property (nonatomic, strong) id reachabilityObject; 46 | 47 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags; 48 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags; 49 | 50 | @end 51 | 52 | static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) 53 | { 54 | return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c", 55 | #if TARGET_OS_IPHONE 56 | (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', 57 | #else 58 | 'X', 59 | #endif 60 | (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', 61 | (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', 62 | (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', 63 | (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', 64 | (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', 65 | (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', 66 | (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', 67 | (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-']; 68 | } 69 | 70 | // Start listening for reachability notifications on the current run loop 71 | static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) 72 | { 73 | #pragma unused (target) 74 | #if __has_feature(objc_arc) 75 | Reachability *reachability = ((__bridge Reachability*)info); 76 | #else 77 | Reachability *reachability = ((Reachability*)info); 78 | #endif 79 | 80 | // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool, 81 | // but what the heck eh? 82 | @autoreleasepool 83 | { 84 | [reachability reachabilityChanged:flags]; 85 | } 86 | } 87 | 88 | 89 | @implementation Reachability 90 | 91 | @synthesize reachabilityRef; 92 | @synthesize reachabilitySerialQueue; 93 | 94 | @synthesize reachableOnWWAN; 95 | 96 | @synthesize reachableBlock; 97 | @synthesize unreachableBlock; 98 | 99 | @synthesize reachabilityObject; 100 | 101 | #pragma mark - Class Constructor Methods 102 | 103 | +(BOOL)networkAvailable 104 | { 105 | if ([[Reachability reachabilityForLocalWiFi] currentReachabilityStatus] != NotReachable) { 106 | return YES; 107 | } 108 | if ([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] != NotReachable) { 109 | return YES; 110 | } 111 | return NO; 112 | } 113 | +(Reachability*)reachabilityWithHostName:(NSString*)hostname 114 | { 115 | return [Reachability reachabilityWithHostname:hostname]; 116 | } 117 | 118 | +(Reachability*)reachabilityWithHostname:(NSString*)hostname 119 | { 120 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]); 121 | if (ref) 122 | { 123 | id reachability = [[self alloc] initWithReachabilityRef:ref]; 124 | 125 | #if __has_feature(objc_arc) 126 | return reachability; 127 | #else 128 | return [reachability autorelease]; 129 | #endif 130 | 131 | } 132 | 133 | return nil; 134 | } 135 | 136 | +(Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress 137 | { 138 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); 139 | if (ref) 140 | { 141 | id reachability = [[self alloc] initWithReachabilityRef:ref]; 142 | 143 | #if __has_feature(objc_arc) 144 | return reachability; 145 | #else 146 | return [reachability autorelease]; 147 | #endif 148 | } 149 | 150 | return nil; 151 | } 152 | 153 | +(Reachability *)reachabilityForInternetConnection 154 | { 155 | struct sockaddr_in zeroAddress; 156 | bzero(&zeroAddress, sizeof(zeroAddress)); 157 | zeroAddress.sin_len = sizeof(zeroAddress); 158 | zeroAddress.sin_family = AF_INET; 159 | 160 | return [self reachabilityWithAddress:&zeroAddress]; 161 | } 162 | 163 | +(Reachability*)reachabilityForLocalWiFi 164 | { 165 | struct sockaddr_in localWifiAddress; 166 | bzero(&localWifiAddress, sizeof(localWifiAddress)); 167 | localWifiAddress.sin_len = sizeof(localWifiAddress); 168 | localWifiAddress.sin_family = AF_INET; 169 | // IN_LINKLOCALNETNUM is defined in as 169.254.0.0 170 | localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); 171 | 172 | return [self reachabilityWithAddress:&localWifiAddress]; 173 | } 174 | 175 | 176 | // Initialization methods 177 | 178 | -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref 179 | { 180 | self = [super init]; 181 | if (self != nil) 182 | { 183 | self.reachableOnWWAN = YES; 184 | self.reachabilityRef = ref; 185 | } 186 | 187 | return self; 188 | } 189 | 190 | -(void)dealloc 191 | { 192 | [self stopNotifier]; 193 | 194 | if(self.reachabilityRef) 195 | { 196 | CFRelease(self.reachabilityRef); 197 | self.reachabilityRef = nil; 198 | } 199 | 200 | self.reachableBlock = nil; 201 | self.unreachableBlock = nil; 202 | 203 | #if !(__has_feature(objc_arc)) 204 | [super dealloc]; 205 | #endif 206 | 207 | 208 | } 209 | 210 | #pragma mark - Notifier Methods 211 | 212 | // Notifier 213 | // NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD 214 | // - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS. 215 | // INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want) 216 | 217 | -(BOOL)startNotifier 218 | { 219 | SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL }; 220 | 221 | // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves 222 | // woah 223 | self.reachabilityObject = self; 224 | 225 | 226 | 227 | // First, we need to create a serial queue. 228 | // We allocate this once for the lifetime of the notifier. 229 | self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL); 230 | if(!self.reachabilitySerialQueue) 231 | { 232 | return NO; 233 | } 234 | 235 | #if __has_feature(objc_arc) 236 | context.info = (__bridge void *)self; 237 | #else 238 | context.info = (void *)self; 239 | #endif 240 | 241 | if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context)) 242 | { 243 | #ifdef DEBUG 244 | NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError())); 245 | #endif 246 | 247 | // Clear out the dispatch queue 248 | if(self.reachabilitySerialQueue) 249 | { 250 | #if NEEDS_DISPATCH_RETAIN_RELEASE 251 | dispatch_release(self.reachabilitySerialQueue); 252 | #endif 253 | self.reachabilitySerialQueue = nil; 254 | } 255 | 256 | self.reachabilityObject = nil; 257 | 258 | return NO; 259 | } 260 | 261 | // Set it as our reachability queue, which will retain the queue 262 | if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue)) 263 | { 264 | #ifdef DEBUG 265 | NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError())); 266 | #endif 267 | 268 | // UH OH - FAILURE! 269 | 270 | // First stop, any callbacks! 271 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); 272 | 273 | // Then clear out the dispatch queue. 274 | if(self.reachabilitySerialQueue) 275 | { 276 | #if NEEDS_DISPATCH_RETAIN_RELEASE 277 | dispatch_release(self.reachabilitySerialQueue); 278 | #endif 279 | self.reachabilitySerialQueue = nil; 280 | } 281 | 282 | self.reachabilityObject = nil; 283 | 284 | return NO; 285 | } 286 | 287 | return YES; 288 | } 289 | 290 | -(void)stopNotifier 291 | { 292 | // First stop, any callbacks! 293 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); 294 | 295 | // Unregister target from the GCD serial dispatch queue. 296 | SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL); 297 | 298 | if(self.reachabilitySerialQueue) 299 | { 300 | #if NEEDS_DISPATCH_RETAIN_RELEASE 301 | dispatch_release(self.reachabilitySerialQueue); 302 | #endif 303 | self.reachabilitySerialQueue = nil; 304 | } 305 | 306 | self.reachabilityObject = nil; 307 | } 308 | 309 | #pragma mark - reachability tests 310 | 311 | // This is for the case where you flick the airplane mode; 312 | // you end up getting something like this: 313 | //Reachability: WR ct----- 314 | //Reachability: -- ------- 315 | //Reachability: WR ct----- 316 | //Reachability: -- ------- 317 | // We treat this as 4 UNREACHABLE triggers - really apple should do better than this 318 | 319 | #define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) 320 | 321 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags 322 | { 323 | BOOL connectionUP = YES; 324 | 325 | if(!(flags & kSCNetworkReachabilityFlagsReachable)) 326 | connectionUP = NO; 327 | 328 | if( (flags & testcase) == testcase ) 329 | connectionUP = NO; 330 | 331 | #if TARGET_OS_IPHONE 332 | if(flags & kSCNetworkReachabilityFlagsIsWWAN) 333 | { 334 | // We're on 3G. 335 | if(!self.reachableOnWWAN) 336 | { 337 | // We don't want to connect when on 3G. 338 | connectionUP = NO; 339 | } 340 | } 341 | #endif 342 | 343 | return connectionUP; 344 | } 345 | 346 | -(BOOL)isReachable 347 | { 348 | SCNetworkReachabilityFlags flags; 349 | 350 | if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) 351 | return NO; 352 | 353 | return [self isReachableWithFlags:flags]; 354 | } 355 | 356 | -(BOOL)isReachableViaWWAN 357 | { 358 | #if TARGET_OS_IPHONE 359 | 360 | SCNetworkReachabilityFlags flags = 0; 361 | 362 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 363 | { 364 | // Check we're REACHABLE 365 | if(flags & kSCNetworkReachabilityFlagsReachable) 366 | { 367 | // Now, check we're on WWAN 368 | if(flags & kSCNetworkReachabilityFlagsIsWWAN) 369 | { 370 | return YES; 371 | } 372 | } 373 | } 374 | #endif 375 | 376 | return NO; 377 | } 378 | 379 | -(BOOL)isReachableViaWiFi 380 | { 381 | SCNetworkReachabilityFlags flags = 0; 382 | 383 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 384 | { 385 | // Check we're reachable 386 | if((flags & kSCNetworkReachabilityFlagsReachable)) 387 | { 388 | #if TARGET_OS_IPHONE 389 | // Check we're NOT on WWAN 390 | if((flags & kSCNetworkReachabilityFlagsIsWWAN)) 391 | { 392 | return NO; 393 | } 394 | #endif 395 | return YES; 396 | } 397 | } 398 | 399 | return NO; 400 | } 401 | 402 | 403 | // WWAN may be available, but not active until a connection has been established. 404 | // WiFi may require a connection for VPN on Demand. 405 | -(BOOL)isConnectionRequired 406 | { 407 | return [self connectionRequired]; 408 | } 409 | 410 | -(BOOL)connectionRequired 411 | { 412 | SCNetworkReachabilityFlags flags; 413 | 414 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 415 | { 416 | return (flags & kSCNetworkReachabilityFlagsConnectionRequired); 417 | } 418 | 419 | return NO; 420 | } 421 | 422 | // Dynamic, on demand connection? 423 | -(BOOL)isConnectionOnDemand 424 | { 425 | SCNetworkReachabilityFlags flags; 426 | 427 | if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 428 | { 429 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && 430 | (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand))); 431 | } 432 | 433 | return NO; 434 | } 435 | 436 | // Is user intervention required? 437 | -(BOOL)isInterventionRequired 438 | { 439 | SCNetworkReachabilityFlags flags; 440 | 441 | if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 442 | { 443 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && 444 | (flags & kSCNetworkReachabilityFlagsInterventionRequired)); 445 | } 446 | 447 | return NO; 448 | } 449 | 450 | 451 | #pragma mark - reachability status stuff 452 | 453 | -(NetworkStatus)currentReachabilityStatus 454 | { 455 | if([self isReachable]) 456 | { 457 | if([self isReachableViaWiFi]) 458 | return ReachableViaWiFi; 459 | 460 | #if TARGET_OS_IPHONE 461 | return ReachableViaWWAN; 462 | #endif 463 | } 464 | 465 | return NotReachable; 466 | } 467 | 468 | -(SCNetworkReachabilityFlags)reachabilityFlags 469 | { 470 | SCNetworkReachabilityFlags flags = 0; 471 | 472 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) 473 | { 474 | return flags; 475 | } 476 | 477 | return 0; 478 | } 479 | 480 | -(NSString*)currentReachabilityString 481 | { 482 | NetworkStatus temp = [self currentReachabilityStatus]; 483 | 484 | if(temp == reachableOnWWAN) 485 | { 486 | // Updated for the fact that we have CDMA phones now! 487 | return NSLocalizedString(@"Cellular", @""); 488 | } 489 | if (temp == ReachableViaWiFi) 490 | { 491 | return NSLocalizedString(@"WiFi", @""); 492 | } 493 | 494 | return NSLocalizedString(@"No Connection", @""); 495 | } 496 | 497 | -(NSString*)currentReachabilityFlags 498 | { 499 | return reachabilityFlags([self reachabilityFlags]); 500 | } 501 | 502 | #pragma mark - Callback function calls this method 503 | 504 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags 505 | { 506 | if([self isReachableWithFlags:flags]) 507 | { 508 | if(self.reachableBlock) 509 | { 510 | self.reachableBlock(self); 511 | } 512 | } 513 | else 514 | { 515 | if(self.unreachableBlock) 516 | { 517 | self.unreachableBlock(self); 518 | } 519 | } 520 | 521 | // this makes sure the change notification happens on the MAIN THREAD 522 | dispatch_async(dispatch_get_main_queue(), ^{ 523 | [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification 524 | object:self]; 525 | }); 526 | } 527 | 528 | #pragma mark - Debug Description 529 | 530 | - (NSString *) description 531 | { 532 | NSString *description = [NSString stringWithFormat:@"<%@: %#x>", 533 | NSStringFromClass([self class]), (unsigned int) self]; 534 | return description; 535 | } 536 | 537 | 538 | @end 539 | -------------------------------------------------------------------------------- /Study Manual For iOS/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnbin/iOSManual/cb4ded911b847b3c0a7d24ff8a65cc2c9352104d/Study Manual For iOS/logo.png -------------------------------------------------------------------------------- /Study Manual For iOS/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Study Manual For iOS 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. 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 | -------------------------------------------------------------------------------- /Study Manual For iOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | cc.huaxun.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Study Manual For iOSTests/Study_Manual_For_iOSTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // Study_Manual_For_iOSTests.m 3 | // Study Manual For iOSTests 4 | // 5 | // Created by Apple on 9/14/15. 6 | // Copyright (c) 2015 广东华讯网络投资有限公司. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface Study_Manual_For_iOSTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation Study_Manual_For_iOSTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------