└── README.md /README.md: -------------------------------------------------------------------------------- 1 | ``*** 2 | ![](http://upload-images.jianshu.io/upload_images/790890-e9aee1a12c8b272a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 3 | **1,打印View所有子视图** 4 | ``` 5 | po [[self view]recursiveDescription] 6 | ``` 7 | **2,layoutSubviews调用的调用时机** 8 | ``` 9 | * 当视图第一次显示的时候会被调用。 10 | * 添加子视图也会调用这个方法。 11 | * 当本视图的大小发生改变的时候是会调用的。 12 | * 当子视图的frame发生改变的时候是会调用的。 13 | * 当删除子视图的时候是会调用的. 14 | ``` 15 | **3,NSString过滤特殊字符** 16 | ``` 17 | // 定义一个特殊字符的集合 18 | NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString: 19 | @"@/:;()¥「」"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\""]; 20 | // 过滤字符串的特殊字符 21 | NSString *newString = [trimString stringByTrimmingCharactersInSet:set]; 22 | ``` 23 | **4,TransForm属性** 24 | ``` 25 | //平移按钮 26 | CGAffineTransform transForm = self.buttonView.transform; 27 | self.buttonView.transform = CGAffineTransformTranslate(transForm, 10, 0); 28 | 29 | //旋转按钮 30 | CGAffineTransform transForm = self.buttonView.transform; 31 | self.buttonView.transform = CGAffineTransformRotate(transForm, M_PI_4); 32 | 33 | //缩放按钮 34 | self.buttonView.transform = CGAffineTransformScale(transForm, 1.2, 1.2); 35 | 36 | //初始化复位 37 | self.buttonView.transform = CGAffineTransformIdentity; 38 | ``` 39 | **5,去掉分割线多余15像素** 40 | ``` 41 | 首先在viewDidLoad方法加入以下代码: 42 |  if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) { 43 |         [self.tableView setSeparatorInset:UIEdgeInsetsZero];    44 | }    45 | if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {        46 | [self.tableView setLayoutMargins:UIEdgeInsetsZero]; 47 | } 48 | 然后在重写willDisplayCell方法 49 | - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell 50 | forRowAtIndexPath:(NSIndexPath *)indexPath{    51 | if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {        52 | [cell setSeparatorInset:UIEdgeInsetsZero];    53 | }    54 | if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {        55 | [cell setLayoutMargins:UIEdgeInsetsZero];    56 | } 57 | } 58 | ``` 59 | **6,计算方法耗时时间间隔** 60 | ``` 61 | // 获取时间间隔 62 | #define TICK   CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); 63 | #define TOCK   NSLog(@"Time: %f", CFAbsoluteTimeGetCurrent() - start) 64 | ``` 65 | **7,Color颜色宏定义** 66 | ``` 67 | // 随机颜色 68 | #define RANDOM_COLOR [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:1] 69 | // 颜色(RGB) 70 | #define RGBCOLOR(r, g, b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] 71 | // 利用这种方法设置颜色和透明值,可不影响子视图背景色 72 | #define RGBACOLOR(r, g, b, a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)] 73 | ``` 74 | **8,Alert提示宏定义** 75 | ``` 76 | #define Alert(_S_, ...) [[[UIAlertView alloc] initWithTitle:@"提示" message:[NSString stringWithFormat:(_S_), ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil] show] 77 | ``` 78 | **8,让 iOS 应用直接退出** 79 | ``` 80 | - (void)exitApplication { 81 |     AppDelegate *app = [UIApplication sharedApplication].delegate; 82 |     UIWindow *window = app.window; 83 | 84 |     [UIView animateWithDuration:1.0f animations:^{ 85 |         window.alpha = 0; 86 |     } completion:^(BOOL finished) { 87 |         exit(0); 88 |     }]; 89 | } 90 | ``` 91 | **8,NSArray 快速求总和 最大值 最小值 和 平均值 ** 92 | ``` 93 | NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil]; 94 | CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue]; 95 | CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue]; 96 | CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue]; 97 | CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue]; 98 | NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min); 99 | ``` 100 | **9,修改Label中不同文字颜色** 101 | ``` 102 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 103 | { 104 |     [self editStringColor:self.label.text editStr:@"好" color:[UIColor blueColor]]; 105 | } 106 | 107 | - (void)editStringColor:(NSString *)string editStr:(NSString *)editStr color:(UIColor *)color { 108 |     // string为整体字符串, editStr为需要修改的字符串 109 |     NSRange range = [string rangeOfString:editStr]; 110 | 111 |     NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] initWithString:string]; 112 | 113 |     // 设置属性修改字体颜色UIColor与大小UIFont 114 |     [attribute addAttributes:@{NSForegroundColorAttributeName:color} range:range]; 115 | 116 |     self.label.attributedText = attribute; 117 | } 118 | ``` 119 | **10,播放声音** 120 | ``` 121 | #import 122 | // 1.获取音效资源的路径 123 |    NSString *path = [[NSBundle mainBundle]pathForResource:@"pour_milk" ofType:@"wav"]; 124 | //  2.将路劲转化为url 125 |    NSURL *tempUrl = [NSURL fileURLWithPath:path]; 126 | // 3.用转化成的url创建一个播放器 127 |    NSError *error = nil; 128 |    AVAudioPlayer *play = [[AVAudioPlayer alloc]initWithContentsOfURL:tempUrl error:&error]; 129 |    self.player = play; 130 | // 4.播放 131 | [play play]; 132 | ``` 133 | **11,检测是否IPad Pro和其它设备型号** 134 | ``` 135 | - (BOOL)isIpadPro 136 | {    137 | UIScreen *Screen = [UIScreen mainScreen];    138 | CGFloat width = Screen.nativeBounds.size.width/Screen.nativeScale;  139 |  CGFloat height = Screen.nativeBounds.size.height/Screen.nativeScale;    140 | BOOL isIpad =[[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;    141 | BOOL hasIPadProWidth = fabs(width - 1024.f) < DBL_EPSILON;    142 | BOOL hasIPadProHeight = fabs(height - 1366.f) < DBL_EPSILON;  143 | return isIpad && hasIPadProHeight && hasIPadProWidth; 144 | } 145 | 146 | #define UI_IS_LANDSCAPE ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight)#define UI_IS_IPAD ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)#define UI_IS_IPHONE ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)#define UI_IS_IPHONE4 (UI_IS_IPHONE && [[UIScreen mainScreen] bounds].size.height < 568.0)#define UI_IS_IPHONE5 (UI_IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 568.0)#define UI_IS_IPHONE6 (UI_IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 667.0)#define UI_IS_IPHONE6PLUS (UI_IS_IPHONE && [[UIScreen mainScreen] bounds].size.height == 736.0 || [[UIScreen mainScreen] bounds].size.width == 736.0) // Both orientations#define UI_IS_IOS8_AND_HIGHER ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) 147 | 148 | 文/Originalee(简书作者)原文链接:http://www.jianshu.com/p/9d36aa12429f著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。 149 | ``` 150 | **11,修改Tabbar Item的属性** 151 | ``` 152 |     // 修改标题位置 153 |     self.tabBarItem.titlePositionAdjustment = UIOffsetMake(0, -10); 154 |     // 修改图片位置 155 |     self.tabBarItem.imageInsets = UIEdgeInsetsMake(-3, 0, 3, 0); 156 | 157 | // 批量修改属性 158 | for (UIBarItem *item in self.tabBarController.tabBar.items) { 159 |         [item setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: 160 |       [UIFont fontWithName:@"Helvetica" size:19.0], NSFontAttributeName, nil] 161 |                             forState:UIControlStateNormal]; 162 |     } 163 | 164 | // 设置选中和未选中字体颜色 165 |     [[UITabBar appearance] setShadowImage:[[UIImage alloc] init]]; 166 | 167 |     //未选中字体颜色 168 |     [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor greenColor]} forState:UIControlStateNormal]; 169 | 170 |     //选中字体颜色 171 |     [[UITabBarItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor cyanColor]} forState:UIControlStateSelected]; 172 | ``` 173 | 174 | **12,NULL - nil - Nil - NSNULL的区别** 175 | ``` 176 | * nil是OC的,空对象,地址指向空(0)的对象。对象的字面零值 177 | 178 | * Nil是Objective-C类的字面零值 179 | 180 | * NULL是C的,空地址,地址的数值是0,是个长整数 181 | 182 | * NSNull用于解决向NSArray和NSDictionary等集合中添加空值的问题 183 | ``` 184 | **11,去掉BackBarButtonItem的文字** 185 | ``` 186 | [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) 187 |                                                          forBarMetrics:UIBarMetricsDefault]; 188 | ``` 189 | **12,控件不能交互的一些原因** 190 | ``` 191 | 1,控件的userInteractionEnabled = NO 192 | 2,透明度小于等于0.01,aplpha 193 | 3,控件被隐藏的时候,hidden = YES 194 | 4,子视图的位置超出了父视图的有效范围,子视图无法交互,设置了。 195 | 5,需要交互的视图,被其他视图盖住(其他视图开启了用户交互)。 196 | ``` 197 | **12,修改UITextField中Placeholder的文字颜色** 198 | ``` 199 | [text setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"]; 200 | } 201 | ``` 202 | **13,视图的生命周期** 203 | ``` 204 | 1、 alloc 创建对象,分配空间 205 | 2、 init (initWithNibName) 初始化对象,初始化数据 206 | 3、 loadView 从nib载入视图 ,除非你没有使用xib文件创建视图 207 | 4、 viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件 208 | 5、 viewWillAppear视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了 209 | 6、 viewDidAppear 视图已在屏幕上渲染完成 210 | 211 | 1、viewWillDisappear 视图将被从屏幕上移除之前执行 212 | 2、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了 213 | 3、dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放. 214 | 215 | viewVillUnload- 当内存过低,即将释放时调用; 216 | viewDidUnload-当内存过低,释放一些不需要的视图时调用。 217 | 218 | ``` 219 | **14,应用程序的生命周期** 220 | ``` 221 | 1,启动但还没进入状态保存 : 222 | - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions  223 | 224 | 2,基本完成程序准备开始运行: 225 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 226 |   227 | 3,当应用程序将要入非活动状态执行,应用程序不接收消息或事件,比如来电话了: 228 | - (void)applicationWillResignActive:(UIApplication *)application  229 | 230 | 4,当应用程序入活动状态执行,这个刚好跟上面那个方法相反: 231 | - (void)applicationDidBecomeActive:(UIApplication *)application    232 | 233 | 5,当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可: 234 | - (void)applicationDidEnterBackground:(UIApplication *)application   235 | 236 | 6,当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反: 237 | - (void)applicationWillEnterForeground:(UIApplication *)application   238 | 239 | 7,当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作: 240 | - (void)applicationWillTerminate:(UIApplication *)application   241 | ``` 242 | **15,判断view是不是指定视图的子视图** 243 | ``` 244 | BOOL isView =  [textView isDescendantOfView:self.view]; 245 | ``` 246 | **16,判断对象是否遵循了某协议** 247 | ``` 248 | if ([self.selectedController conformsToProtocol:@protocol(RefreshPtotocol)]) { 249 | [self.selectedController performSelector:@selector(onTriggerRefresh)]; 250 | } 251 | ``` 252 | 253 | **17,页面强制横屏** 254 | ``` 255 | #pragma mark - 强制横屏代码 256 | - (BOOL)shouldAutorotate{    257 | //是否支持转屏    258 | return NO; 259 | } 260 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations{    261 | //支持哪些转屏方向    262 | return UIInterfaceOrientationMaskLandscape; 263 | } 264 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{  265 | return UIInterfaceOrientationLandscapeRight; 266 | } 267 | - (BOOL)prefersStatusBarHidden{    268 | return NO; 269 | } 270 | ``` 271 | **18,系统键盘通知消息** 272 | ``` 273 | 1、UIKeyboardWillShowNotification-将要弹出键盘 274 | 2、UIKeyboardDidShowNotification-显示键盘 275 | 3、UIKeyboardWillHideNotification-将要隐藏键盘 276 | 4、UIKeyboardDidHideNotification-键盘已经隐藏 277 | 5、UIKeyboardWillChangeFrameNotification-键盘将要改变frame 278 | 6、UIKeyboardDidChangeFrameNotification-键盘已经改变frame 279 | ``` 280 | 281 | **19,关闭navigationController的滑动返回手势** 282 | ``` 283 | self.navigationController.interactivePopGestureRecognizer.enabled = NO; 284 | ``` 285 | **20,设置状态栏背景为任意的颜色** 286 | ``` 287 | - (void)setStatusColor 288 | { 289 |     UIView *statusBarView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 20)]; 290 |     statusBarView.backgroundColor = [UIColor orangeColor]; 291 |     [self.view addSubview:statusBarView]; 292 | } 293 | ``` 294 | **21,让Xcode的控制台支持LLDB类型的打印** 295 | ``` 296 | 打开终端输入三条命令: 297 | touch ~/.lldbinit 298 | echo display @import UIKit >> ~/.lldbinit 299 | echo target stop-hook add -o \"target stop-hook disable\" >> ~/.lldbinit 300 | ``` 301 | 下次重新运行项目,然后就不报错了。 302 | ![](http://upload-images.jianshu.io/upload_images/790890-f3e134d18e165916.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 303 | **22,Label行间距** 304 | ```Objc 305 | -(void)test{ 306 |   NSMutableAttributedString *attributedString = 307 | [[NSMutableAttributedString alloc] initWithString:self.contentLabel.text]; 308 |     NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];   309 |   [paragraphStyle setLineSpacing:3]; 310 | 311 | //调整行间距       312 | [attributedString addAttribute:NSParagraphStyleAttributeName 313 | value:paragraphStyle 314 | range:NSMakeRange(0, [self.contentLabel.text length])]; 315 |      self.contentLabel.attributedText = attributedString; 316 | } 317 | ``` 318 | **23,UIImageView填充模式** 319 | ``` 320 | @"UIViewContentModeScaleToFill",      // 拉伸自适应填满整个视图   321 | @"UIViewContentModeScaleAspectFit",   // 自适应比例大小显示   322 | @"UIViewContentModeScaleAspectFill",  // 原始大小显示   323 | @"UIViewContentModeRedraw",           // 尺寸改变时重绘   324 | @"UIViewContentModeCenter",           // 中间   325 | @"UIViewContentModeTop",              // 顶部   326 | @"UIViewContentModeBottom",           // 底部   327 | @"UIViewContentModeLeft",             // 中间贴左   328 | @"UIViewContentModeRight",            // 中间贴右   329 | @"UIViewContentModeTopLeft",          // 贴左上   330 | @"UIViewContentModeTopRight",         // 贴右上   331 | @"UIViewContentModeBottomLeft",       // 贴左下   332 | @"UIViewContentModeBottomRight",      // 贴右下   333 | ``` 334 | **24,宏定义检测block是否可用** 335 | ```objc 336 | #define BLOCK_EXEC(block, ...) if (block) { block(__VA_ARGS__); };    337 | // 宏定义之前的用法 338 |  if (completionBlock)   {    339 |     completionBlock(arg1, arg2);  340 |  }     341 | // 宏定义之后的用法 342 |  BLOCK_EXEC(completionBlock, arg1, arg2); 343 | ``` 344 | **25,Debug栏打印时自动把Unicode编码转化成汉字** 345 | ``` 346 | // 有时候我们在xcode中打印中文,会打印出Unicode编码,还需要自己去一些在线网站转换,有了插件就方便多了。 347 | DXXcodeConsoleUnicodePlugin 插件 348 | ``` 349 | **26,设置状态栏文字样式颜色** 350 | ``` 351 | [[UIApplication sharedApplication] setStatusBarHidden:NO]; 352 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; 353 | ``` 354 | 355 | **26,自动生成模型代码的插件** 356 | ``` 357 | // 可自动生成模型的代码,省去写模型代码的时间 358 | ESJsonFormat-for-Xcode 359 | ``` 360 | 361 | **27,iOS中的一些手势** 362 | ``` 363 | 轻击手势(TapGestureRecognizer) 364 | 轻扫手势(SwipeGestureRecognizer) 365 | 长按手势(LongPressGestureRecognizer) 366 | 拖动手势(PanGestureRecognizer) 367 | 捏合手势(PinchGestureRecognizer) 368 | 旋转手势(RotationGestureRecognizer) 369 | ``` 370 | **27,iOS 开发中一些相关的路径** 371 | ``` 372 | 模拟器的位置: 373 | /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs 374 | 375 | 文档安装位置: 376 | /Applications/Xcode.app/Contents/Developer/Documentation/DocSets 377 | 378 | 插件保存路径: 379 | ~/Library/ApplicationSupport/Developer/Shared/Xcode/Plug-ins 380 | 381 | 自定义代码段的保存路径: 382 | ~/Library/Developer/Xcode/UserData/CodeSnippets/ 383 | 如果找不到CodeSnippets文件夹,可以自己新建一个CodeSnippets文件夹。 384 | 385 | 证书路径 386 | ~/Library/MobileDevice/Provisioning Profiles 387 | ``` 388 | **28,获取 iOS 路径的方法** 389 | ``` 390 | 获取家目录路径的函数 391 | NSString *homeDir = NSHomeDirectory(); 392 | 393 | 获取Documents目录路径的方法 394 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 395 | NSString *docDir = [paths objectAtIndex:0]; 396 | 397 | 获取Documents目录路径的方法 398 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 399 | NSString *cachesDir = [paths objectAtIndex:0]; 400 | 401 | 获取tmp目录路径的方法: 402 | NSString *tmpDir = NSTemporaryDirectory(); 403 | ``` 404 | 405 | **29,字符串相关操作 ** 406 | ``` 407 | 去除所有的空格 408 | [str stringByReplacingOccurrencesOfString:@" " withString:@""] 409 | 410 | 去除首尾的空格 411 | [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 412 | 413 | - (NSString *)uppercaseString; 全部字符转为大写字母 414 | - (NSString *)lowercaseString 全部字符转为小写字母 415 | ``` 416 | 417 | **30, CocoaPods pod install/pod update更新慢的问题** 418 | ``` 419 | pod install --verbose --no-repo-update  420 | pod update --verbose --no-repo-update 421 | 如果不加后面的参数,默认会升级CocoaPods的spec仓库,加一个参数可以省略这一步,然后速度就会提升不少。 422 | ``` 423 | 424 | **31,MRC和ARC混编设置方式** 425 | ``` 426 | 427 | 在XCode中targets的build phases选项下Compile Sources下选择 不需要arc编译的文件 428 | 双击输入 -fno-objc-arc 即可 429 | 430 | MRC工程中也可以使用ARC的类,方法如下: 431 | 在XCode中targets的build phases选项下Compile Sources下选择要使用arc编译的文件 432 | 双击输入 -fobjc-arc 即可 433 | ``` 434 | 435 | **32,把tableview里cell的小对勾的颜色改成别的颜色** 436 | ``` 437 | _mTableView.tintColor = [UIColor redColor]; 438 | ``` 439 | 440 | **33,调整tableview的separaLine线的位置** 441 | ``` 442 | tableView.separatorInset = UIEdgeInsetsMake(0, 100, 0, 0); 443 | ``` 444 | 445 | **34,设置滑动的时候隐藏navigationbar** 446 | ``` 447 | navigationController.hidesBarsOnSwipe = Yes 448 | ``` 449 | 450 | **35,自动处理键盘事件,实现输入框防遮挡的插件** 451 | ``` 452 | IQKeyboardManager 453 | https://github.com/hackiftekhar/IQKeyboardManager 454 | ``` 455 | 456 | **36,Quartz2D相关** 457 | ``` 458 | 图形上下是一个CGContextRef类型的数据。 459 | 图形上下文包含: 460 | 1,绘图路径(各种各样图形) 461 | 2,绘图状态(颜色,线宽,样式,旋转,缩放,平移) 462 | 3,输出目标(绘制到什么地方去?UIView、图片) 463 | 464 | 1,获取当前图形上下文 465 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 466 | 2,添加线条 467 | CGContextMoveToPoint(ctx, 20, 20); 468 | 3,渲染 469 | CGContextStrokePath(ctx); 470 | CGContextFillPath(ctx); 471 | 4,关闭路径 472 | CGContextClosePath(ctx); 473 | 5,画矩形 474 | CGContextAddRect(ctx, CGRectMake(20, 20, 100, 120)); 475 | 6,设置线条颜色 476 | [[UIColor redColor] setStroke]; 477 | 7, 设置线条宽度 478 | CGContextSetLineWidth(ctx, 20); 479 | 8,设置头尾样式 480 | CGContextSetLineCap(ctx, kCGLineCapSquare); 481 | 9,设置转折点样式 482 | CGContextSetLineJoin(ctx, kCGLineJoinBevel); 483 | 10,画圆 484 | CGContextAddEllipseInRect(ctx, CGRectMake(30, 50, 100, 100)); 485 | 11,指定圆心 486 | CGContextAddArc(ctx, 100, 100, 50, 0, M_PI * 2, 1); 487 | 12,获取图片上下文 488 | UIGraphicsGetImageFromCurrentImageContext(); 489 | 13,保存图形上下文 490 | CGContextSaveGState(ctx) 491 | 14,恢复图形上下文 492 | CGContextRestoreGState(ctx) 493 | ``` 494 | 495 | **37,屏幕截图** 496 | ``` 497 |     // 1. 开启一个与图片相关的图形上下文 498 |     UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,NO,0.0); 499 | 500 |     // 2. 获取当前图形上下文 501 |     CGContextRef ctx = UIGraphicsGetCurrentContext(); 502 | 503 |     // 3. 获取需要截取的view的layer 504 |     [self.view.layer renderInContext:ctx]; 505 | 506 |     // 4. 从当前上下文中获取图片 507 |     UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 508 | 509 |     // 5. 关闭图形上下文 510 |     UIGraphicsEndImageContext(); 511 | 512 |     // 6. 把图片保存到相册 513 |     UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); 514 | ``` 515 | 516 | **37,左右抖动动画** 517 | ``` 518 | //1, 创建核心动画 519 | CAKeyframeAnimation *keyAnima = [CAKeyframeAnimation animation]; 520 | 521 | //2, 告诉系统执行什么动画。 522 | keyAnima.keyPath = @"transform.rotation"; 523 | keyAnima.values = @[@(-M_PI_4 /90.0 * 5),@(M_PI_4 /90.0 * 5),@(-M_PI_4 /90.0 * 5)]; 524 | 525 | // 3, 执行完之后不删除动画 526 | keyAnima.removedOnCompletion = NO; 527 | 528 | // 4, 执行完之后保存最新的状态 529 | keyAnima.fillMode = kCAFillModeForwards; 530 | 531 | // 5, 动画执行时间 532 | keyAnima.duration = 0.2; 533 | 534 | // 6, 设置重复次数。 535 | keyAnima.repeatCount = MAXFLOAT; 536 | 537 | // 7, 添加核心动画 538 | [self.iconView.layer addAnimation:keyAnima forKey:nil]; 539 | ``` 540 | 541 | **38,CALayer 的知识** 542 | ``` 543 | CALayer 负责视图中显示内容和动画 544 | UIView 负责监听和响应事件 545 | 546 | 创建UIView对象时,UIView内部会自动创建一个图层(既CALayer) 547 | UIView本身不具备显示的功能,是它内部的层才有显示功能. 548 | 549 | CALayer属性: 550 | position 中点(由anchorPoint决定) 551 | anchorPoint 锚点 552 | borderColor 边框颜色 553 | borderWidth 边框宽度 554 | cornerRadius 圆角半径 555 | shadowColor 阴影颜色 556 | contents 内容 557 | opacity 透明度 558 | shadowOpacity 偏移 559 | shadowRadius 阴影半径 560 | shadowColor 阴影颜色 561 | masksToBounds 裁剪 562 | ``` 563 | **39,性能相关** 564 | ``` 565 | 1. 视图复用,比如UITableViewCell,UICollectionViewCell. 566 | 2. 数据缓存,比如用SDWebImage实现图片缓存。 567 | 3. 任何情况下都不能堵塞主线程,把耗时操作尽量放到子线程。 568 | 4. 如果有多个下载同时并发,可以控制并发数。 569 | 5. 在合适的地方尽量使用懒加载。 570 | 6. 重用重大开销对象,比如:NSDateFormatter、NSCalendar。 571 | 7. 选择合适的数据存储。 572 | 8. 避免循环引用。避免delegate用retain、strong修饰,block可能导致循环引用,NSTimer也可能导致内存泄露等。 573 | 9. 当涉及到定位的时候,不用的时候最好把定位服务关闭。因为定位耗电、流量。 574 | 10. 加锁对性能有重大开销。 575 | 11. 界面最好不要添加过多的subViews. 576 | 12. TableView 如果不同行高,那么返回行高,最好做缓存。 577 | 13. Viewdidload 里尽量不要做耗时操作。 578 | ``` 579 | 580 | **40,验证身份证号码** 581 | ``` 582 | //验证身份证号码 583 | - (BOOL)checkIdentityCardNo:(NSString*)cardNo 584 | { 585 |     if (cardNo.length != 18) { 586 |         return  NO; 587 |     } 588 |     NSArray* codeArray = [NSArray arrayWithObjects:@"7",@"9",@"10",@"5",@"8",@"4",@"2",@"1",@"6",@"3",@"7",@"9",@"10",@"5",@"8",@"4",@"2", nil]; 589 |     NSDictionary* checkCodeDic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"0",@"X",@"9",@"8",@"7",@"6",@"5",@"4",@"3",@"2", nil]  forKeys:[NSArray arrayWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10", nil]]; 590 | 591 |     NSScanner* scan = [NSScanner scannerWithString:[cardNo substringToIndex:17]]; 592 | 593 |     int val; 594 |     BOOL isNum = [scan scanInt:&val] && [scan isAtEnd]; 595 |     if (!isNum) { 596 |         return NO; 597 |     } 598 |     int sumValue = 0; 599 | 600 |     for (int i =0; i<17; i++) { 601 |         sumValue+=[[cardNo substringWithRange:NSMakeRange(i , 1) ] intValue]* [[codeArray objectAtIndex:i] intValue]; 602 |     } 603 | 604 |     NSString* strlast = [checkCodeDic objectForKey:[NSString stringWithFormat:@"%d",sumValue%11]]; 605 | 606 |     if ([strlast isEqualToString: [[cardNo substringWithRange:NSMakeRange(17, 1)]uppercaseString]]) { 607 |         return YES; 608 |     } 609 |     return  NO; 610 | } 611 | ``` 612 | **41,响应者链条顺序** 613 | ``` 614 | 1> 当应用程序启动以后创建 UIApplication 对象 615 | 616 | 2> 然后启动“消息循环”监听所有的事件 617 | 618 | 3> 当用户触摸屏幕的时候, "消息循环"监听到这个触摸事件 619 | 620 | 4> "消息循环" 首先把监听到的触摸事件传递了 UIApplication 对象 621 | 622 | 5> UIApplication 对象再传递给 UIWindow 对象 623 | 624 | 6> UIWindow 对象再传递给 UIWindow 的根控制器(rootViewController) 625 | 626 | 7> 控制器再传递给控制器所管理的 view 627 | 628 | 8> 控制器所管理的 View 在其内部搜索看本次触摸的点在哪个控件的范围内(调用Hit test检测是否在这个范围内) 629 | 630 | 9> 找到某个控件以后(调用这个控件的 touchesXxx 方法), 再一次向上返回, 最终返回给"消息循环" 631 | 632 | 10> "消息循环"知道哪个按钮被点击后, 在搜索这个按钮是否注册了对应的事件, 如果注册了, 那么就调用这个"事件处理"程序。(一般就是执行控制器中的"事件处理"方法) 633 | ``` 634 | 635 | ####42,使用函数式指针执行方法和忽略performSelector方法的时候警告 636 | ``` 637 | 不带参数的: 638 | SEL selector = NSSelectorFromString(@"someMethod"); 639 | IMP imp = [_controller methodForSelector:selector]; 640 | void (*func)(id, SEL) = (void *)imp; 641 | func(_controller, selector); 642 | 643 | 带参数的: 644 | SEL selector = NSSelectorFromString(@"processRegion:ofView:"); 645 | IMP imp = [_controller methodForSelector:selector]; 646 | CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp; 647 | CGRect result = func(_controller, selector, someRect, someView); 648 | 649 | 忽略警告: 650 | #pragma clang diagnostic push 651 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 652 | [someController performSelector: NSSelectorFromString(@"someMethod")] 653 | #pragma clang diagnostic pop 654 | 655 | 如果需要忽视的警告有多处,可以定义一个宏: 656 | #define SuppressPerformSelectorLeakWarning(Stuff) \ 657 | do {\ 658 | _Pragma("clang diagnostic push") \ 659 | _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ 660 | Stuff; \ 661 | _Pragma("clang diagnostic pop") \ 662 | } while (0) 663 | 使用方法: 664 | SuppressPerformSelectorLeakWarning( 665 | [_target performSelector:_action withObject:self] 666 | ); 667 | ``` 668 | 669 | **43,UIApplication的简单使用** 670 | ``` 671 | --------设置角标数字-------- 672 | //获取UIApplication对象 673 |     UIApplication *ap = [UIApplication sharedApplication]; 674 | //在设置之前, 要注册一个通知,从ios8之后,都要先注册一个通知对象.才能够接收到提醒. 675 |     UIUserNotificationSettings *notice = 676 |     [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil]; 677 | //注册通知对象 678 |     [ap registerUserNotificationSettings:notice]; 679 | //设置提醒数字 680 |     ap.applicationIconBadgeNumber = 20; 681 | 682 | --------设置联网状态-------- 683 | UIApplication *ap = [UIApplication sharedApplication]; 684 | ap.networkActivityIndicatorVisible = YES; 685 | -------------------------- 686 | ``` 687 | 688 | 44, UITableView隐藏空白部分线条 689 | ``` 690 | self.tableView.tableFooterView = [[UIView alloc]init]; 691 | ``` 692 | 693 | 45,显示git增量的Xcode插件:GitDiff 694 | ``` 695 | 下载地址:https://github.com/johnno1962/GitDiff 696 | 这款插件的名字是GitDiff,作用就是可以显示表示出git增量提交的代码行,比如下图 697 | 会在Xcode左边标识出来: 698 | ``` 699 | ![](http://upload-images.jianshu.io/upload_images/790890-c600e11f4f73014d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 700 | 701 | 702 | 46,各种收藏的网址 703 | ``` 704 | unicode编码转换 705 | http://tool.chinaz.com/tools/unicode.aspx 706 | 707 | JSON 字符串格式化 708 | http://www.runoob.com/jsontool 709 | 710 | RGB 颜色值转换 711 | http://www.sioe.cn/yingyong/yanse-rgb-16/ 712 | 713 | 短网址生成 714 | http://dwz.wailian.work/ 715 | 716 | MAC 软件下载 717 | http://www.waitsun.com/ 718 | 719 | objc 中国 720 | http://objccn.io/ 721 | ``` 722 | 723 | 47,NSObject 继承图 724 | ![](http://upload-images.jianshu.io/upload_images/790890-87f15751aca47601.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 725 | 726 | 48,浅拷贝、深拷贝、copy和strong 727 | ``` 728 | 浅拷贝:(任何一方的变动都会影响到另一方) 729 | 只是对对象的简单拷贝,让几个对象共用一片内存,当内存销毁的时候,指向这片内存的几个指针 730 | 需要重新定义才可以使用。 731 | 732 | 深拷贝:(任何一方的变动都不会影响到另一方) 733 | 拷贝对象的具体内容,内存地址是自主分配的,拷贝结束后,两个对象虽然存的值是相同的,但是 734 | 内存地址不一样,两个对象也互不影响,互不干涉。 735 | 736 | copy和Strong的区别:copy是创建一个新对象,Strong是创建一个指针。 737 | ``` 738 | 739 | 49,SEL 和 IMP 740 | ``` 741 | SEL: 其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后 742 | 就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。 743 | 744 | 745 | IMP: 是”implementation”的缩写,它是objetive-C 方法 (method)实现代码块的地址,类似函数 746 | 指针,通过它可以 直接访问任意一个方法。免去发送消息的代价。 747 | ``` 748 | 749 | 50, self 和 super 750 | ``` 751 | 在动态方法中,self代表着"对象" 752 | 在静态方法中,self代表着"类" 753 | 754 | 万变不离其宗,记住一句话就行了: 755 | self代表着当前方法的调用者self 和 super 是oc提供的 两个保留字, 但有根本区别,self是类的隐藏的 756 | 参数变量,指向当前调用方法的对象(类也是对象,类对象) 757 | 另一个隐藏参数是_cmd,代表当前类方法的selector。 758 | 759 | super并不是隐藏的参数,它只是一个"编译器指示符" 760 | super 就是个障眼法 发,编译器符号, 它可以替换成 [self class],只不过 方法是从 self 的 761 | 超类开始寻找。 762 | ``` 763 | 764 | 51, 长连接 和 短连接 765 | ``` 766 | 长连接:(长连接在没有数据通信时,定时发送数据包(心跳),以维持连接状态) 767 | 连接→数据传输→保持连接(心跳)→数据传输→保持连接(心跳)→……→关闭连接;   768 | 长连接:连接服务器就不断开 769 | 770 | 短连接:(短连接在没有数据传输时直接关闭就行了) 771 | 连接→数据传输→关闭连接; 772 | 短连接:连接上服务器,获取完数据,就立即断开。 773 | ``` 774 | 775 | 52, HTTP 基本状态码 776 | ``` 777 | 200 OK 778 |     请求已成功,请求所希望的响应头或数据体将随此响应返回。 779 | 780 | 300 Multiple Choices 781 |     被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。 782 | 783 | 400 Bad Request 784 |     由于包含语法错误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。 785 | 786 | 404 Not Found 787 |     请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。 788 | 789 | 408 Request Timeout 790 |     请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。 791 | 792 | 500 Internal Server Error 793 |     服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。 794 | 795 | ``` 796 | 797 | 53, TCP 和 UDP 798 | ``` 799 | TCP: 800 | 801 | - 建立连接,形成传输数据的通道 802 | - 在连接中进行大数据传输(数据大小受限制) 803 | - 通过三次握手完成连接,是可靠协议 804 | - 必须建立连接,效率比UDP低 805 | 806 | UDP: 807 | 808 | - 只管发送,不管接受 809 | - 将数据以及源和目的封装成数据包中,不需要建立连接、 810 | - 每个数据报的大小限制在64K之内 811 | - 不可靠协议 812 | - 速度快 813 | ``` 814 | 815 | 54, 三次握手和四次断开 816 | ``` 817 | 三次握手: 818 | 你在吗-我在的-我问你个事情 819 | 四次断开握手 820 | 我这个问题问完了--你问完了吗---可以下线了吗---我真的问完了拜拜 821 | ``` 822 | 823 | 55, 设置按钮按下时候会发光 824 | ``` 825 | button.showsTouchWhenHighlighted=YES; 826 | ``` 827 | 56,怎么把tableview里Cell的小对勾颜色改成别的颜色? 828 | ``` 829 | _mTableView.tintColor = [UIColor redColor]; 830 | ``` 831 | 832 | 57, 怎么调整Cell 的 separaLine的位置?** 833 | ``` 834 | _myTableView.separatorInset = UIEdgeInsetsMake(0, 100, 0, 0); 835 | ``` 836 | 837 | 58, ScrollView莫名其妙不能在viewController划到顶怎么办? 838 | ``` 839 | self.automaticallyAdjustsScrollViewInsets = NO; 840 | ``` 841 | 59, 设置TableView不显示没内容的Cell。 842 | ``` 843 | self.tableView.tableFooterView = [[UIView alloc]init] 844 | ``` 845 | 846 | 60,复制字符串到iOS剪贴板 847 | ``` 848 | UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; 849 | pasteboard.string = self.label.text; 850 | ``` 851 | 852 | 61,宏定义多行使用方法 853 | ``` 854 | 例子:( 只需要每行加个 \ 就行了) 855 | 856 | #define YKCodingScanData \ 857 | -(void)setValue:(id)value forUndefinedKey:(NSString *)key{} \ 858 | - (instancetype)initWithScanJson:(NSDictionary *)dict{ \ 859 | if (self = [super init]) { \ 860 | [self setValuesForKeysWithDictionary:dict]; \ 861 | } \ 862 |     return self; \ 863 | } \ 864 | ``` 865 | 62,去掉cell点击后背景变色 866 | ``` 867 | [tableView deselectRowAtIndexPath:indexPath animated:NO]; 868 | 如果发现在tableView的didSelect中present控制器弹出有些慢也可以试试这个方法 869 | ``` 870 | 63,线程租调度事例 871 | ``` 872 | // 群组-统一监控一组任务 873 | dispatch_group_t group = dispatch_group_create(); 874 | 875 | dispatch_queue_t q = dispatch_get_global_queue(0, 0); 876 | // 添加任务 877 | // group 负责监控任务,queue 负责调度任务 878 | dispatch_group_async(group, q, ^{ 879 | [NSThread sleepForTimeInterval:1.0]; 880 | NSLog(@"任务1 %@", [NSThread currentThread]); 881 | }); 882 | dispatch_group_async(group, q, ^{ 883 | NSLog(@"任务2 %@", [NSThread currentThread]); 884 | }); 885 | dispatch_group_async(group, q, ^{ 886 | NSLog(@"任务3 %@", [NSThread currentThread]); 887 | }); 888 | 889 | // 监听所有任务完成 - 等到 group 中的所有任务执行完毕后,"由队列调度 block 中的任务异步执行!" 890 | dispatch_group_notify(group, dispatch_get_main_queue(), ^{ 891 | // 修改为主队列,后台批量下载,结束后,主线程统一更新UI 892 | NSLog(@"OK %@", [NSThread currentThread]); 893 | }); 894 | 895 | NSLog(@"come here"); 896 | ``` 897 | 64、视图坐标转换 898 | ``` 899 | // 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值 900 | - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view; 901 | // 将像素point从view中转换到当前视图中,返回在当前视图中的像素值 902 | - (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view; 903 | 904 | // 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect 905 | - (CGRect)convertRect:(CGRect)rect toView:(UIView *)view; 906 | // 将rect从view中转换到当前视图中,返回在当前视图中的rect 907 | - (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view; 908 | 909 | *例把UITableViewCell中的subview(btn)的frame转换到 910 | controllerA中 911 | // controllerA 中有一个UITableView, UITableView里有多行UITableVieCell,cell上放有一个button 912 | // 在controllerA中实现: 913 | CGRect rc = [cell convertRect:cell.btn.frame toView:self.view]; 914 | 或 915 | CGRect rc = [self.view convertRect:cell.btn.frame fromView:cell]; 916 | // 此rc为btn在controllerA中的rect 917 | 918 | 或当已知btn时: 919 | CGRect rc = [btn.superview convertRect:btn.frame toView:self.view]; 920 | 或 921 | CGRect rc = [self.view convertRect:btn.frame fromView:btn.superview]; 922 | ``` 923 | 65、设置animation动画终了,不返回初始状态 924 | ``` 925 | animation.removedOnCompletion = NO; 926 | animation.fillMode = kCAFillModeForwards; 927 | ``` 928 | 66、UIViewAnimationOptions类型 929 | ``` 930 | 常规动画属性设置(可以同时选择多个进行设置) 931 | UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动。 932 | UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互。 933 | UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行。 934 | UIViewAnimationOptionRepeat:重复运行动画。 935 | UIViewAnimationOptionAutoreverse :动画运行到结束点后仍然以动画方式回到初始点。 936 | UIViewAnimationOptionOverrideInheritedDuration:忽略嵌套动画时间设置。 937 | UIViewAnimationOptionOverrideInheritedCurve:忽略嵌套动画速度设置。 938 | UIViewAnimationOptionAllowAnimatedContent:动画过程中重绘视图(注意仅仅适用于转场动画)。   939 | UIViewAnimationOptionShowHideTransitionViews:视图切换时直接隐藏旧视图、显示新视图,而不是将旧视图从父视图移除(仅仅适用于转场动画)UIViewAnimationOptionOverrideInheritedOptions :不继承父动画设置或动画类型。 940 | 2.动画速度控制(可从其中选择一个设置) 941 | UIViewAnimationOptionCurveEaseInOut:动画先缓慢,然后逐渐加速。 942 | UIViewAnimationOptionCurveEaseIn :动画逐渐变慢。 943 | UIViewAnimationOptionCurveEaseOut:动画逐渐加速。 944 | UIViewAnimationOptionCurveLinear :动画匀速执行,默认值。 945 | 3.转场类型(仅适用于转场动画设置,可以从中选择一个进行设置,基本动画、关键帧动画不需要设置) 946 | UIViewAnimationOptionTransitionNone:没有转场动画效果。 947 | UIViewAnimationOptionTransitionFlipFromLeft :从左侧翻转效果。 948 | UIViewAnimationOptionTransitionFlipFromRight:从右侧翻转效果。 949 | UIViewAnimationOptionTransitionCurlUp:向后翻页的动画过渡效果。     950 | UIViewAnimationOptionTransitionCurlDown :向前翻页的动画过渡效果。     951 | UIViewAnimationOptionTransitionCrossDissolve:旧视图溶解消失显示下一个新视图的效果。     952 | UIViewAnimationOptionTransitionFlipFromTop :从上方翻转效果。     953 | UIViewAnimationOptionTransitionFlipFromBottom:从底部翻转效果。 954 | ``` 955 | 67、获取当前View所在的控制器 956 | ``` 957 | #import "UIView+CurrentController.h" 958 | 959 | @implementation UIView (CurrentController) 960 | 961 | /** 获取当前View所在的控制器*/ 962 | -(UIViewController *)getCurrentViewController{ 963 |     UIResponder *next = [self nextResponder]; 964 |     do { 965 |         if ([next isKindOfClass:[UIViewController class]]) { 966 |             return (UIViewController *)next; 967 |         } 968 |         next = [next nextResponder]; 969 |     } while (next != nil);  970 |     return nil; 971 | } 972 | ``` 973 | 68、iOS横向滚动的scrollView和系统pop手势返回冲突的解决办法 974 | ``` 975 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 976 | { 977 | // 首先判断otherGestureRecognizer是不是系统pop手势 978 | if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) { 979 | // 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边 980 | if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) { 981 | return YES; 982 | } 983 | } 984 | return NO; 985 | } 986 | ``` 987 | 69、设置状态栏方向位置 988 | ``` 989 | 修改状态栏方向, 990 | [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft; 991 | 992 | 枚举值说明: 993 | UIDeviceOrientationPortraitUpsideDown,  //设备直立,home按钮在上 994 | UIDeviceOrientationLandscapeLeft,       //设备横置,home按钮在右 995 | UIDeviceOrientationLandscapeRight,      //设备横置, home按钮在左 996 | UIDeviceOrientationFaceUp,              //设备平放,屏幕朝上 997 | UIDeviceOrientationFaceDown             //设备平放,屏幕朝下 998 | 999 | 再实现这个代理方法就行了 1000 | - (BOOL)shouldAutorotate 1001 | { 1002 | return NO; //必须返回no, 才能强制手动旋转 1003 | } 1004 | ``` 1005 | 69、修改 UICollectionViewCell 之间的间距 1006 | ``` 1007 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section 1008 | { 1009 |     return UIEdgeInsetsMake(10, 10, 10, 10); 1010 | } 1011 | ``` 1012 | 70,时间戳转换成标准时间 1013 | ``` 1014 | -(NSString *)TimeStamp:(NSString *)strTime 1015 | { 1016 |     //因为时差问题要加8小时 == 28800 sec 1017 |     NSTimeInterval time=[strTime doubleValue]+28800; 1018 |      1019 |     NSDate *detaildate=[NSDate dateWithTimeIntervalSince1970:time]; 1020 |      1021 |     //实例化一个NSDateFormatter对象 1022 |     NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 1023 |      1024 |     //设定时间格式,这里可以设置成自己需要的格式 1025 |     [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 1026 |      1027 |     NSString *currentDateStr = [dateFormatter stringFromDate: detaildate]; 1028 |      1029 |     return currentDateStr; 1030 | } 1031 | ``` 1032 | 71,CocoaPods 安装不上怎么办 1033 | ``` 1034 | 终端进入 repos目录 1035 | cd ~/.cocoapods/repos 1036 | 新建一个文件夹master 1037 | 然后下载 https://coding.net/u/CocoaPods/p/Specs/git 1038 | 到master下 1039 | ``` 1040 | 72,快速创建Block 1041 | ``` 1042 | 输入 :xcode中输入 : inlineblock 1043 | ``` 1044 | 73,Git 关联仓库 ,和基本配置 1045 | ``` 1046 | -------Git global setup------- 1047 | 1048 | git config --global user.name "张大森" 1049 | git config --global user.email "zhangdasen@126.com" 1050 | 1051 | -------Create a new repository------- 1052 | git clone git@gitlab.testAddress.com:test/QRZxing.git 1053 | cd QRZxing 1054 | touch README.mdgit 1055 | add README.mdgit commit -m "add README" 1056 | git push -u origin master 1057 | 1058 | -------Existing folder or Git repository------- 1059 | cd existing_folder 1060 | git init 1061 | git remote add origin git@gitlab.testAddress.com:test/QRZxing.git 1062 | git add . 1063 | git commit 1064 | git push -u origin master 1065 | 1066 | ``` 1067 | 74,Git 命令大全 1068 | 1069 | ![1234.png](http://upload-images.jianshu.io/upload_images/790890-2233c59924c77b95.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 1070 | >以上整理只为自己和大家方便查看,iOS中小技巧和黑科技数不尽 1071 | **如果大家有不错的代码和技巧,也可留言或私信我**,然后加上。 1072 | 待续。。。。。。 1073 | >会继续更新的! 😇 1074 | --------------------------------------------------------------------------------