1 生命周期
- UIView没有designated初始化方法。
- 初始化
updateConstraints
和layoutSubviews
的关系有点像,收集-实施的关系。(准备数据、使用数据)
触发layoutSubviews的方式:
- setFrame,且frame不是CGRectZero,(且前后变化)
- addSubview:,removeSubview:
- 滚动UIScrollView
- 屏幕旋转
- setNeedsLayout,setNeedUpdateConstraints(且前后变化)
- 改变frame,只触发自己的layoutSubviews,不会影响到父视图、兄弟视图
2 代码组织
-
initialize中 坐标计算,使用static变量只计算一次
-
initWithFrame:中
组装subview
-
setModel中
配置数据源,needLayout
-
layoutSubviews中
处理布局
注意有些第三方库的view,可能没有实现layoutSubviews,而是重写了setFrame:,如果我们的View以他们为subview了, 要注意:
3 注意事项
3.1 绘制顺序
深度优先: 父视图,有兄弟视图的情况下,先绘制父视图,然后绘制父视图的子视图,最后绘制兄弟视图。
4 常用API
4.1 获取controller
//比superview准确,用superview的话,要判断navigationController和tabbarController
- (UIViewController *)viewController {
UIResponder *responder = self;
while (![responder isKindOfClass:[UIViewController class]]) {
responder = [responder nextResponder];
if (nil == responder) {
break;
}
}
return (UIViewController *)responder;
}
复制代码
4.2 一些属性
4.2.1 透明度相关
//1. alpha,hidden。较少用,opaque。
//2. opacity,layer的属性,相当于view.alpha,但设置为0,也不影响事件响应。
复制代码
以上都会影响子视图(或子layer),如果希望父视图透明,子视图不透明。
//只对颜色有效,对图片无效
superView.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
复制代码
4.2.2 切边相关
//效果上没区别
view.clipsToBounds = YES;
layer.masksToBounds = YES;
复制代码
4.2.3 其他
//1. sizeToFit,在autoLayout中无效了,要强行生效,可以写在viewDidLayoutSubviews中
//2. tintColor,默认背景色,会被子类继承
//3. multipleTouchEnabled,是否开启多点触摸,默认NO
//4. exclusiveTouch,事件独占,默认NO
表示事件独占,如果UIView是事件的firstResponder,那么第一个手指离开前,其他视图不会响应任何触摸事件。(仅Touch事件,不包括手势)
iOS 解决页面按钮同时点击,同时触发问题 设置所有UIButton的ExclusiveTouch属性为YES
-(void)setExclusiveTouchForButtons:(UIView *)myView {
for (UIView * v in [myView subviews]) {
if([v isKindOfClass:[UIButton class]])
[((UIButton *)v) setExclusiveTouch:YES];
else if ([v isKindOfClass:[UIView class]]){
[self setExclusiveTouchForButtons:v];
}
}
}
//5. 根据tag拿view
viewWithTag:
//6. 是否为子视图
isDescendantOfView:
//7.层级、响应相关
insertSubview:belowSubview:
insertSubview:aboveSubview:
becomeFirstResponder
resignFirstResponder
bringSubviewToFront:
sendSubviewToBack:
//8. sizeToFit,会被autoLayout覆盖(除非在viewDidLayoutSubviews中调用,不推荐),不需要太在意这个属性
sizeToFit //不要重写,可能会改变原始frame
siztThatFits //重写这个,为sizeToFit提供数据,"照这个数据fit"
//9. 刷新相关
setNeedsUpdateConstraints
updateConstraintsIfNeeded
setNeedsLayout
layoutIfNeeded
setNeedsDisplay
复制代码
5 其他
5.1 frame和bounds
- 修改view's bounds.size,center不会变。origin会变。
- 修改bounds.origin,这个view不会变,变的是他的subviews。因为相当于改了子视图frame所处的坐标系。UIScrollView用到了。