知识点1

作者: DDY | 来源:发表于2016-10-13 10:48 被阅读1619次

    虽不才,关注下吧,防止你用到了,有问题连个商量的人都找不到...

    0.防止暴力点击

    防止collection短时间点击多个item
    [collectionView setUserInteractionEnabled:NO];
    [collectionView performSelector:@selector(setUserInteractionEnabled:)withObject:[NSNumber numberWithBool:YES] afterDelay:0.5f];
    
    防止短时间点击两个按钮
    [view setExclusiveTouch:YES];
    
    防止按钮短时间多次点击
    - (void)todoSomething:(id)sender {
        //在这里做按钮的想做的事情。
    }
    - (void)starButtonClicked:(id)sender {
        //先将未到时间执行前的任务取消。
        [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(todoSomething:) object:sender];
        [self performSelector:@selector(todoSomething:) withObject:sender afterDelay:0.2f];
    }
    

    1. 打印View根视图所有子视图

    [self.view.superview recursiveDescription]
    

    2.layoutSubviews调用的调用时机

    • 当视图第一次显示的时候会被调用
    • 当这个视图显示到屏幕上了,点击按钮
    • 添加子视图也会调用这个方法
    • 当本视图的大小发生改变的时候是会调用的
    • 当子视图的frame发生改变的时候是会调用的
    • 当删除子视图的时候是会调用的

    3. NSString过滤特殊字符

    // 定义一个特殊字符的集合
    NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:
    @"@/:;()¥「」"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\""];
    // 过滤字符串的特殊字符
    NSString *newString = [trimString stringByTrimmingCharactersInSet:set];
    

    4. TransForm属性

    //平移按钮
    CGAffineTransform transForm = self.buttonView.transform;
    self.buttonView.transform = CGAffineTransformTranslate(transForm, 10, 0);
     
    //旋转按钮
    CGAffineTransform transForm = self.buttonView.transform;
    self.buttonView.transform = CGAffineTransformRotate(transForm, M_PI_4);
     
    //缩放按钮
    self.buttonView.transform = CGAffineTransformScale(transForm, 1.2, 1.2);
     
    //初始化复位
    self.buttonView.transform = CGAffineTransformIdentity;
    

    5. 去掉分割线多余15像素

    - (void)viewDidLayoutSubviews {
     if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
            [self.tableView setSeparatorInset:UIEdgeInsetsZero];    
      }   
     if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {        
            [self.tableView setLayoutMargins:UIEdgeInsetsZero];
      }
    }
    然后在重写willDisplayCell方法
    - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell 
    forRowAtIndexPath:(NSIndexPath *)indexPath{   
        if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {       
                 [cell setSeparatorInset:UIEdgeInsetsZero];    
        }    
        if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {        
                 [cell setLayoutMargins:UIEdgeInsetsZero];    
        }
    }
    

    6. 计算方法耗时时间间隔

    // 获取时间间隔
    #define TICK   CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
    #define TOCK   NSLog(@"Time: %f", CFAbsoluteTimeGetCurrent() - start)
    

    7. Color颜色宏定义

    // 随机颜色
    #define RANDOM_COLOR [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:1]
    // 颜色(RGB)
    #define RGBCOLOR(r, g, b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1]
    // 利用这种方法设置颜色和透明值,可不影响子视图背景色
    #define RGBACOLOR(r, g, b, a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)]
    

    8. Alert

    宏定义
    #define Alert(_S_, ...) [[[UIAlertView alloc] initWithTitle:@"提示" message:[NSString stringWithFormat:(_S_), ##__VA_ARGS__] delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil] show]
    

    9. NSArray 快速求总和 最大值 最小值 和 平均值

    NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
    CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
    CGFloat avg = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
    CGFloat max =[[array valueForKeyPath:@"@max.floatValue"] floatValue];
    CGFloat min =[[array valueForKeyPath:@"@min.floatValue"] floatValue];
    NSLog(@"%f\n%f\n%f\n%f",sum,avg,max,min);
    

    10. 修改Label中不同文字颜色

    - (void)touchesEnded:(NSSet<UITouch> *)touches withEvent:(UIEvent *)event
    {
        [self editStringColor:self.label.text editStr:@"好" color:[UIColor blueColor]];
    }
     
    - (void)editStringColor:(NSString *)string editStr:(NSString *)editStr color:(UIColor *)color {
        // string为整体字符串, editStr为需要修改的字符串
        NSRange range = [string rangeOfString:editStr];
     
        NSMutableAttributedString *attribute = [[NSMutableAttributedString alloc] initWithString:string];
     
        // 设置属性修改字体颜色UIColor与大小UIFont
        [attribute addAttributes:@{NSForegroundColorAttributeName:color} range:range];
     
        self.label.attributedText = attribute;
    }
    

    11. 播放声音

    #import<AVFoundation>
     //  1.获取音效资源的路径
     NSString *path = [[NSBundle mainBundle]pathForResource:@"pour_milk" ofType:@"wav"];
     //  2.将路径转化为url
     NSURL *tempUrl = [NSURL fileURLWithPath:path];
     //  3.用转化成的url创建一个播放器
     NSError *error = nil;
     AVAudioPlayer *play = [[AVAudioPlayer alloc]initWithContentsOfURL:tempUrl error:&error];
     self.player = play;
     //  4.播放
     [play play];
    

    **12. NSTimer **

    1、NSTimer计算的时间并不精确
    2、NSTimer需要添加到runLoop运行才会执行,但是这个runLoop的线程必须是已经开启。
    3、NSTimer会对它的tagert进行retain,我们必须对其重复性的使用intvailte停止。target如果是self(指UIViewController),那么VC的retainCount+1,如果你不释放NSTimer,那么你的VC就不会dealloc了,内存泄漏了。

    13.Could not find Developer Disk Image

    在“/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport”里列出了Xcode支持的设备,从同事相同目录copy对应版本OK
    本人提供如下:
    链接: iOS9及以下 密码: v8y8
    链接: 包含iOS10.0 密码: qgew
    链接: 包含iOS10.1 密码: 84mt
    链接: 包含iOS10.2 密码: k9m9
    链接: 包含iOS10.3 密码: crzs

    14.UISearchBar 中cancel改成取消

    - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
        searchBar.showsCancelButton = YES;
        for(UIView *view in  [[[searchBar subviews] objectAtIndex:0] subviews]) {
            if([view isKindOfClass:[NSClassFromString(@"UINavigationButton") class]]) {
                UIButton * cancel =(UIButton *)view;
                [cancel setTitle:@" 取消" forState:UIControlStateNormal];
            }
        }
        return YES;
    }
    

    15.截图功能

    // iOS7.0后系统封装了截屏方法: - snapshotViewAfterScreenUpdates:
    UIView *redView = [[UIView alloc]initWithFrame:CGRectMake(100, 300, 200, 200)];
     redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView]; 
    UIView *captureView = [redView snapshotViewAfterScreenUpdates:YES];
    [self.view addSubview:captureView]; 
    // captureView.frame == (0,0,200,200)
    

    16.获取设备上所有app的bundle id

    import <objc/runtime.h>
    
    Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
    NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];NSLog(@"apps: %@", [workspace performSelector:@selector(allApplications)]);
    

    17.iOS 判断图片类型

    特征码
    JPEG,JPG: 0xFF 0xD8 2字节 JPG是JPEG的缩写
    BMP: 0x42 0x4D 2字节
    PNG: 0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A 8字节
    GIF: 0x47 0x49 0x46 0x38 0x39/ 0x37 0x61 GIF有87a和89a两种格式

    // 通过图片Data数据第一个字节 来获取图片扩展名
    - (NSString *)contentTypeForImageData:(NSData *)data {
        uint8_t c;
        [data getBytes:&c length:1];
        switch (c) {
            case 0xFF:
                return @"jpeg";
            case 0x89:
                return @"png";     
            case 0x47:
            case 0x37:
                return @"gif";        
            case 0x49:   
            case 0x4D:
                return @"tiff";
            case 0x42:
                return @"bmp";        
            case 0x52:  
                if ([data length] < 12) {
                    return nil;
                }
                NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
                if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
                    return @"webp";
                }
                return nil;
        }
        return nil;
    }
    

    其实图片数据的第一个字节是固定的,一种类型的图片第一个字节就是它的标识, 我们来调用一下这个方法:
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:picPathStr]];
    NSString *string = [self contentTypeForImageData:data];

    18.App迭代开发版本号的规则介绍

    • 1.修复Bug或者优化功能, 我们只修改叠加第三位数字, 其他不变,如1.0.1
    • 2.有了新的需求, 在原基础上增加新功能, 版本号变为1.1.0, 清空第三位为0, 叠加第二位
    • 3.需求功能大改, 更新量非常大, 那我们的版本号变为2.0.0, 需要叠加第一位, 清空其他为0

    19.iOS 系统权限介绍

    20.私有API实现进入后台(相当于按home键)

    [[UIApplication sharedApplication] performSelector:@selector(suspend)];  // suspend:暂停;
    

    21.带有中文的URL处理

    NSString *URLStr = @"http://static.tripbe.com/videofiles/视频/我的自拍视频.mp4";
    // NSString *path  = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)URLStr, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    NSString* encodedURLString = [URLStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    

    22.给UIView/UILabel设置图片

    • 使用UIImageView
    • [view setBackGroundColor:[UIColor colorWithPatternImage:img];
    • CALayer
    view.layer.contents = (__bridge id)image.CGImage;
    //设置显示的图片范围,四个值在0-1之间,对应的为x, y, w, h
    view.layer.contentsCenter = CGRectMake(0.25,0.25,0.5,0.5);
    

    23.VC设置背景图片

    // 没必要添加UIImageView,直接在layer上画
    self.view.layer.contents = (__bridge id _Nullable)([UIImage imageNamed:@"beijing"].CGImage)
    

    24.view的部分圆角问题

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view2.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(10, 10)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = view2.bounds;
    maskLayer.path = maskPath.CGPath;
    view2.layer.mask = maskLayer;
    //其中,
    byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight
    /* 指定了需要成为圆角的角,用“|”组合。该参数是UIRectCorner类型的,可选的值有:
    * UIRectCornerTopLeft
    * UIRectCornerTopRight
    * UIRectCornerBottomLeft
    * UIRectCornerBottomRight
    * UIRectCornerAllCorners
    */
    

    25.禁止程序运行时自动锁屏

    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    

    26.KVC妙用之NSArray 快速求总和、最大值、最小值、平均值

    简单集合运算符,共有@avg, @count , @max , @min ,@sum5种

    NSArray *array = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", @"10", nil];
    CGFloat sum = [[array valueForKeyPath:@"@sum.floatValue"] floatValue];
    CGFloat avg  = [[array valueForKeyPath:@"@avg.floatValue"] floatValue];
    CGFloat max = [[array valueForKeyPath:@"@max.floatValue"] floatValue];
    CGFloat min  = [[array valueForKeyPath:@"@min.floatValue"] floatValue];
    

    27.把tableview里cell的小对勾的颜色改成别的颜色

    tableView.tintColor = [UIColor redColor];
    

    28.修改textFieldplaceholder字体颜色和大小

    [textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];  
    [textField setValue:[UIFont boldSystemFontOfSize:16] forKeyPath:@"_placeholderLabel.font"];
    

    29.主线程操作UI(对UI进行更新只能在主线程进行)

    * 方法一:
    // waitUntilDone:是否线程任务完成执行
    [self performSelectorOnMainThread:@selector(updateImage:) withObject:data waitUntilDone:YES];
    
    * 方法二:
    dispatch_async(dispatch_get_main_queue(), ^{
            //更新UI的代码,不用主线程中调用
        });
    
    * 方法三:
    // 使用NSOperationQueue
    // 第一种:
        [[NSOperationQueuemainQueue]addOperationWithBlock:^{
            // do something
        }];
    // 第二种:将工作内容封装在NSOperation中,然后
    // [[NSOperationQueue mainQueue] addOperation:myOperation];
    

    30.两种方法删除NSUserDefaults所有记录

    //方法一
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
    
    //方法二
    - (void)resetDefaults {
        NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
        NSDictionary * dict = [defs dictionaryRepresentation];
        for (id key in dict) {
            [defs removeObjectForKey:key];
        }
        [defs synchronize];
    }
    

    31.UITableView设置Section间距

    // 只设一个可能仍出现20的高度,也不可设置0
    // Header底部间距
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section  
    {  
        return 40;//section头部高度  
    }  
    // footer底部间距  
    - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section  
    {  
        return 0.001;  
    } 
    

    32.常用GCD总结

        // 后台执行: 
         dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
              // something 
         }); 
         // 主线程执行: 
         dispatch_async(dispatch_get_main_queue(), ^{ 
              // something 
         }); 
         // 一次性执行: 
         static dispatch_once_t onceToken; 
         dispatch_once(&onceToken, ^{ 
             // code to be executed once 
         }); 
         // 延迟2秒执行: 
          dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)),       dispatch_get_main_queue(), ^{
                    // code to be executed after a specified delay
                });
    

    GCD高级用法,让后台2个线程并行执行,等都结束后,再汇总执行结果

        dispatch_group_t group = dispatch_group_create(); 
        dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 
              // 并行执行的线程一 
         }); 
         dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ 
              // 并行执行的线程二 
         }); 
         dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ 
              // 上面的线程走完成后,最后通知走次block,保证这部分代码最后执行 
         }); 
    
    // 1、创建主线程(串行)
        dispatch_async(dispatch_get_main_queue(), ^{
            // 刷新界面代码
        });
    // 2、创建异步线程(并行)
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //比较耗时的代码放这里
        });
        
    //3、gcd延迟
        double delayInSeconds = 1.0;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            //延迟代码
        });
        
    // 4、gcd只执行一次
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            //只执行一次代码
        });
        
    //5、有三个任务,需要异步并发执行前两个任务,前两个任务执行完成后再执行第三个任务。
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //创建组
            dispatch_group_t group=dispatch_group_create();
    // 关联一个任务到group
          dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                //任务一
                NSLog(@"******执行任务一******");
            });
            
            // 关联一个任务到group
            dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                //任务二
                NSLog(@"******执行任务二******");
            });
            // 等待组中的任务执行完毕,回到主线程执行block回调
            dispatch_group_notify(group, dispatch_get_main_queue(), ^{
                //任务三
                NSLog(@"******等待组中的任务执行完毕,回到主线程执行block回调,执行任务三******");
            });
        });
    //6、dispatch_barrier_async的使用,dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
        dispatch_queue_t queue = dispatch_queue_create("create_asy_queue", DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            NSLog(@"dispatch_async1");
        });
        dispatch_async(queue, ^{
            NSLog(@"dispatch_async2");
        });
        dispatch_barrier_async(queue, ^{
            NSLog(@"dispatch_barrier_async");
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"刷新界面");
            });
            
        });
        dispatch_async(queue, ^{
            [NSThread sleepForTimeInterval:1];
            NSLog(@"dispatch_async3");
        });
        
        /*7、GCD的另一个用处是可以让程序在后台较长久的运行。
        在没有使用GCD时,当app被按home键退出后,app仅有最多5秒钟的时候做一些保存或清理资源的工作。但是在使用GCD后,app最多有10分钟的时间在后台长久运行。这个时间可以用来做清理本地缓存,发送统计数据等工作。
        让程序在后台长久运行的示例代码如下:
        */
    // AppDelegate.h文件
    @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;
        
    // AppDelegate.m文件
    - (void)applicationDidEnterBackground:(UIApplication *)application {
            [self beingBackgroundUpdateTask];
            // 在这里加上你需要长久运行的代码
            [self endBackgroundUpdateTask];
        }
        
    - (void)beingBackgroundUpdateTask {
            self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
                [self endBackgroundUpdateTask];
            }];
        }
        
    - (void)endBackgroundUpdateTask {
            [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
            self.backgroundUpdateTask = UIBackgroundTaskInvalid;
        }
    
    // 附 NSOperation 概述 http://www.jianshu.com/p/3502b0d7429f
    

    33.tabBarController跳转到另一个一级页面

    当我们用tabBarController时,若已经到其中一个TabBar的子页,又要跳转到某一个一级的页面时,如果这样写,导致底部出现黑边,引起tabbar消失的bug

    [self.navigationController popToRootViewControllerAnimated:YES];
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
    
    * 解决方法一:删除动画
    [self.navigationController popToRootViewControllerAnimated:NO];
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
    
    * 解决方法二:延迟执行另一个系统操作
    [self.navigationController popToRootViewControllerAnimated:NO];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    ((AppDelegate *)AppDelegateInstance).tabBarController.selectedIndex = 2;
        });
    

    34. UIWebView获取Html的标题title

    titleLabel.text = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    

    35.user-Agent问题

    // AppDelegate 中 - (BOOL)application: didFinishLaunchingWithOptions:
    NSDictionary *dict = @{@"UserAgent":@"appwebkit"};
    [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
    

    考虑到兼容性,只对某些webview实施自定义UA。这几个方法一定要是静态方法,要不然设置UA不生效

    NSString* defaultUserAgent = nil;
    #pragma mark 获取默认的UA,用于恢复UA
    + (void)initialize {
        if (self == [WebViewController class]) {
            defaultUserAgent =  [[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
        }
    }
    #pragma mark 在默认UA后追加自定义UA
    + (void)registeCustomizeWebViewUserAgent {
        UIDevice *device = [UIDevice currentDevice];
        NSString *iOSName = [device systemName];
        NSString *iOSVersion = [device systemVersion];
        NSString *customizeUserAgent = [NSString stringWithFormat:@"xxxxxMobile/%@ (Platform/%@; %@/%@)", APP_SHORT_VERSION, @"iPad", iOSName, iOSVersion];
        NSString *webViewUserAgent = [[UIWebView new] stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
        customizeUserAgent = [webViewUserAgent stringByAppendingFormat:@" %@", customizeUserAgent];
        if (customizeUserAgent) {
            [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent": customizeUserAgent}];
        }
    }
    - (void)dealloc {
        /*由于自定义的userAgent无法播放webview的视频,所以。当webview销毁的时候,重置一下userAgent*/
        [[self class] recoverDefaultUserAgent];
    }
    + (void) recoverDefaultUserAgent {
        if (defaultUserAgent) {
            [[NSUserDefaults standardUserDefaults] registerDefaults:@{ @"UserAgent": defaultUserAgent}];
        }
    }
    

    36.汉字转为拼音

    - (NSString *)Charactor:(NSString *)aString getFirstCharactor:(BOOL)isGetFirst {
        //转成了可变字符串
        NSMutableString *str = [NSMutableString stringWithString:aString];
        //先转换为带声调的拼音
        CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
        //再转换为不带声调的拼音
        CFStringTransform((CFMutableStringRef)str,NULL, kCFStringTransformMandarinLatin,NO);
        CFStringTransform((CFMutableStringRef)str, NULL, kCFStringTransformStripDiacritics, NO);
        NSString *pinYin = [str capitalizedString];
        //转化为大写拼音
        if(isGetFirst) {
            //获取并返回首字母
            return [pinYin substringToIndex:1];
        } else {
            return pinYin;
        }
    }
    

    37.打印宏定义

    // 处于开发阶段
    #ifdef DEBUG
    #define DDYLog(...) NSLog(__VA_ARGS__)
    #define DDYInfoLog(fmt, ...) NSLog((@"\n[fileName:%s]\n[methodName:%s]\n[lineNumber:%d]\n" fmt),__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
    // 处于发布阶段
    #else
    #define DDYLog(...)
    #define DDYInfoLog(...)
    #endif
    

    38.CocoaPods

    CocoaPods教程
    CocoaPods教程

    39.Runtime objc_msgSend报错

    Too many arguments to function call ,expected 0,have3
    Project --> Build Settings --> 搜索objc --> ENABLE_STRICT_OBJC_MSGSEND --> 设置NO

    40.保存view为image

    UIGraphicsBeginImageContext(self.bounds.size);
        if([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]){
            [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO];
        }
        else{
            [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        }
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        NSData *imageData = UIImageJPEGRepresentation(image, 0.75);
        image = [UIImage imageWithData:imageData];
        return image;
    

    41. 捕获系统外异常

    void UncaughtExceptionHandler(NSException *exception) {
        NSArray  *callStackSymbols = [exception callStackSymbols];
        NSString *callStackSymbolStr = [callStackSymbols componentsJoinedByString:@"\n"];
        NSString *reason = [exception reason];
        NSString *name = [exception name];
        DDYInfoLog(@"异常名称:%@\n异常原因:%@\n堆栈标志:%@",name, reason, callStackSymbolStr);
    }
    

    - application: didFinishLaunchingWithOptions:

    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
    

    42.Xcode8打印过多subsystem: category:

    Product–>Scheme–>Edict Scheme–>Run–>Envlronment Variables –>添加OS_ACTIVITY_MODE值disable

    44.语法糖

    self.imageView = ({
        UIImageView *imageView = [[UIImageView alloc] init];
        imageView.image = [UIImage imageNamed:@"12345"];
        imageView.frame = CGRectMake(0, 0, 100, 100);
        [self.view addSubview:imageView];
        imageView;
    });
    

    45.获取当前显示的控制器

    + (UIViewController *)findCurrentResponderViewController{ 
    UIViewController *currentVC = nil; 
    UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 
    if (window.windowLevel != UIWindowLevelNormal) { 
    NSArray *windows = [[UIApplication sharedApplication] windows]; 
    for(UIWindow *tmpWin in windows) { 
    if (tmpWin.windowLevel == UIWindowLevelNormal) 
    { window = tmpWin; break; 
         }
       }
     }
     UIView *frontView = [[window subviews] objectAtIndex:0]; 
    id nextResponder = [frontView nextResponder]; 
    if ([nextResponder isKindOfClass:[UIViewController class]]) 
    currentVC = nextResponder; 
    else 
    { 
    UIViewController *topVC = window.rootViewController.presentedViewController; 
    if (topVC) { 
    currentVC = topVC; 
    }else{ 
    currentVC = window.rootViewController;
     } 
    } 
    return currentVC;
    }
    

    view中跳转

    NASkillAptitudeVC *vc = [[NASkillAptitudeVC alloc] init];
        [[self currentViewController].navigationController pushViewController:vc animated:YES];
    
    - (UIViewController *)currentViewController {
        UIResponder *next = self.nextResponder;
        do {
            //判断响应者是否为视图控制器
            if ([next isKindOfClass:[UIViewController class]]) {
                return (UIViewController *)next;
            }
            next = next.nextResponder;
        } while (next != nil);
        
        return nil;
    }
    

    46. UIView虚线框

    CAShapeLayer *borderLayer = [CAShapeLayer layer];
    borderLayer.bounds = self.picView.frame;
    borderLayer.position = self.picView.center;
    borderLayer.path = [UIBezierPath bezierPathWithRoundedRect:borderLayer.bounds cornerRadius:3].CGPath;
    borderLayer.lineWidth = 1;
    borderLayer.lineDashPattern = @[@4, @2];
    borderLayer.fillColor = [UIColor clearColor].CGColor;
    borderLayer.strokeColor = [UIColor grayColor].CGColor;
    [self.picView.layer addSublayer:borderLayer];
    

    iOS为UIView添加虚线边框

    47.iOS打电话的三种方式对比

    打电话的三种方式对比

    48.TableViewCell间距

    - (void)setFrame:(CGRect)frame {
        // 整体向下 移动10 
        frame.origin.y += 10;
        // 间隔10 
        frame.size.height -= 10;
        [super setFrame:frame];
    }
    

    49.带UITableView的界面出现空白解决

    - (void)deleteTopBlank
    { 
            self.edgesForExtendedLayout = UIRectEdgeNone;
            self.navigationController.navigationBar.translucent = NO;
            self.automaticallyAdjustsScrollViewInsets = NO;
            self.extendedLayoutIncludesOpaqueBars = YES
    }
    

    50.判断字符串是否是整型

    - (BOOL)isPureInt:(NSString *)string {
      NSScanner* scan = [NSScanner scannerWithString:string];
      int val;
      return [scan scanInt:&val] && [scan isAtEnd];
    }
    

    51.字符串数字当位数不够时补0

    // *号当占位符
    _minuteLabel.text = [NSString stringWithFormat:@"%0*d",wid, minute];
    // 直接写位数
    _secondLabel.text = [NSString stringWithFormat:@"%02d",second];
    

    52.weakSelf定义

    __weak __typeof__ (self)weakSelf = self;

    53.状态栏高度和导航栏高度

    状态栏通常高度20,在通话中和有热点连接时40
    获取状态栏高度
    [[UIApplication sharedApplication] statusBarFrame].size.height

    状态栏发生变化通知

    UIApplicationWillChangeStatusBarFrameNotification
    UIApplicationDidChangeStatusBarFrameNotification
    

    获取导航栏高度
    self.navigationController.navigationBar.frame.size.height

    ttp://www.jianshu.com/p/8c8303f7d439

    54.终端Vim编辑器显示行号

    按esc,输入: 然后输入set number回车

    55.移除子视图

    [view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    

    56.在线工具

    在线编译 菜鸟工具
    unicode转中文

    57.button文字居左显示

    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;

    58.Mac系统显示/隐藏文件

    显示:defaults write com.apple.finder AppleShowAllFiles -bool true
    隐藏:defaults write com.apple.finder AppleShowAllFiles -bool false
    

    59. 获取keywindow

    // iOS 9 之前
    UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
    // iOS 9 之后
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]
    

    .

    60. 网络请求参数为字典/数组/字典和数组嵌套问题

    - (NSString *)changeToString:(id)sender
    {
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sender options:NSJSONWritingPrettyPrinted error:nil];
        return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    // [self changeToString:array];
    
    

    61.判断空值

    判断空值别直接 if (str) ,如果字符串为空描述时可能出现问题
    要用下面方法

    - (BOOL)isBlankString:(NSString *)string
    {
        if (string == nil || string == NULL || [string isKindOfClass:[NSNull class]])
        {
            return YES;
        }
        if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]==0)
        {
            return YES;
        }
        return NO;
    }
    
    

    62.判断只有数字、小数点和减号

    #define NUMBERS @"0123456789.-"
    
    #pragma mark -是否只包含数字,小数点,负号
    - (BOOL)isOnlyhasNumberAndpointWithString:(NSString *)string
    {
        NSCharacterSet *cs=[[NSCharacterSet characterSetWithCharactersInString:NUMBERS] invertedSet];
        NSString *filter=[[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
        return [string isEqualToString:filter];
    }
    

    63.判断系统版本

    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0)
    {
    }
    else
    {
    }
    

    64. NSNotificationCenter

    需要接收通知的地方注册观察者

    //获取通知中心单例对象
        NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
        //添加当前类对象为一个观察者,name和object设置为nil,表示接收一切通知
        [center addObserver:self selector:@selector(notice:) name:@"123" object:nil];
    

    发送通知消息

    //创建一个消息对象
        NSNotification * notice = [NSNotification notificationWithName:@"123" object:nil userInfo:@{@"1":@"123"}];
        //发送消息
           [[NSNotificationCenter defaultCenter]postNotification:notice];
    

    回调的函数中取到userInfo内容

    -(void)notice:(id)sender{
        NSLog(@"%@",sender);
    }
    

    65.监听耳机的插拔

    //监听耳机的插拔
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(routeChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
    
    //相应的事件
    - (void)routeChange:(NSNotification *)notification {
        NSDictionary *interuptionDict = notification.userInfo;
        NSInteger roteChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    
        switch (roteChangeReason) {
            case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
                //插入耳机
                break;
            case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
                //拔出耳机
                NSLog(@"拔出耳机");
                [self pausePlay];
                break;
    
        }
    }
    

    66.点击耳机中键的事件

    首先要在程序入口处让app接收远程控制事件

    //让app支持接收远程控制事件
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    

    然后在远程事件通知中进行相应的操作(这个通知还会接收系统上拉菜单中的控制中心的播放和暂停按钮)

    //app接受远程控制(控制中心 耳机等)
    - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    
        if (event.type == UIEventTypeRemoteControl) {
            switch (event.subtype) {
                case 100:
                    //控制中心的播放按钮
                    [[PlayingManager defaultManager] musicPlay];
                    break;
                case 101:
                    //控制中心的暂停按钮
                    [[PlayingManager defaultManager] pausePlay];
                    break;
                case 103:{
                    //耳机的单击事件 根据音乐的播放状态选择暂停或播放
                    if ([[PlayingManager defaultManager] getStateOfPlayer]) {
                        [[PlayingManager defaultManager] pausePlay];
                    } else {
                        [[PlayingManager defaultManager] musicPlay];
                    }
                }
                    break;
                case 104:
                    //耳机的双击中键事件 
                    [[PlayingManager defaultManager] nextMusic];
                    break;
                 case 105:
                    //耳机的中键盘点击三下触发的时间
                    [[PlayingManager defaultManager] beforeMusic];
                    break;
                default:
                    break;
            }
        }
    }
    

    67.检测程序是在真机上还是在模拟器上

    #if TARGET_IPHONE_SIMULATOR
    #define SIMULATOR 1
    #elif TARGET_OS_IPHONE
    #define SIMULATOR 0
    #endif
    

    68.view中获取控制器

    - (UIViewController*)viewController:(UIView *)view {
        for (UIView* next = [view superview]; next; next = next.superview) {
            UIResponder* nextResponder = [next nextResponder];
            if ([nextResponder isKindOfClass:[UINavigationController class]]) {
                return (UIViewController*)nextResponder;
            }
        }
        return nil;
    }
    
    /获取导航控制器
    - (UINavigationController*)navigationController:(UIView *)view {
        for (UIView* next = [view superview]; next; next = next.superview) {
            UIResponder* nextResponder = [next nextResponder];
            if ([nextResponder isKindOfClass:[UINavigationController class]]) {
                return (UINavigationController*)nextResponder;
            }
        }
        return nil;
    }
    

    69. 稍后执行与取消

    情景:视频直播1V1连麦,邀请A观众连麦,A不回应可能导致无法邀请其他观众,此时就要设定超时。但如果A回应了就要取消超时

    // selector 和 object 两次调用要是一致的
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(inviteTimeOut:) object:userID];
    [self performSelector:@selector(inviteTimeOut:) withObject:userID afterDelay:100];
    

    70.防止点击cell后仍为灰色

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
    

    71.沙盒

    /* 默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp
    Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
    Library:存储程序的默认设置或其它状态信息;
    Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
    tmp:提供一个即时创建临时文件的地方。
    iTunes在与iPhone同步时,备份所有的Documents和Library文件。
    iPhone在重启时,会丢弃所有的tmp文件。
    */
    // 获取Cache目录:
    NSArray*paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES); 
    NSString *path = [paths objectAtIndex:0];
    NSLog(@"%@", path);
    
    // 获取documents目录:
    NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    NSLog(@"path:%@", path);
    
    // 获取Libarary目录:
    NSArray*paths =NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    NSLog(@"%@", path);
    
    // 获取tmp目录:
    NSString*tmpDir = NSTemporaryDirectory(); 
    NSLog(@"%@", tmpDir);
    
    // NSFileManager创建目录、文件
    // 创建文件:
    NSString*rootPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];
    NSString*plistPath = [rootPathstringByAppendingPathComponent:@"hhk.plist"];
    NSFileManager *fileManager = [NSFileManagerdefaultManager];
    if(![fileManager fileExistsAtPath:plistPath]) {
    [fileManagercreateFileAtPath:plistPathcontents:nilattributes:[NSDictionarydictionary]]; //创建一个dictionary文件
    }
    
    // 写入文件:
    NSMutableDictionary *dictionary= [NSMutableDictionary dictionary];
    [mutableDictionarywriteToFile:plistPath atomically:YES]
    
    // 读取文件:
    NSMutableDictionary *dictionary= [NSDictionarydictionaryWithContentsOfFile:plistPath];
    
    // 创建目录:
    NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); 
    NSString *documentsDirectory =[pathsobjectAtIndex:0]; 
    NSLog(@"documentsDirectory%@",documentsDirectory); 
    NSFileManager *fileManager = [NSFileManagerdefaultManager]; 
    NSString*testDirectory =[documentsDirectorystringByAppendingPathComponent:@"test"]; // 创建目录
    [fileManagercreateDirectoryAtPath:testDirectorywithIntermediateDirectories:YESattributes:nil error:nil];
    // http://www.cnblogs.com/uncle4/p/5547514.html
    

    72. 隐藏导航栏分割线

    @property (nonatomic, strong) UIView *navLine; //导航分割线
    
    UIView *backgroundView = [self.navigationController.navigationBar subviews].firstObject;
        // _navLine = backgroundView.subviews.firstObject;
    for (UIView *view in backgroundView.subviews)
        {
            if ([view isKindOfClass:[UIImageView class]] && view.ddy_h == 0.5)
            {
                _navLine = (UIImageView *)view;
            }
        }
    
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        _navLine.hidden = YES;
        if([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
        {
            self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        }
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        _navLine.hidden = NO;
        if([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
        {
            self.navigationController.interactivePopGestureRecognizer.enabled = YES;
        }
    }
    

    73. 防止UITableViewCell或者UICollectionViewCell重用

    UICollectionViewCell

    // 有时候我们不需要重用,这时候防止重用带来混乱
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        // 防止重用问题,因为我们不需要重用
        NSString *identifier = [NSString stringWithFormat:@"%ld%ld",(long)indexPath.section,(long)indexPath.row];
        [_collectionView registerClass:[NAHomeSkillListAllCell class] forCellWithReuseIdentifier:identifier];
        NAHomeSkillListAllCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
        return cell;
    }
    

    tableViewCell

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSString *CellIdentifier = [NSString stringWithFormat:@"cell%ld%ld",indexPath.section,indexPath.row];
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }
        return cell;
    }
    

    74.关闭侧滑返回

    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) 
    {
            self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        }
    
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(doNothing:)];
        [self.view addGestureRecognizer:pan];
    
    
    -(void)doNothing:(UISwipeGestureRecognizer *)recognizer {
    }
    

    75.带超链接的文字

    <TTTAttributedLabelDelegate>
    @property (nonatomic, strong) TTTAttributedLabel *linkLabel;
    
    - (TTTAttributedLabel *)linkLabel
    {
        if (!_linkLabel) {
            _linkLabel = [[TTTAttributedLabel alloc] initWithFrame:CGRectMake(margin, 0, LC_DEVICE_WIDTH-2*margin, 60)];
            _linkLabel.linkAttributes = @{NSForegroundColorAttributeName:NAYX_APP_COLOR};
            _linkLabel.delegate = self;
            _linkLabel.numberOfLines = 0;
            [self.contentView  addSubview:_linkLabel];
        }
        return _linkLabel;
    }
    
    - (void)addTipView
    {
        NSMutableAttributedString *tipStr = [[NSMutableAttributedString alloc] initWithString:_title];
        NSRange linkRange = {25, _title.length-25};
        NSRange baseRange = {0, tipStr.length};
        [tipStr addAttribute:NSForegroundColorAttributeName value:NAYX_Mid_Black range:baseRange];
        [tipStr addAttribute:NSFontAttributeName            value:NA_FONT(14)    range:baseRange];
        
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
        paragraphStyle.lineSpacing = 6;
        [tipStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:baseRange];
        
        self.linkLabel.text = tipStr;
        [self.linkLabel addLinkToURL:[NSURL URLWithString:@"openNewPage"] withRange:linkRange];
    }
    
    _title = @"该资质需要进行人工审核,请联系考官后再返回填写资料【官方考核(线上游戏)】"
    

    76.判断是否耳机状态

    - (BOOL)isHeadphone
    {
        UInt32 propertySize = sizeof(CFStringRef);
        NSString * state   = nil;
        AudioSessionGetProperty(kAudioSessionProperty_AudioRoute ,&propertySize,&state);
        if ([(NSString *)state rangeOfString:@"Headphone"].length || [(NSString *)state rangeOfString:@"HeadsetInOut"].length)
            return YES;
        else
            return NO;
    }
    

    77.改变headerfooter颜色

    #pragma mark 代理方法改变headerfooter颜色
    - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
    {
        if ([view isMemberOfClass:[UITableViewHeaderFooterView class]])
        {
            ((UITableViewHeaderFooterView *)view).backgroundView.backgroundColor = [UIColor clearColor];
        }
    }
    

    78.视图圆角和阴影共存

      UIView *v=[[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
        v.backgroundColor=[UIColor yellowColor];
        //v.layer.masksToBounds=YES;这行去掉
        v.layer.cornerRadius=10;
        v.layer.shadowColor=[UIColor redColor].CGColor;
        v.layer.shadowOffset=CGSizeMake(10, 10); // 右下
        v.layer.shadowOpacity=0.5;
        v.layer.shadowRadius=5;
        [self.view addSubview:v];
    

    79.多级模态弹出视图dismiss

    UIViewController *rootVC = self.presentingViewController;
    
        while (rootVC.presentingViewController) {
            rootVC = rootVC.presentingViewController;
        }
    
        [rootVC dismissViewControllerAnimated:YES completion:nil];
    

    80.UITableViewStylePlain下防止HeaderFooterView悬停(悬浮)

    /**
    #pragma mark - 防止plain模式悬浮
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat sectionHeaderHeight = 50;
        if(scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
            scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0,0);
        } else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
            scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
        }
    }
    */
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        //headerView
        if (scrollView == _tableView) {
            //去掉UItableview的section的headerview黏性
            CGFloat sectionHeaderHeight = _headerView.ddy_h;
            if (scrollView.contentOffset.y<=sectionHeaderHeight && scrollView.contentOffset.y>=0) {
                scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
            } else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
                scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
            }
        }
        
        //footerView
        if (scrollView == _tableView) {
            //去掉UItableview的section的footerview黏性
            CGFloat sectionFooterHeight = 55;
            if (scrollView.contentOffset.y<=sectionFooterHeight && scrollView.contentOffset.y>=0) {
                scrollView.contentInset = UIEdgeInsetsMake(0, 0, -sectionFooterHeight, 0);
            } else if (scrollView.contentOffset.y>=sectionFooterHeight) {
                scrollView.contentInset = UIEdgeInsetsMake(0, 0, -sectionFooterHeight, 0);
            }
        }
    }
    
    /*
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        
        CGFloat sectionHeaderHeight = _headerView.ddy_h;
        CGFloat sectionFooterHeight = 55;
        CGFloat offsetY = scrollView.contentOffset.y;
        if (offsetY >= 0 && offsetY <= sectionHeaderHeight)
        {
            scrollView.contentInset = UIEdgeInsetsMake(-offsetY, 0, -sectionFooterHeight, 0);
        }else if (offsetY >= sectionHeaderHeight && offsetY <= scrollView.contentSize.height - scrollView.frame.size.height - sectionFooterHeight)
        {
            scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, -sectionFooterHeight, 0);
        }else if (offsetY >= scrollView.contentSize.height - scrollView.frame.size.height - sectionFooterHeight && offsetY <= scrollView.contentSize.height - scrollView.frame.size.height)
        {
            scrollView.contentInset = UIEdgeInsetsMake(-offsetY, 0, -(scrollView.contentSize.height - scrollView.frame.size.height - sectionFooterHeight), 0);
        }
    }
    */
    

    81.根据时间戳获取时间

    很多情况需要根据时间戳计算是几分钟前,几小时前或者几天前

    #pragma mark 返回相对时间 2小时前
    - (NSString *)updateTimeForRow:(NSString *)lastTimeStr
    {
        // 获取当前时时间戳 1466386762.345715 十位整数 6位小数
        NSTimeInterval currentTime = [[NSDate date] timeIntervalSince1970];
        // 最后登录时间戳(后台返回的时间)
        NSTimeInterval createTime = [lastTimeStr longLongValue]/((lastTimeStr.length == 13)?1000:1);
        // 时间差
        NSTimeInterval time = currentTime - createTime;
        
        NSInteger sec = time/60;
        if (sec<60)
        {
            return [NSString stringWithFormat:@"%ld分钟前",sec];
        }
        
        // 秒转小时
        NSInteger hours = time/3600;
        if (hours<24)
        {
            return [NSString stringWithFormat:@"%ld小时前",hours];
        }
        //秒转天数
        NSInteger days = time/3600/24;
        if (days < 30)
        {
            return [NSString stringWithFormat:@"%ld天前",days];
        }
        //秒转月
        NSInteger months = time/3600/24/30;
        if (months < 12)
        {
            return [NSString stringWithFormat:@"%ld月前",months];
        }
        //秒转年
        NSInteger years = time/3600/24/30/12;
        return [NSString stringWithFormat:@"%ld年前",years];
    }
    

    返回年月日时分秒

    #pragma mark 返回年月日时分秒
    - (NSString *)timeToString:(NSString *)str
    {
        if ([self isBlankString:str])
        {
            return @"";
        }
        NSTimeInterval time = [str doubleValue];//+28800;//因为时差问题要加8小时 == 28800 sec
        NSDate *detaildate=[NSDate dateWithTimeIntervalSince1970:time];
        NSLog(@"date:%@",[detaildate description]);
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        [dateFormatter setDateFormat:@"MM月dd日 HH:mm"];
        NSString *currentDateStr = [dateFormatter stringFromDate: detaildate];
        return currentDateStr;
    }
    

    82.UISwitch改变大小

    // 不能改变frame,采用缩放方式
    switchBtn.transform = CGAffineTransformMakeScale(0.75, 0.75);
    

    83.获取当前时间

    + (NSString*)getCurrentTime
    {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; //hh:12小时制 HH:24小时制
        NSDate *dateNow = [NSDate date];
        NSString *currentTimeString = [formatter stringFromDate:dateNow];
        return currentTimeString;
    }
    
    // 获取当前时间戳有两种方法(以秒为单位)
    +(NSString *)getNowTimeTimestamp {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
        [formatter setDateStyle:NSDateFormatterMediumStyle];
        [formatter setTimeStyle:NSDateFormatterShortStyle];
        [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; 
        //设置时区,这个对于时间的处理有时很重要
        NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
        [formatter setTimeZone:timeZone];
        NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
        NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
        return timeSp;
    }
    
    +(NSString *)getNowTimeTimestamp2{
        NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
        NSTimeInterval a=[dat timeIntervalSince1970];
        NSString*timeString = [NSString stringWithFormat:@"%0.f", a];//转为字符型
    return timeString;
    }
    
     //获取当前时间戳  (以毫秒为单位)
    
    +(NSString *)getNowTimeTimestamp3{
    
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    
        [formatter setDateStyle:NSDateFormatterMediumStyle];
    
        [formatter setTimeStyle:NSDateFormatterShortStyle];
    
        [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss SSS"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    
        //设置时区,这个对于时间的处理有时很重要
    
        NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    
        [formatter setTimeZone:timeZone];
    
        NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
    
        NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]*1000];
    
        return timeSp;
    
    }
    
    

    84.NSString 和 NSURL转化

    NSURL *URL = [NSURL URLWithString:str];  //string>url
    NSString *str1 = [URL absoluteString];   //url>string
    

    85.safari保存的webAchirve转html

    终端 textutil -convert html (webarchive文件拖入)
    

    85.Xcode不提示或者宏定义不识别

    完全关闭Xcode ,终端open /Users/电脑/Library/Developer/Xcode/DerivedData

    86.UIButton改变imageView.contentMode

    必须采用setImage: forState: 不能用setBackGroundImage方式,否则模式不生效

    87.AVAudioPlayer播放声音小的解决方案

     NSError *categoryError = nil;
            AVAudioSession *audioSession = [AVAudioSession sharedInstance];
            [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&categoryError];
            [audioSession setActive:YES error:&categoryError];
            NSError *audioError = nil;
            BOOL success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioError];
            if(!success)
            {
                NSLog(@"error doing outputaudioportoverride - %@", [audioError localizedDescription]);
            }
    

    88. 按钮声音播放动画

    - (void)playVoice:(UIButton *)button
    {
        if (![self isBlankString:_skillAptitudeModel.skill_audio])
        {
            [[NAChatVoicePlayer sharedInstance] setPlayPath:_skillAptitudeModel.skill_audio];
            [NAChatVoicePlayer sharedInstance].audioCategory = AVAudioSessionCategoryPlayback;
            
            NSError *categoryError = nil;
            AVAudioSession *audioSession = [AVAudioSession sharedInstance];
            [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:&categoryError];
            [audioSession setActive:YES error:&categoryError];
            NSError *audioError = nil;
            BOOL success = [audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&audioError];
            if(!success)
            {
                NSLog(@"error doing outputaudioportoverride - %@", [audioError localizedDescription]);
            }
            
            [button setAdjustsImageWhenHighlighted:NO];
            if ([_soundBtn.imageView isAnimating])
            {
                [_soundBtn.imageView stopAnimating];
            }
            
            UIImageView *imageView = button.imageView;
            //设置动画帧
            imageView.animationImages = [NSArray arrayWithObjects:
                                       [UIImage imageNamed:@"skill_voice1"],
                                       [UIImage imageNamed:@"skill_voice2"],
                                       [UIImage imageNamed:@"skill_voice3"],
                                       nil];
            // 设置动画总时间
            imageView.animationDuration = 0.6;
            //设置重复次数,0表示无限
    //        imageView.animationRepeatCount = 5;
            //开始动画
            if (! imageView.isAnimating)
            {
                [imageView startAnimating];
            }
            [self performSelector:@selector(stopButtonAnimation) withObject:nil afterDelay:[_skillAptitudeModel.audio_second integerValue]];
    
        }
    }
    
    - (void)stopButtonAnimation
    {
        if ([_soundBtn.imageView isAnimating])
        {
            [_soundBtn.imageView stopAnimating];
        }
    }
    
    

    89 富文本计算高度

    #pragma mark 文字高度
    - (CGFloat)textH:(NSString *)text lineSpace:(CGFloat)lineSpace width:(CGFloat)width font:(UIFont *)font
    {
        NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc]init];
        paragraphStyle.lineSpacing = lineSpace;
        NSDictionary *attributes = @{NSParagraphStyleAttributeName:paragraphStyle,NSFontAttributeName:font};
        CGSize size = [text boundingRectWithSize:CGSizeMake(width, MAXFLOAT)
                                         options:NSStringDrawingUsesLineFragmentOrigin
                                      attributes:attributes
                                         context:nil].size;
        return size.height;
    }
    

    90.监听网络状态

    原生Reachability

    方法一 :command + shift + 0打开 Documentation And API reference 搜索 Reachability
    方法二:到网页[下载]https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html

    • 获取当前网络状态
    Reachability *reachability = [Reachability reachabilityWithHostName:@"www.baidu.com"];
        NetworkStatus netStatus = [reachability currentReachabilityStatus];
        switch (netStatus) {
            case NotReachable:
                break;
            case ReachableViaWiFi:
                networkStatus = 
                break;
            case ReachableViaWWAN:
                break;
    
            default:
                break;
        }
    
    • 监听网络状态
    - (void) addNotifacation
    {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
     [self.hostReachability startNotifier];
    }
    
    - (void) reachabilityChanged:(NSNotification *)note
    {
     Reachability* curReach = [note object];
     NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
     NetworkStatus netStatus = [reachability currentReachabilityStatus];
    }
    

    AFN 的二次封装监听

    [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
                switch (status)
                {
                       //结合MBProgressHUD进行显示:
                    case -1:  //AFNetworkReachabilityStatusUnknown
                    {
                        //提示框:
                        MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                        textOnlyHUD.mode = MBProgressHUDModeText;
                        textOnlyHUD.labelText = @"未知网络";
                        [textOnlyHUD hide:YES afterDelay:1.f];
                    }
                        break;
                    case 0:  //AFNetworkReachabilityStatusNotReachable
                    {
                        //提示框:
                        MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                        textOnlyHUD.mode = MBProgressHUDModeText;
                        textOnlyHUD.labelText = @"无法连接";
                        [textOnlyHUD hide:YES afterDelay:1.f];
                    }
                        break;
                    case 1:  //AFNetworkReachabilityStatusReachableViaWWAN
                    {
                        //这里是本文的核心点:采用遍历查找状态栏的显示网络状态的子视图,通过判断该子视图的类型来更详细的判断网络类型
                        NSArray *subviewArray = [[[[UIApplication sharedApplication] valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
                        int type = 0;
                        for (id subview in subviewArray)
                        {
                            if ([subview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")])
                            {
                                type = [[subview valueForKeyPath:@"dataNetworkType"] intValue];
                        }
                        switch (type)
                        {
                            case 1:
                            {
                                //提示框:
                                MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                                textOnlyHUD.mode = MBProgressHUDModeText;
                                textOnlyHUD.labelText = @"当前为2G网络";
                                [textOnlyHUD hide:YES afterDelay:1.f];
                            }
                                break;
                            case 2:
                            {
                                //提示框:
                                MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                                textOnlyHUD.mode = MBProgressHUDModeText;
                                textOnlyHUD.labelText = @"当前为3G网络";
                                [textOnlyHUD hide:YES afterDelay:1.f];
                            }
                                break;
                            case 3:
                            {
                                //提示框:
                                MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                                textOnlyHUD.mode = MBProgressHUDModeText;
                                textOnlyHUD.labelText = @"当前为4G网络";
                                [textOnlyHUD hide:YES afterDelay:1.f];
                            }
                                break;
    
                            default:
                                break;
                        }
                    }
                }
                    break;
                case 2:  //AFNetworkReachabilityStatusReachableViaWiFi
                {
                    //提示框:
                    MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                    textOnlyHUD.mode = MBProgressHUDModeText;
                    textOnlyHUD.labelText = @"当前为WIFI";
                    [textOnlyHUD hide:YES afterDelay:1.f];
                }
                    break;
    
                default:
                {
                    //提示框:
                    MBProgressHUD *textOnlyHUD = [MBProgressHUD showHUDAddedTo:self.tabBarController.view animated:YES];
                    textOnlyHUD.mode = MBProgressHUDModeText;
                    textOnlyHUD.labelText = @"无网络连接";
                    [textOnlyHUD hide:YES afterDelay:1.f];
                }
                    break;
            }
        }];
    
        //开始监测
        [[AFNetworkReachabilityManager sharedManager] startMonitoring];
    

    获取状态栏信息方式

    - (BOOL)checkNoNetwork{
        BOOL flag = NO;
        UIApplication *app = [UIApplication sharedApplication];
        NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
        int netType = 0;
        //获取到网络返回码
        for (id child in children) {
            if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
                //获取到状态栏,飞行模式和关闭移动网络都拿不到dataNetworkType;1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI
                netType = [[child valueForKeyPath:@"dataNetworkType"] intValue];
    
                switch (netType) {
                    case 0:
                        flag = NO;
                        //无网模式
                        break;
    
                    default:
                        flag = YES;
                        break;
                }
            }
        }
        return flag;
    }
    

    91.iOS5后真机上条件亮度接口

    [[UIScreen mainScreen] setBrightness: mSlider.value];
    

    92.简易更改push动画

    CATransition* transition = [CATransition animation];
    transition.duration = 0.2;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionPush;
    transition.subtype = kCATransitionFromRight;
    [[NA_APPDELEGATE currentController].navigationController.view.layer addAnimation:transition
                                                                                      forKey:nil];
    // 之后push
    [self.navigationController pushViewController:vc animation:NO];
    

    93. 跳转到AppStore评分

    -(void)goToAppStore
    {
        NSString *str = [NSString stringWithFormat:
                         @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%d",547203890];
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:str]];
    }
    

    94.判断scrollView滚动方向

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGPoint vel = [scrollView.panGestureRecognizer velocityInView:scrollView];
        GTLog(@"%f",vel.y);
        if (vel.y > 0) {
            // 下拉
        }else
        {
            // 上拉
        }
    }
    

    95.获取控件在屏幕上的相对位置

    UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
        if (!keyWindow) keyWindow = [[UIApplication sharedApplication] keyWindow];
        CGRect rect=[bView convertRect: bView.bounds toView:keyWindow];
    

    96.快速的查看一段代码的执行时间

    #define TICK   NSDate *startTime = [NSDate date]
    #define TOCK   NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])
    // 在想要查看执行时间的代码的地方进行这么处理
    TICK
    //do your work here
    TOCK
    

    97.控件抖动

    -(void)BeginWobble
    {
    
        srand([[NSDate date] timeIntervalSince1970]);
        float rand=(float)random();
        CFTimeInterval t=rand*0.0000000001;
    
        [UIView animateWithDuration:0.1 delay:t options:0  animations:^
         {
             要抖动的视图.transform=CGAffineTransformMakeRotation(-0.05);
         } completion:^(BOOL finished)
         {
             [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionAllowUserInteraction  animations:^
              {
                  要抖动的视图.transform=CGAffineTransformMakeRotation(0.05);
              } completion:^(BOOL finished) {}];
         }];
    }
    
    -(void)EndWobble
    {
    
        [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^
         {
             要抖动的视图.transform=CGAffineTransformIdentity;
         } completion:^(BOOL finished) {}];
    }
    

    98.小数化整总结

    99.窗口中有多个Responder,如何快速释放键盘

    [[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];
    

    100.视频质量

    1,固定分辨率预设属性
    (1)AVAssetExportPreset640x480:设置视频分辨率640x480
    (2)AVAssetExportPreset960x540:设置视频分辨率960x540
    (3)AVAssetExportPreset1280x720:设置视频分辨率1280x720
    (4)AVAssetExportPreset1920x1080:设置视频分辨率1920x1080
    (5)AVAssetExportPreset3840x2160:设置视频分辨率3840x2160

    2,相对质量预设属性
    (1)AVAssetExportPresetLowQuality:低质量
    (2)AVAssetExportPresetMediumQuality:中等质量
    (3)AVAssetExportPresetHighestQuality:高质量
    这种设置方式,最终生成的视频分辨率与具体的拍摄设备有关。比如 iPhone6 拍摄的视频:
    使用AVAssetExportPresetHighestQuality则视频分辨率是1920x1080(不压缩)。
    AVAssetExportPresetMediumQuality视频分辨率是568x320
    AVAssetExportPresetLowQuality视频分辨率是224x128

    101.二维码扫描GBK编码中文乱码甚至空值问题解决

     NSString *result=self.ScanResultString;//返回的扫描结果
            NSData *data=[self.ScanResultString dataUsingEncoding:NSUTF8StringEncoding];
            NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
            NSString *retStr = [[NSString alloc] initWithData:data encoding:enc];//如果中文是utf-8编码转gbk结果为空(还没搞明白)
       if (retStr)//如果扫描中文乱码则需要处理,否则不处理
         {
           NSInteger max = [self.ScanResultString length];
           char *nbytes = malloc(max + 1);
           for (i = 0; i < max; i++)
           {
              unichar ch = [self.ScanResultString  characterAtIndex: i];
              nbytes[i] = (char) ch;
           }
           nbytes[max] = '\0';
          result=[NSString stringWithCString: nbytes
                                          encoding: enc];
         }
    

    相关文章

      网友评论

      • 梁森的简书:"防止按钮短时间多次点击" 个人感觉这样的应用场景并不多吧。 如果防止多次点击我会在点击第一次后让按钮交互失效,需要再次交互的时候在设置交互有效
        DDY:各有优劣,怎么实用,怎么简单,怎么来。比如视频播放我想点击屏幕隐藏多余控件,就不能单纯用停止交互了
      • 0无敌小宋0:小伙子不错:smile:
        DDY:这是 1 还有2,3,4,5,6:stuck_out_tongue_closed_eyes:
      • c769b551ec07:写的和我的博文格式很像,自己的总结,干货!一起加油!
        c769b551ec07:@DDY 糖衣语法?求知若渴~望解释
        DDY:@取个傻子名 不是,糖衣语法。
        c769b551ec07:@取个傻子名 最后一个是运行在swift下面吧?在OC里面好像没有这样的语法
      • 刘三刀:继续加油
        DDY:@刘三刀 好的

      本文标题:知识点1

      本文链接:https://www.haomeiwen.com/subject/gyjwyttx.html