美文网首页Ios开发iOS开发知识小集iOS开发
两年iOS经验之你忽略的小知识点

两年iOS经验之你忽略的小知识点

作者: SmallWhiteMouse | 来源:发表于2018-04-08 16:19 被阅读1349次

    2018-04-28更新:

    第12条关于tableView的执行调用顺序机制。

    2018-05-17更新:

    第二条-:imageWithImage:应该传一个图片对象而不是一个字符串。

    第三条:将类型UIEdgeInsets 改成属性contentOffset

    1.子视图超出frame的部分不显示  view.clipsToBounds 设置为YES;   UIScrollview的clipsToBounds默认就是YES

    2.UIImage 有一个属性叫size 。  当为对象Image赋值一张图片以后,Image会自动生成一个size。 那么也就是说你可以用image.size.x 来设置其父视图的size。即:

    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageWithName:@"text.png"]];  

    这样不用给定frame 系统也可以显示出带图片大小的ImageView。

    3.contentOffset 表示UIScrollView滚动的位置。(其实就是内容视图左上角与scrollView显示视图左上角的间距值)

    4. contentInset (UIEdgeInsets结构体类型 )这个属性能够在UIScrollView的四周增加额外的滚动区域,一般用来避免scrollView的内容被其他控件挡住。

    5.UIView渐变动画有三种:(UI控件属性被修改)

    [UIView animateWithDuration:0.1 animations:^{

         //需要动画的内容 

          self.imageView.frame = CGRectMake(20, 20, 30, 20);//e.g     

     }];

    [UIView beginAnimations:nil context:nil];   

    [UIView setAnimationDuration:2.0f];//修改动画持续时间

          //   需要做动画的内容

         self.imageView.frame = CGRectMake(20, 20, 30, 20);//e.g

    [UIView commitAnimations];


    [UIView transitionWithView:noteView duration:0.6 // 在noteView视图上设置过渡效果  options:UIViewAnimationOptionTransitionCurlUp  animations:^{ 

         NSString *currentText = noteView.text;

          noteView.text = nextText;

         self.nextText = currentText; 

    }  completion:^(BOOL finished){

    }];

    6.OC语法细节:不允许直接修改OC对象的结构体属性的成员

    修改结构体

    7.图片缩放不止可以用手势,也可以用ScrollView

    利用ScollerView缩放控件

    顺便提一句,viewForZoomingInScrollView不仅仅可以缩放图片,只要是继承自UIIView的控件都可以进行缩放

    8.NSArray  有一个方法让所有对象都执行某个方法

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

    后边的方法可以自定义,也可以用系统的。

    当然类似东西都用for - in  了,如果在循环中用的是系统的一些操作、方法。不妨试试上边这个方法。

    9.从Xib、Storybord加载控件执行方法顺序

    - initWithCoder:aCoder   作用是将xib的控件通过aCoder解析器创建所有子控件,通过IBOutlet 连接的属性在这个方法里边值是null。走了initWithCoder  就不会走initWithFrame。

    - awakeFormNib  是将冻结的nib控件唤醒,即所有子控件创建完毕后就会调用这个方法,在这个地方IBOutlet连接的属性才会真正的有值,所以修改nib控件的属性值应该在这个方法或者运行过程之后的方法。

    10.为什么 iOS 开发中,控件一般为 weak 而不是 strong?

    IBOutlet的属性一般可以设为weak是因为它已经被view引用了,除非view被释放,否则IBOutlet的属性也不会被释放,另外IBOutlet属性的生命周期和view应该是一致的,所以IBOutlet属性一般设为weak。

    通俗点讲:

    因为控件他爹( view.superview )已经揪着它的小辫了( strong reference ),你( viewController )眼瞅着( weak reference )就好了。当然,如果你想在 view 从 superview 里面 remove 掉之后还继续持有的话,还是要用 strong 的( 你也揪着它的小辫, 这样如果他爹松手了它也跑不了 )。

    11、用NSLayoutConstrain给控件做了约束以后,如何执行一定的UIView动画呢?

    // 高度约束,为了点击方法可以改变  

    @property (nonatomic, strong) NSLayoutConstraint    *heightConstraint;

    //在修改了约束以后,只要执行下边的代码,就能做动画效果   

    [UIView animateWithDuration:2.0 animations:^{

            [添加了约束的View    layoutIfNeeded];   

    }];

    12、关于TableView的[- tableView: heightForRowAtIndexPath:]和[ -tableView: cellForRowAtIndexPath:  ]历史版本调用顺序的变迁

    iOS  7及之前: 

     先依次调一遍heightForRow方法再依次调一遍cellForRow方法,在调cellForRow方法的时候并不会再调一次对应的heightForRow方法。如果我们实现了:【-tableView: estimatedHeightForRowAtIndexPath:】给了系统估计高度,那么上述两个方法的执行顺序就会颠倒。并且给定估计高度对于TableView的性能方面也提示不少。

    iOS8  :

    先依次调heightForRow(如果行数超过屏幕依次调用两次,如果行数很少,没有超过屏幕,只依次调用一次),之后每调一次cellForRow的时候又调一次对应的heightForRow方法。

    iOS9和iOS10:

    heightForRow方法会先调用三次,然后每调用一次cellForRow的时候再调用一次对应的heightForRow。

    iOS 11 :

     先row = 0调用一次 cellForRow,然后一次heightForRow.然后再是row =1 ,依次类推。看打印结果

    iOS11图片

    PS:本次更新感谢小C酱油醋 的留言。并且关于历史版本验证截图请查看博客关于heightForRow和cellForRow方法的调用次数和顺序的系统差异性

    13、LayoutIfNeeded小理解

    这个方法和另一个方法配对的,setNeedLayout和layoutIfNeed,还有一个关联的方法是layoutSubviews,在我们没有任何干预的情况下,一个view的fram或bounds发生变化时,系统会设置一个flag给这个view,当下一个渲染时机到来时系统会重新按新的布局来渲染视图。setNeedLayout就是我们主动为这个视图设置一个flag,告诉系统这个视图再下一个时机到来时要重新渲染,而layoutIfNeed则是告诉系统,如果设置了flag那么不用等待时机到来了,直接渲染吧。而layoutSubviews这个方法是系统调用的,我们不需要主动调用,我们只需要调用layoutIfNeed就可以了,让系统判断是否在当前时机下立即渲染。

    另同时附上一个场景举个例,当想知道tableView reloadData后的contentSize的话可以在reloadData后用这两个方法,然后就可以直接提取contentSize了。

    14、UILabel.preferredMaxLayoutWidth属性

     - 设置label每一行文字的最大宽度

    这个属性建立在autoLayout布局的label中,如果是非零,那么这个属性用于多行Label的文字固定宽度

    15、iOS NSLog去掉时间戳及其他输出样式

    加宏定义

    #ifdef DEBUG

    #define NSLog(FORMAT, ...) fprintf(stderr,"%s\n",[[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);

    #else

    #define NSLog(...)

    #endif

    16、UITableView点击一下就出现灰色但是立马消失掉。

    点击那一刻可以指示出点击了哪一行,灰色停留一秒钟消失掉。

    //1.设置cell点击时候为灰色

    cell.selectionStyle = UITableViewCellSelectionStyleGray;  

    //2.在tableView代理方法didSelectedRow方法这样写

    - (void)tableView:(UITableView *)tableView didSelecteRowAtIndexPath:(NSIndexPath *)indexPath{

          [ tableView deselectRowAtIndexPath:indexPath animated:YES];//直接取消选中这一行

    }


    获取笔者更多记录小知识点,请点击三年经验之你忽略的小知识点

    如果您有什么疑问或者书写歧义,非常感激您能留言~

    相关文章

      网友评论

      • 龙伟17:很基础
      • 随行的羊:希望关注 “iOS开发知识小集” 的专题哈,谢谢:smile:
        随行的羊:@SmallWhiteMouse :smile: 没事儿,加油,共勉。
        SmallWhiteMouse:@随行的羊 已经关注了,最近有点私事。很少上网。群里讨论没及时跟上还望见谅啊
      • ZJS_Sky:谢谢对我的帮助很多
      • calm1993:[[UIImageView alloc]initWithImage:@"text.png"]; 后面不是应该传image 吗 怎么传的字符串,不要骗我 scrollview增加额外滚动内容的不是应该是contentInset吗 UIEdgeInsets只是一个结构体啊
        SmallWhiteMouse:首先很感谢你认真读我写下的文字,其次这两个问题在书写过程中过于匆忙导致出现的错误,希望不要对其他初学者造成误导,两处地方已修改更正,非常感谢你的指出~
        以后还请多多指教
      • yuebiubiu:写的都很基础,也很实用,mark了
      • 你见过彩虹吗:第12个,为什么我的cellForRowAtIndexPath会在heightForRowAtIndexPath之前,我并没有实现这个estimatedHeightForRowAtIndexPath方法
        SmallWhiteMouse:@小C酱油醋 苹果的框架说白了也是程序员写的, tableView的调用顺序,苹果公司在版本升级过程中优化代码修改了调用的机制。从iOS 6到现在的iOS 11.4经历了几番变化。详细了解你可以看这篇博客https://www.jianshu.com/p/c67dfa3ecd11。
        非常感谢你的留言指点,关于第12个,我会尽快更新书写。希望可以多多保持联系,码农之路我们一起前行。
        祝生活愉快~
        你见过彩虹吗:@SmallWhiteMouse 呃,可以在那两个方法里面各写一个nslog看下,哪个先输出
        SmallWhiteMouse:有代码看一下吗?我们可以交流一下
      • 谢谢生活:描述的简单易懂,666666
        谢谢生活:@SmallWhiteMouse 我能说因为爱情吗?
        SmallWhiteMouse:说出你关注又取消关注的心路历程
      • 花落花瓣哭:大神666啊,终于找到答案了。
      • db99fcd3f429:解决了我多年的疑惑 大神666
      • 1e43b934e1a6:大神牛逼!!!
        SmallWhiteMouse:共勉,共勉。 你也牛逼

      本文标题:两年iOS经验之你忽略的小知识点

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