uikit——UIView——view hierarchy

来源:互联网 发布:晚上醒了就睡不着 知乎 编辑:程序博客网 时间:2024/06/06 04:03

view hierarchy

@property(nullable, nonatomic,readonly) UIView       *superview;@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;@property(nullable, nonatomic,readonly) UIWindow     *window;- (void)removeFromSuperview;- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;- (void)addSubview:(UIView *)view;- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;- (void)bringSubviewToFront:(UIView *)view;- (void)sendSubviewToBack:(UIView *)view;- (BOOL)isDescendantOfView:(UIView *)view;  // returns YES for self.
解释:
  • view hierarchy本质是tree
  • superview:view parent
  • subviews:view children,添加subview会进行判断,nil不会添加,同一subview不会重复添加
  • window:view所在view hierarchy(tree) root,即view controller.view.superview

view hierarchy图层

  • superview位于下层,subviews位于上层
  • 同一subviews,索引小的位于下层,索引大的位于上层,索引也称为view z-index或z-order
- (void)drawView{    int width = self.view.bounds.size.width;    int halfHeight = self.view.bounds.size.height / 2;        {        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, halfHeight)];        UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(40, 30, 200, 200)];        UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(80, 60, 200, 200)];        UIView *view1_1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 80, 80)];        UIView *view1_2 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 80, 80)];                view.backgroundColor = [UIColor purpleColor];        view1.backgroundColor = [UIColor blueColor];        view2.backgroundColor = [UIColor orangeColor];        view1_1.backgroundColor = [UIColor redColor];        view1_2.backgroundColor = [UIColor cyanColor];                [self.view addSubview:view];        [view addSubview:view1];        [view addSubview:view2];        [view1 addSubview:view1_1];        [view1 addSubview:view1_2];    }        {        UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, halfHeight, width, halfHeight)];        UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(40, 30, 200, 200)];        UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(80, 60, 200, 200)];        UIView *view1_1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 80, 80)];        UIView *view1_2 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 80, 80)];                view.backgroundColor = [UIColor brownColor];        view1.backgroundColor = [UIColor blueColor];        view2.backgroundColor = [UIColor orangeColor];        view1_1.backgroundColor = [UIColor redColor];        view1_2.backgroundColor = [UIColor cyanColor];                [self.view addSubview:view];        [view addSubview:view2];        [view addSubview:view1];        [view1 addSubview:view1_1];        [view1 addSubview:view1_2];    }}

view hierarchy遍历

view hierarchy指以receiver为root view hierarchy,view hierarchy先根遍历
通常情况下,遍历子树按从左到右顺利遍历(subview index从小到大),用代码表示:
- (void)traverse{    [self visit];        for(int i = 0; i < self.subviews.count; ++i)    {        UIView *view = [self.subviews objectAtIndex:i];        [view traverse];    }}
特殊情况下,为了性能优化,遍历子树按从右到左顺利遍历(subview index从大到小),用代码表示:
- (void)traverse{    [self visit];        for(int i = self.subviews.count - 1; i >= 0; --i)    {        UIView *view = [self.subviews objectAtIndex:i];        [view traverse];    }}
view的draw(layout)为了性能优化,遍历子树按从右到左顺利遍历(subview index从大到小),先draw(layout)上层图层,然后draw(layout)下层图层,如果下层图层区域被上层图层不透明覆盖,则不必draw(layout)这些区域,极大提高了draw(layout)性能

view hierarchy crash

view hierarchy本质为tree,因此切不可形成闭环(循环),一旦形成闭环(循环),就破坏tree结构,先根遍历无穷递归,crash
- (void)circleCrash{    UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 200, 200)];    UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)];    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];        [self.view addSubview:view1];    [self.view addSubview:view2];    [view1 addSubview:subView];    [subView addSubview:self.view];}
self.view->view1->subview->self.view形成闭环(循环)
0 0
原创粉丝点击