Men的博客

欢迎光临!

0%

UI相关

UIView绘制原理

当UIView调用setNeedDisplay之后,系统会调用view对应layer的 
setNeedsDisplay方法,相当于在当前layer上打上了一个脏标记,然后会在
当前runloop即将结束的时候调用CALayer的display方法,才会真正的进入
当前视图的绘制流程当中,所以视图的绘制时机,是在当前runloop即将结束的
时候才会开始.
CALayer的display方法的内部实现,首先会判断layer的delegete是否响
应display方法,如果代理不响应就会进入到系统的绘制流程当中,如果响应,实
际上就为我们提供了异步绘制的接口,这样就构成了UIView的绘制原理
进行异步绘制,其实就是基于系统给我们开的口子layer.delegate,如果遵从
或者实现了displayLayer方法,我们就可以进入到异步绘制流程当中,在异步
绘制的过程当中
1.就由delegete去负责生成bitmap位图
2.设置改bitmap作为layer.content属性的值

Masonry

https://www.cnblogs.com/ludashi/archive/2016/07/11/5591572.html
是一个对系统NSLayoutConstraint进行封装的第三方自动布局框架,采用链
式编程的方式提供给开发者API
UIView的对象可以直接调用mas_makeConstraints方法来为相应的View对
象添加约束。因为mas_makeConstraints方法位于UIView的
View+MASAdditions类目中,所以UIView的对象可以直接调用。同样在
View+MASAdditions类目还有其他方法供UIView的对象使用
MASViewAttribute这个类名中我们就能看出,这个类是对UIView和
NSLayoutAttribute的封装。使用等式来表示就是MASViewAttribute = 
UIView + NSLayoutAttribute + item。在MASViewAttribute类中
的view属性表示所约束的对象,而item就是该对象上可以被约束的部分。
MASViewConstraint做的最核心的一件事情就是初始化
NSLayoutConstriant对象,并将该对象添加在相应的视图上
MASConstraintMaker类。该类就是一个工厂类,负责创建MASConstraint
类型的对象(依赖于MASConstraint接口,而不依赖于具体实现)

圆角性能问题

OpenGL中,GPU屏幕渲染有以下两种方式:
On-Screen Rendering
意为当前屏幕渲染,指的是GPU的渲染操作是在当前用于显示的屏幕缓冲区中进行。
Off-Screen Rendering
意为离屏渲染,指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
相比于当前屏幕渲染,离屏渲染的代价是很高的,主要体现在两个方面:
创建新缓冲区
要想进行离屏渲染,首先要创建一个新的缓冲区。
上下文切换
离屏渲染触发方式
设置了以下属性时,都会触发离屏绘制:
shouldRasterize(光栅化)
masks(遮罩)
shadows(阴影)
edge antialiasing(抗锯齿)
group opacity(不透明)
实现圆角cornerRadius要比mask高效很多。
方案:
直接使用setCornerRadius
这种就是最常用的,也是最耗性能的。
setCornerRadius设置圆角之后,shouldRasterize=YES光栅化
avatarImageView.clipsToBounds = YES;
[avatarImageView.layer setCornerRadius:50];
avatarImageView.layer.shouldRasterize = YES;
avatarImageViewUrl.layer.rasterizationScale=[UIScreen mainScreen].scale;
直接覆盖一张中间为圆形透明的图片(推荐使用)
这种方法就是多加了一张透明的图片,GPU计算多层的混合渲染blending也是会消耗一点性能的,但比第一种方法还是好上很多的。
Core Graphics绘制圆角
这种方式GPU损耗最低,但是UIButton上不知道怎么绘制,可以用UIimageView添加个点击手势当做UIButton使用。
可以用Instruments的 GPU Driver进行测试:

Target-Action 设计模式

Target-Action,意为 目标-行为,行为即要调用的方法,目标即消息的接收
对象(Objective-C 语言使用消息机制,类似但不同于方法调用,该两种概
念可能未来会进行探讨)。整个过程为:用户点击按钮,触发某事件发生,该消
息由按钮传到另外的接收对象,接收对象再做相应处理。接收对象可以为任何对
象,但通常为控制器
[self.btnCooking addTarget:self    
action:@selector(pressCooking:) 
forControlEvents:UIControlEventTouchUpInside];
1、self 指目标对象为当前对象,及WViewController; 
2、action 即 在目标对象上的点击方法; 
3、何时调用该方法,UIControlEventTouchUpInside即单击时。 

layer与view的区别

UIView相比CALayer最大区别是UIView可以响应用户事件,
而CALayer不可以。UIView侧重于对显示内容的管理,CALayer侧重于对内
容的绘制。
UIView的继承结构为: UIResponder : NSObject。 
UIResponder是用来响应事件的,也就是UIView可以响应用户事件。
CALayer的继承结构为: NSObject。 
直接从 NSObject继承,因为缺少了UIResponder类,所以CALayer悲催的
不能响应任何用户事件。 
CALayer定义了position、size、transform、animations 等基本属
性。
View和CALayer的Frame映射及View如何创建CALayer.
一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 
transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer
的 frame,同样 View 的 center和 bounds 也是返回 Layer 的一些属
性。

viewController push生命周期

------------------------PUSH---------------------------
A-willDisappear --> B-willAppear --> A-didDisappear --> B-didAppear
---------------------NormalPresent---------------------
A-willDisappear --> B-willAppear --> B-didAppear --> A-didDisappear
-----------------------TabBar切换------------------------
B-willAppear --> A-willDisappear --> A-didDisappear --> B-didAppear

轮播图实现原理

第一种:基于collectionView进行的封装(推荐)
这种方式应该是实现起来最简单的一种方式了,也是个人最喜欢的一种封装方
式。它的原理就是几个collectionView,至于无限轮播,很简单,只需要你
的轮播数组给collectionView赋值的时候乘以一个较大的数字即可(例如
100),collectionView本身处理了重用等一系列问题。
第二种:基于scrollView的无限轮播(首尾各多创建一个展示图片的
ImageView)
这种实现方式个人感觉是最麻烦,而且还需要考虑重用等性能问题的一种。基本
的原理就是在根据你轮播数组的个数在首尾各多创建一个ImageView,当然首
位之前多创建一个展示轮播数组最后一个的ImageView,而尾部多创建一个展
示轮播数组第一个的ImageView。
第三种:同样是基于scrollView的无限轮播(总共就创建三个ImageView)
这种实现方式比第二种的好处就是不需要考虑重用问题,不论数组是多少个轮播
图,我只创建三个ImageView。它与第二种的不同之处是其实用户每次看到的
一直都是中间那张的ImageView,只是上边的内容改变了。其内部实现其实是在
不断的改变那个轮播数组。    

xib的约束,拖出线后系统默认为什么是weak

IBOutlet的属性一般可以设为weak是因为它已经被view引用了,除非view
被释放,否则IBOutlet的属性也不会被释放,另外IBOutlet属性的生命周期
和view应该是一致的,所以IBOutlet属性一般设为weak。
从storyboard或者xib上创建控件,在控件放在view上的时候,已经形成了
如下的引用关系,以UIButton为例:
UIViewController->UIView->subView->UIButton
然后你为这个UIButton声明一个weak属性
@property(nonatomic,weak) IBOOutlet UIButton *btn;
相当于xib/sb对这个Button是强引用,你声明的属性对它是弱引用。

label只设置上和左的约束正常,UIview这样设置为什么会有约束警告

大概意思是并不是所有的View都有Intrinsic Content Size,而拥有
Intrinsic Content Size的view有这样的特征:它们可以根据view中的
内容来确定view的size。例如Button,我们可以不用指定它们已经计算好的
size,只需要指定position即可。在Masonry中,UIButton的布局我们可
以这样子写:
Content Compression Resistance即为抗压缩阻力,而Content 
Hugging即为抗拉伸阻力
View    Intrinsic content size
UIView and NSView    No intrinsic content size.
Sliders    Defines only the width (iOS).
Labels, buttons, switches, and text fields    Defines both the height and the width.
Text views and image views    Intrinsic content size can vary.

position与anchorPoint

每一个UIView内部都默认关联着一个CALayer, UIView有frame、bounds
和center三个属性,CALayer也有类似的属性,分别为frame、bounds、
position、anchorPoint。frame和bounds比较好理解,bounds可以视为
x坐标和y坐标都为0的frame,那position、anchorPoint是什么呢?先看
看两者的原型,可知都是CGPoint点。
position是layer中的anchorPoint点在superLayer中的位置坐标。因此
可以说, position点是相对suerLayer的,anchorPoint点是相对layer
的,两者是相对不同的坐标空间的一个重合点。
总结
1、position是layer中的anchorPoint在superLayer中的位置坐标。 
2、互不影响原则:单独修改position与anchorPoint中任何一个属性都不
影响另一个属性。
anchorPoint 是相对于自身的位置,而 position 是相对于父图层的,改
变 anchorPoint 只是更改了图层自身旋转地位置,但始终还是要通过改变 
frame 使 anchorPoint 和 position 重合

显示动画和隐式动画区别

显式动画是指用户自己通过beginAnimations:context:和
commitAnimations创建的动画。    
隐式动画是指通过UIView的animateWithDuration:animations:方法创
建的动画。
区别就是使用隐式动画后,View会暂时不能接收用户的触摸、滑动等手势。这
就造成了当一个列表滚动时,如果对其中的view使用了隐式动画,就会感觉滚
动无法主动停止下来,必须等动画结束了才能停止。