iOS - Common Sense

这些都是本身以为很是宝贵的知识(也有踩过的坑),在此保存和分享一下html

持续更新...java

1.计算代码行数

find . -name "*.m" -or -name "*.h" -or -name "*.xib" -or -name "*.c" |xargs wc -l
复制代码

2.防止滑动tableView时,定时器中止运行

[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
复制代码

3.iOS 判断app程序第一次启动方法

if(![[NSUserDefaults standardUserDefaults] boolForKey:@"firstStart"])
{
    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"firstStart"];
        
        NSLog(@"第一次启动");
}else{
        
        NSLog(@"不是第一次启动");
}
复制代码

4. cocoapods 版本管理

Podfile 或者 Cartfile 中指定依赖版本的时候咱们能够看到相似这样的小飘箭头的符号,这表明版本兼容。好比兼容 2.6.1 表示高于 2.6.12.6.x 版本均可以使用,而 2.7 或以上不行;同理,若是兼容 2.6 的话,2.62.72.8 等等这些版本都是兼容的,而 3.0 不行。固然也可使用 >= 或者是 = 这些符号。ios

4.png

5. fastlane

开发老是有趣的,可是发布通常都很无聊。由于发布流程每次都同样,很是机械。无非就是跑测试,打 tag,上传代码,写 release log,更新 podspec 等等。虽然简单,可是费时费力,容易出错。对于这种情景,自动化流程显然是最好的选择。而相比于本身写发布脚本,在 Cocoa 社区咱们有更好的工具,那就是 fastlane。面试

fastlane 是一系列 Cocoa 开发的工具的集合,包括跑测试,打包 app,自动截图,管理 iTunes Connect 等等。json

6.RunLoop 的运行状态

注册 RunLoopObserver 能够观测当前 RunLoop 的运行状态,并在状态机切换时收到通知:windows

  • RunLoop开始
  • RunLoop即将处理Timer
  • RunLoop即将处理Source
  • RunLoop即将进入休眠状态
  • RunLoop即将从休眠状态被事件唤醒
  • RunLoop退出

RunLoop.png

7.Autorelease对象何时释放?

这个问题拿来作面试题,问过不少人,没有几个能答对的。不少答案都是“当前做用域大括号结束时释放”,显然木有正确理解Autorelease机制。tomcat

在没有手加Autorelease Pool的状况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它可以释放的缘由是系统在每一个runloop迭代中都加入了自动释放池Push和Pop
————Sunny 博客bash

8.CocoaPods pod install/pod update更新慢的问题

  • pod install --verbose --no-repo-update
  • pod update --verbose --no-repo-update

9.Object-C Category 和 Class Extension 的区别

Category
  • 用于给class及其subclass添加新的方法
  • 有本身单独的 .h 和 .m 文件
  • 用于添加新方法,而不能添加新属性(property)
Class Extension
  • Extension常被称为是匿名的Category
  • 用于给类添加新方法,但只做用于原始类,不做用于subclass
  • 只能对有implementation源代码的类写Extension,对于没有implementation源代码的类,好比framework class,是不能够的
  • Extension能够给原始类添加新方法,以及新属性

10.URL 组成结构

NSURL *url = [NSURL URLWithString:@"http://www.onevcat.com/2011/11/debug/;param?p=307#more-307"];
    NSLog(@"Scheme: %@", [url scheme]);
    NSLog(@"Host: %@", [url host]);
    NSLog(@"Port: %@", [url port]);
    NSLog(@"Path: %@", [url path]);
    NSLog(@"Relative path: %@", [url relativePath]);
    NSLog(@"Path components as array: %@", [url pathComponents]);
    NSLog(@"Parameter string: %@", [url parameterString]);
    NSLog(@"Query: %@", [url query]);
    NSLog(@"Fragment: %@", [url fragment]);
将url 转换为合法的url字符串
NSString *fixedStr = [reqStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
复制代码

11.使label里的内容字体大小自适应label

descriptionLabel.adjustsFontSizeToFitWidth = YES;
复制代码

12.用苹果自带MessageComposer 发送email/sms

developer.apple.com/library/ios…app

调用 SMS编辑器

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://800888"]];
复制代码

若须要传递内容能够作以下操做:

加入:MessageUI.framework #import <MessageUI/MFMessageComposeViewController.h>

实现代理:MFMessageComposeViewControllerDelegate

调用sendSMS函数

//内容,收件人列表
- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients
{
    MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
    if([MFMessageComposeViewController canSendText])
    {
        controller.body = bodyOfMessage;  
        controller.recipients = recipients;
        controller.messageComposeDelegate = self;
        [self presentModalViewController:controller animated:YES];
    }  
}

复制代码
// 处理发送完的响应结果
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
  [self dismissModalViewControllerAnimated:YES];
 
  if (result == MessageComposeResultCancelled)
    NSLog(@"Message cancelled")
  else if (result == MessageComposeResultSent)
    NSLog(@"Message sent") 
  else
    NSLog(@"Message failed") 
}
复制代码

默认发送短信的界面为英文的,解决办法为: 在.xib 中的Localization添加一組chinese就ok了

13.测试跳转页面

#if 1
   
    LoginViewController *vc = [[LoginViewController alloc] init];
    _window.rootViewController = vc;

#else // 测试界面用 
    
    RegisterViewController *vc = [[RegisterViewController alloc] init];
    _window.rootViewController = vc;

#endif
复制代码

14.iOS系统中的蓝色色值

[UIColor colorWithRed:0.0 green:110.0/255.0 blue:1.0 alpha:1.0];

15.判断字符串汉字和字母的个数

- (CGFloat)inputString:(NSString *)string{
    int x = 0;
    int y = 0;
    for (int i = 0; i < string.length; i++) {
        
        NSRange range = NSMakeRange(i,1);
        NSString *subString = [string substringWithRange:range];
       
        const char *cString = [subString UTF8String];
        if (strlen(cString) == 3)
        {
            NSLog(@"汉字");
            x+=1;
        }
        else if(strlen(cString) == 1){
            
            NSLog(@"字母");
            y+=1;
        }
    }

    return 10 + ([[NSString stringWithFormat:@"%lu",_selectRedAmount] length]+3+3*x+y)*5+10;
}
复制代码

16.iOS 停靠模式

16.png

17.去掉UItableview headerview黏性

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    if (scrollView == _tableView)
      {
         CGFloat sectionHeaderHeight = SECTION_HEIGHT;
         
          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);
         }
      }
}
复制代码

18.合成两张图片为一张图片

- (UIImage *)addImage:(UIImage *)image1 toImage:(UIImage *)image2 {
    UIGraphicsBeginImageContext(image1.size);
    
    CGFloat width = image1.size.width;
    CGFloat height = image1.size.height;
    
    // Draw image1
    [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
    
    // Draw image2
    [image2 drawInRect:CGRectMake(width * 0.4, height * 0.4, width*0.2, height*0.2)];
    
    
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return resultingImage;
}
复制代码

19.设置window alert等级以使其显示在状态栏之上

[_assetsCalendarWindow setWindowLevel:UIWindowLevelAlert];

iOS系统中定义了三个window层级,其中每个层级又能够分好多子层级(从UIWindow的头文件中能够看到成员变量CGFloat _windowSublevel),不过系统并无把这个属性开出来。UIWindow的默认级别是UIWindowLevelNormal,咱们打印输出这三个level的值分别以下:

2012-03-27 22:46:08.752 UIViewSample[395:f803] Normal window level: 0.000000
2012-03-27 22:46:08.754 UIViewSample[395:f803] Alert window level: 2000.000000
2012-03-27 22:46:08.755 UIViewSample[395:f803] Status window level: 1000.000000

复制代码

这样印证了他们级别的高低顺序从小到大为Normal < StatusBar < Alert

20.获取当前导航控制器下前一个控制器

- (UIViewController *)backViewController
{
    NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];

    if ( myIndex != 0 && myIndex != NSNotFound ) {
        return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
    } else {
        return nil;
    }
}
复制代码

21.mac 使用终端链接后台,输出日志,查看验证码

cd /usr/local/tomcat-app/logs/
tail -1000f /usr/local/tomcat-app/logs/catalina.out
复制代码

22.Xcode 8 运行一堆没用的logs解决办法

22-1.png

上图咱们看到,本身新建的一个工程啥也没干就打印一堆烂七八糟的东西,这个应该是Xcode 8的问题,解决办法是设置OS_ACTIVITY_MODE : disable以下图:

22-2.png

23.升级Xcode8以后文字占用空间变化

建立一个Label而后让它自适应大小,字体大小都是17最后输出的宽度是不同的,咱们再看一下,下面的数据就知道为何升级 iOS 10 以后App中有的文字显示不全了: 

英文字母会不会也有这种问题,我又经过测试,后来发现英文字母没有问题,只有汉字有问题。目前只有一个一个修改控件解决这个问题,暂时没有其余好办法来解决。

23.png

24.给tabbar添加点击动画

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {

    NSInteger index = [self.tabBar.items indexOfObject:item];

    if (self.indexFlag != index) {
        [self animationWithIndex:index];
    }

}
// 动画
- (void)animationWithIndex:(NSInteger) index {
    NSMutableArray * tabbarbuttonArray = [NSMutableArray array];
    for (UIView *tabBarButton in self.tabBar.subviews) {
        if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            [tabbarbuttonArray addObject:tabBarButton];
        }
    }
    CABasicAnimation*pulse = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    pulse.timingFunction= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pulse.duration = 0.08;
    pulse.repeatCount= 1;
    pulse.autoreverses= YES;
    pulse.fromValue= [NSNumber numberWithFloat:0.7];
    pulse.toValue= [NSNumber numberWithFloat:1.3];
    [[tabbarbuttonArray[index] layer]
     addAnimation:pulse forKey:nil];

    self.indexFlag = index;

}
复制代码

25.获取当前界面上显示的键盘UIKeyboard方法

正常状况下咱们对iOS系统键盘的使用仅限于让其显示或者隐藏,不会有须要获取到它的对象,仅当有一种状况,便是当咱们须要在界面上添加一些元素,而且但愿这些元素可以不被键盘挡住。这种状况下咱们须要找到当前键盘所在的Window,并将元素添加到这个Window上,如此一来,咱们先要找到键盘的实例对象,它是UIView的子类对象,咱们只须要调用其window方法就能找到包含了键盘的UIWindow对象,就能够进行元素的添加了。具体方法以下:

- (UIView *)findKeyboard
{
    UIView *keyboardView = nil;
    NSArray *windows = [[UIApplication sharedApplication] windows];
    for (UIWindow *window in [windows reverseObjectEnumerator])//逆序效率更高,由于键盘总在上方
    {
        keyboardView = [self findKeyboardInView:window];
        if (keyboardView)
        {
            return keyboardView;
        }
    }
    return nil;
}


- (UIView *)findKeyboardInView:(UIView *)view
{    
    for (UIView *subView in [view subviews])
    {
        if (strstr(object_getClassName(subView), "UIKeyboard"))
        {
            return subView;
        }
        else
        {
            UIView *tempView = [FTEView findKeyboardInView:subView];
            if (tempView)
            {
                return tempView;
            }
        }
    }
    return nil;
}
复制代码

26.设置UILabel行间距

NSMutableAttributedString * attrString = [[NSMutableAttributedString  alloc] initWithString:label.text];
NSMutableParagraphStyle * style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:20];
[attrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, label.text.length)]; 
label.attributedText = attrString;
复制代码

27.在image上绘制文字并生成新的image

UIFont *font = [UIFont boldSystemFontOfSize:12];
UIGraphicsBeginImageContext(image.size);
[image drawInRect:CGRectMake(0,0,image.size.width,image.size.height)];
CGRect rect = CGRectMake(point.x, point.y, image.size.width, image.size.height);
[[UIColor whiteColor] set];
[text drawInRect:CGRectIntegral(rect) withFont:font]; 
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

复制代码

28.iPhone X 适配的宏定义

#define iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) 
// 状态栏高度
#define STATUS_BAR_HEIGHT (iPhoneX ? 44.f : 20.f) 
// 导航栏高度
#define NAVIGATION_BAR_HEIGHT (iPhoneX ? 88.f : 64.f) 
// tabbar高度
#define TAB_BAR_HEIGHT (iPhoneX ? (49.f+34.f) : 49.f)
 // home indicator 
#define HOME_INDICATOR_HEIGHT (iPhoneX ? 34.f : 0.f)
复制代码

29.使用YYLabel实现超连接效果

NSString *string = @"注册即表示赞成《注册协议》和《隐私声明》";
       
        NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:string];
        attrString.yy_font           = [UIFont systemFontOfSize:12.0f];
        attrString.yy_color          = DEF_UICOLORFROMRGB(0x999999);
        attrString.yy_underlineStyle = NSUnderlineStyleNone;
        @weakify(self);
        [attrString yy_setTextHighlightRange:[string rangeOfString:@"《注册协议》"]
                                color:DEF_UICOLORFROMRGB(0x0076FF)
                      backgroundColor:[UIColor clearColor]
                            tapAction:^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect){
                                @strongify(self);
                                [self registerProtocolButtonClicked:nil];
                            }];
        [attrString yy_setTextHighlightRange:[string rangeOfString:@"《隐私声明》"]
                                color:DEF_UICOLORFROMRGB(0x0076FF)
                      backgroundColor:[UIColor clearColor]
                            tapAction:^(UIView *containerView, NSAttributedString *text, NSRange range, CGRect rect){
                                @strongify(self);
                                [self privacyStatementButtonClicked:nil];
                            }];
        
        _linkLabel           = [[YYLabel alloc] init];
        _linkLabel.frame     = CGRectMake((DEF_DEVICE_WIDTH -290)/2, self.registerBtn.bottom +20, 290, 20);
        _linkLabel.attributedText  = attrString;
        _linkLabel.textAlignment   = NSTextAlignmentCenter;
        _linkLabel.textVerticalAlignment = YYTextVerticalAlignmentCenter;
        _linkLabel.numberOfLines   = 0;
        _linkLabel.backgroundColor = [UIColor clearColor];
        [self addSubview:_linkLabel];

复制代码

30. 带有.00的数字,使用number类型json解析以后会失去精度

今天遇到了一个大坑,这个问题调查了好久。一直觉得是jar包或者哪里转错了,本身动手实验了一下,发现是json js 和java数值范围不一样引发的。

{ 
      “boolean”: true, 
      “starttimeseconds”:9223372036854122112, 
      “null”: null, 
      “number”: 11222222222222222223, 
} 
复制代码

上边是一段json格式的字符串,经由json编辑器转成json对象的结果是starttimeseconds:9223372036854122000; 形成这个现象的主要缘由是 js 中的 number 数值类型是双浮点精度类型即 double , 而 java 中的 starttimeseconds 的类型为 long 类型, 也就是说 java 中得 long 能表示的范围比 js 中 number 大, 也就意味着部分数值在 js 中存不下, 因此在 js 中字符串转成 js 中的 object 的过程当中数字精度发生额了丢失。

  • 解决方法一:将starttimeseconds设置为string类型的,这个的话来回转换的 是字符串,不存在数值丢失。
  • 解决方法二:protoful.js 的 long.js 解决。

31.进入某一页面,使某一输入框成为第一响应者,可能须要延迟

//键盘成为第一响应者,延迟展现(牢记)
- (void)viewDidAppear:(BOOL)animated{
    
    [super viewDidAppear:animated];
    [self.textField becomeFirstResponder];
}
//或者
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        [self.textField becomeFirstResponder];
    });
复制代码
相关文章
相关标签/搜索