Skip to content

Files

Latest commit

f1b58ae · Dec 26, 2019

History

History
1164 lines (948 loc) · 36.9 KB

Tip002.md

File metadata and controls

1164 lines (948 loc) · 36.9 KB

本文对应github地址Tip002,如果由于github调整导致资源找不到,请访问github

上篇 知识点1 传送门

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

  • NSScanner

     - (BOOL)isPureInt:(NSString *)string {
       NSScanner* scan = [NSScanner scannerWithString:string];
       int val;
       return [scan scanInt:&val] && [scan isAtEnd];
     }
    
  • 还可以正则表达式

    详见github NSPredicate传送门

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

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

52.weakSelf,strongSelf定义

  • 手写

     __weak __typeof__ (self)weakSelf = self; 
     __strong __typeof__ (weakSelf)strongSelf = weakSelf;
    
  • 宏定义(autoreleasepool方式需要添加@符号)

     #ifndef weakify
     #if DEBUG
     #if __has_feature(objc_arc)
     #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
     #else
     #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
     #endif
     #else
     #if __has_feature(objc_arc)
     #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
     #else
     #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
     #endif
     #endif
     #endif
     
     #ifndef strongify
     #if DEBUG
     #if __has_feature(objc_arc)
     #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
     #else
     #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
     #endif
     #else
     #if __has_feature(objc_arc)
     #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
     #else
     #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
     #endif
     #endif
     #endif
    

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

  • 状态栏通常高度20(X系列44)但在通话中和有热点连接时+20,所以最好别写死

  • 获取状态栏高度

     [[UIApplication sharedApplication] statusBarFrame].size.height 
    
  • 状态栏发生变化通知

     UIApplicationWillChangeStatusBarFrameNotification
     UIApplicationDidChangeStatusBarFrameNotification
    
  • 获取导航栏高度(View中需要先获取导航控制器)

     self.navigationController.navigationBar.frame.size.height 
    

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

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

55.移除子视图

  • 姿势一

     [view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    
  • 姿势二

     for (UIView *subView in view.subviews) {
     	[subView removeFromSuperview];
     }
    

56. 在线工具

在线编译 菜鸟工具
unicode转中文
DNS查询
bejson

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

  • 两者区别请移步百度(比如弹出了Alert时用哪个)

     #define DDYKeyWindow \
     [[[UIApplication sharedApplication] delegate] window] ? \
     [[[UIApplication sharedApplication] delegate] window] : \
     [[UIApplication sharedApplication] keyWindow]
    
  • 还可以从window数组中取

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.判断空值(nil, null, @"")

  • 判断空值别直接 if (str) ,如果字符串为空描述时可能出现问题

     + (BOOL)ddy_blankString:(NSString *)string {
         if (string == nil || string == NULL || [string isKindOfClass:[NSNull class]] || [[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) {
     	// iOS10+
     } else {
     	// iOS9-
     }
    
  • 现在

     if (@available(iOS 10.0, *)) {
         // [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
     } else {
         // [[UIApplication sharedApplication] openURL:url];
     }
    

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. 删除MacOS自带输入法

69. 稍后执行与取消

  • 本次执行取消上次等待执行的队列

     // selector 和 object 两次调用要是一致的
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(inviteTimeOut:) object:userID];
     // 取消所有
     // [NSObject cancelPreviousPerformRequestsWithTarget:self];
     [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;
    }
}
  • 姿势二

     // 背景色(设置图片形式)
     [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
     // 分割线(设置图片形式)
     self.navigationController.navigationBar.shadowImage = [UIImage new]; 
    

73. Cell不重用

用同Cell不同ID

  • 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;
     }
    
  • 非国行可能出问题加 timeZone

     /**
       *  FDateFormatterStyle
       *  kCFDateFormatterNoStyle     无输出
       *  kCFDateFormatterShortStyle  10/29/12, 2:27 PM
       *  kCFDateFormatterMediumStyle 10,29,2012, 2:39:56 PM
       *  kCFDateFormatterLongStyle   10,29,2012, 2:39:56 PM GMT+08:00
       *  kCFDateFormatterFullStyle   星期日,10,29,2012, 2:39:56 PM China Standard Time
       *
       *
       *  G: 公元时代,例如AD公元
       *  yy: 年的后2位
       *  yyyy: 完整年
       *  MM: 月,显示为1-12
       *  MMM: 月,显示为英文月份简写,如 Jan
       *  MMMM: 月,显示为英文月份全称,如 Janualy
       *  dd: 日,2位数表示,如02
       *  d: 日,1-2位显示,如 2
       *  e: 1~7 (一周的第几天, 带0)
       *  EEE: 简写星期几,如Sun
       *  EEEE: 全写星期几,如Sunday
       *  aa: 上下午,AM/PM
       *  H: 时,24小时制,0-23
       *  K:时,12小时制,0-11
       *  m: 分,1-2位
       *  mm: 分,2位
       *  s: 秒,1-2位
       *  ss: 秒,2位
       *  S: 毫秒
       *  Q/QQ: 1~4 (0 padded Quarter) 第几季度
       *  QQQ: Q1/Q2/Q3/Q4 季度简写
       *  QQQQ: 1st quarter/2nd quarter/3rd quarter/4th quarter 季度全拼
       *  zzz表示时区
       *  timeZone:[NSTimeZone timeZoneWithName:@"Asia/Shanghai"]
       *           [NSTimeZone timeZoneForSecondsFromGMT:0*3600]
       */
    

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. git运用

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
    方法二:到网页下载

  • 获取当前网络状态

     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;
     }
    
  • 很遗憾的是在局域网时可能误判,详见Reachability检测网络状态

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. 关闭Mac SIP

详见

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) {}];
}

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

  • 姿势一

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

     [[[UIApplication sharedApplication] keyWindow] endEditing:YES];