锦集01-零碎知识

1. iOS父控件view高度改变为0,子控件不隐藏

  1. 出现这样的情况是因为view中缺少个属性,超出view部分切除掉。
  2. 解决:
    1. 代码: 代码中可添加如下属性

       //父控件frame改变 子控件被切除
       xview.clipsToBounds = YES;
      
    2. XIB: xib中可勾选 clip subviews

2. Label的换行

  1. 布局条件
    1. 左边顶部布局即可,或者顶部/centerY
    2. 最好不要设置其他约束了,否者会很麻烦(有些人就不自觉的设置距离右边边距)
  2. 在Xib中直接设置Label的换行
    1. 设置Lines = 0;
    2. 鼠标点击指到你想换行的位置,然后option+回车键即可
  3. 代码布局

     label.numberOfLines = 0;
     label.preferredMaxLayoutWidth = 200;
    

3. 系统自带cell(UITableViewcell)的优化

  1. 情景:
    1. 当我们想直接使用系统的cell,而不自定义cell时,但是这个cell又与系统的cell不一样,我们需要在系统的cell上添加子控件,一般情况下会出现复用cell时会重复添加这些子控件,那么怎么优化呢?
  2. 代码

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
     if (cell == nil) {
         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
     }
     //添加cell防止重用时重复添加
     UILabel *label = (UILabel *)[cell.contentView viewWithTag:-10];
     if (!label) {
         label = [[UILabel alloc] init];
         label.tag = -10;
         [cell.contentView addSubview:label];
     }
     label.text = [NSString stringWithFormat:@"这是cell===%zd",indexPath.row];
     [label sizeToFit];
     return cell;
     }
    

4. git多分支开发

  1. 当一个团队需要同时开发多个版本时,就需要多分支开发
  2. Xcode操作如下 图2
  3. 多分支开发特点:
    1. 分支1,分支2修改同一个文件,合并时会冲突
    2. 分支1,分支2分别修改不同的文件,分支1合并到分支2时,不会冲突,会将分支1修改的内容同步到分支2
    3. 分支1修改了文件内容,没有commit的情况下是不能切换到分支2的

5. 升级OSX High Sierra 10.13遇到一些问题及解决方法

  1. 10.13版本加强了权限的限制,尤其是对/usr/local目录,默认开通 SIP (System Intergrity Protection),它禁止了软件以root身份在Mac上运行,不管你是在终端中如何运行
  2. 例如:MyMBP:~ Jacky$ sudo chown -R $(whoami) /usr/local ,返回给你的就是: chown: Operation not permitted,哪怕你是用root的身份。
  3. mac 10.13 没有telnet命令了
    1. 关掉SIP
      1. 重启Mac,按住Command + R键直到Apple Logo出现,进入Recovery Mode模式(我感觉我是按了好半天)
      2. 点击工具里的Terminal(终端)
      3. 输入csrutil disable,之后回车
      4. 重启Mac
      5. 如果想重新开启安全设置,则重复1、2步骤,输入csrutil enable就可以了
    2. 执行sudo chown -R xyj /usr/local
    3. brew update
    4. brew install telnet

6. Xcode 9.0 报错, Safe Area Layout Guide Before IOS 9.0

  1. 解决如下
    图2

7. 真机运行报错/模拟器没问题

  1. 具体错误

     xxx has conflicting settings. xxx is automatically signed for development, but a conflicting code signing identity iPhone Distribution has been manually specified. Set the code signing identity value to "iPhone Developer" in the build settings editor, or switch to manual signing in the project editor.
    Code signing is required for product type 'Application' in SDK 'iOS 10.2'
    
  2. 解决办法:

    1. 证书有问题!!!
    2. 打包需使用线上Distribution证书,调试使用Developer 证书,检查一下对应证书存在不。
    3. TARGETS(选中项目)->build settings -> Signing->Code signing Identity->(里面全部设置为iOS Developer即可)

8. 导航栏相关知识

  1. 解决导航栏设置颜色后色值变化问题
    1. 现象: 导航栏和下面的View采用的是同一个色值,但是导航栏上出来的效果跟美工设计的效果有差别
    2. 解决办法:
      1. 这个原因是由于ios7 以上导航栏默认透明导致的,可以去掉导航栏透明度
      2. 在APPdelegate里面全局去掉

         [UINavigationBar appearance].translucent = NO;
        
      3. 某一个页面去掉

         self.navigationController.navigationBar.translucent = NO;
        
  2. 去掉导航栏下面条线
    1. 产生原因: 是由于苹果默认有shadowImage 导致
    2. 解决办法:
      1. 在APPdelegate里面全局去掉

         [[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
          [[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
        
      2. 在具体的某一个页面去掉

         [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
          [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
        
  3. 修改状态栏颜色

     - (void)setStatusBarBackgroundColor:(UIColor *)color {
        
     UIView *statusBar = [[[UIApplication sharedApplication] valueForKey:@"statusBarWindow"] valueForKey:@"statusBar"];
     if ([statusBar respondsToSelector:@selector(setBackgroundColor:)]) {
         statusBar.backgroundColor = color;
     }
     }
    

9. Git管理Xcode推送(push)代码报错: The server SSL certificate failed to verify

  1. 原因: 电脑没有安装对应的ca证书,所以无法通过https连接到git服务器。
  2. 解决办法: 通过设置git的ssl验证跳过了这个错误

     git config --global http.sslVerify false
    

10.关于xcworkspace中出现IDEWorkspaceChecks.plist 文件的问题

  1. 问题:更新了Xcode 9.3 macOS 10.13.4后,在项目中多了 IDEWorkspaceChecks.plist 文件,每一次从git拉取代码就会多出这个文件
  2. 解决办法: 由于这是Xcode新加的,因此原来的.gitignore文件中并没有对此进行忽略
  3. 通过show in Finder发现这些文件都在workspace/xcshareddata目录下
  4. 我们打开项目的.gitignore 文件,会看到有一个xcuserdata/ ,然后换行添加一个: xcshareddata/ 即可解决

10.关于XCodel提交代码出现:Xcode Couldn’t communicate with a helper application.

图2

  1. 出现这样问题的原因在于Git源代码管理,Xcode7在创建一个新的工程时会尝试着与终端上保存的全局用户名(globalUserName)和全局的email进行匹配,如果匹配不上,就会出现类似的提示警告
  2. 解决办法就是利用终端告诉Xcode你的全局用户名和全局的email,打开我们的终端,然后在里面输入下面的代码就可以解决问题:

     xcrun git config --global user.email your@email.com
     xcrun git config --global user.name "your name"
    

11.如何配置.gitignore忽略掉CocoaPods导入的第三方?

  1. 打开.gitignore文件,搜索CocoaPods,可以看到如下

     # CocoaPods
     #
     # We recommend against adding the Pods directory to your .gitignore. However
     # you should judge for yourself, the pros and cons are mentioned at:
     # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
     #
     # Pods/
    
  2. 将最后一行的# Pods/左边的 #删除即可
  3. 如何配置.gitignore?
    1. 配置

       # 此为注释 – 将被 Git 忽略
       *.a       # 忽略所有 .a 结尾的文件
       !lib.a    # 但 lib.a 除外
       /TODO     # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
       build/    # 忽略 build/ 目录下的所有文件
       doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
      
    2. Git中.gitignore文件不起作用

      1. 在.gitignore文件中增加需要忽略的文件并更新后,有时会出现相关文件并未被忽略的情况,即更新后的.gitignore并未生效。
      2. 原因是.gitignore只能忽略未被track的文件,而git有本地缓存。如果增加的ignore文件原来被track过,则需要清除缓存后update。具体做法如下:

         git rm -r --cached .
         git add .
         git commit -m 'update .gitignore'
        

12.MJRefresh的header不弹回?

  1. 如下图 图2
  2. 出现场合
    1. 使用Xib布局
  3. 解决办法:
    1. 方法一:延迟结束刷新:

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
           [self.tableView.mj_header endRefreshing];
       });
      
    2. 方法二:

       self.tableView.contentInset = UIEdgeInsetsMake(-55, 0, 0, 0);
      

13.重点!!! 静态库库使用预处理bug

  1. 场景描述
    1. 制作一个静态库,但是由于这个静态库中很多地方用到了一个网络请求地址(或者其他的通用数据),但是呢?这个地址的设置又要暴露给用户
  2. 常见错误
    1. 提供一个头文件,在头文件中使用预处理命令define(假设宏名为SERVICEIP),然后将这个头文件暴露给用户
    2. 静态库中所有用到这个地址的地方都用宏代替(SERVICEIP)
  3. 错误分析:
    1. 静态库需要编译后打出,而宏SERVICEIP是在编译器通过预处理,将静态库中的所有SERVICEIP替换成实际的地址
    2. 那么静态库中所有SERVICEIP的地方都已经被替换成了常量
    3. 提供给用户静态库后,用户根据自己需求修改SERVICEIP宏的值,已经没有任何用处,应为静态库中的SERVICEIP全部已经被替换成最初的那个常量了。
  4. 解决办法:
    1. 采用外部变量的方法
    2. 创建一个.h文件声明外部变量
    3. 同时创建一个.m文件,定义外部变量SERVICEIP,然后初始化默认值
    4. 将这个.h文件暴露给用户
    5. 这样用户在外部任意修改SERVICEIP,都可以让静态库中的值修改掉
    6. 原因分析
      1. 静态库尽管会编译,但是编译的事一个外部SERVICEIP变量,仅仅是分配了变量的内存
      2. 当外部用户修改了SERVICEIP变量的值时,就相当于把内存中存储的数据修改
      3. 当程序运行时,到内存中取值时,当然是已经修改过的值。
    7. 示例代码:

       //.h文件
       #ifndef EtasFaceConst_h
       #define EtasFaceConst_h
       #import <UIKit/UIKit.h>
       //外部变量
       UIKIT_EXTERN NSString * SERVER_IP;
       #endif /* EtasFaceConst_h */
              
       //.m文件
       #import <UIKit/UIKit.h>
       //默认为生产环境
       NSString * SERVER_IP = @"https://*********************";
      

14.静态局部变量只会初始化一次

  1. 举例:

     -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
         [self test];
     }
        
     -(void)test{
         //初始化只会初始化一次
         static int a = 10;
         NSLog(@"=======%d",a);
         a = 20;
         NSLog(@"=======%d",a);
     }
    
  2. 连续点击2次,打印如下

     =======10
     =======20
     =======20
     =======20
    
    1. 从打印可以看出
      1. 调用2次test方法,但是static int a = 10;只执行了一次
      2. 即只初始化了一次
Table of Contents