我们开发很多时候都会遇到需要设置不同view的层次关系,而Mac开发和iOS开发稍微有点不同,NSView是没有sendSubviewToback和bringSubViewToFront这两个设置层级关系的方法的。那Mac上的NSView是如何设置层级关系的呢?下面介绍两种方法:一是Storyboard,二是纯代码。
一、Storyboard
Storyboard加载view有个特点,是根据你添加view的先后顺序来加载view的,也就是说越在后面添加的view显示的时候越在前面,写个例子测试一下:
新建一个工程,storyboard拖入三个Custom View,如图所示:
可以看出viewThree是最先添加的,排在最底下,viewOne是最后添加的,排在最前面,ViewController添加如下代码:
//
// ViewController.m
// NSViewHierarchicalRelationships
//
// Created by SC Chen on 28/12/2017.
// Copyright © 2017 sc. All rights reserved.
//
#import "ViewController.h"
@interface ViewController()
@property (strong) IBOutlet NSView *viewOne;
@property (strong) IBOutlet NSView *viewTwo;
@property (strong) IBOutlet NSView *viewThree;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[_viewThree setWantsLayer:YES];
[_viewThree.layer setBackgroundColor:[NSColor yellowColor].CGColor];
[_viewOne setWantsLayer:YES];
[_viewOne.layer setBackgroundColor:[NSColor redColor].CGColor];
[_viewTwo setWantsLayer:YES];
[_viewTwo.layer setBackgroundColor:[NSColor blueColor].CGColor];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
@end
运行结果如图:
跟预先看到的结果一样,viewThree排在最底下,viewTwo排在中间,viewOne排在最前面,这样的话我们可以调整storyboard中三个view的位置,实现view之间的层级关系。比如我们将storyboard中三个view的顺序调整为:
viewOne在最底下,viewThree在中间,viewTwo在最前面。运行一下,结果如图:
结论:我们可以调整storyboard中view的顺序实现view层级关系显示,越在下面的view显示的时候越在前面。
二、纯代码
用storyboard调整view的层级关系毕竟有很多限制,通过代码调整view的层级关系才是最佳选择,因为代码可以的动态改变view的层级关系。前面也说了,NSView没有sendSubviewToback和bringSubViewToFront这两个设置层级关系的方法,但是NSView有addSubview:positioned:relativeTo:这个方法,这个方法功能与sendSubviewToback和bringSubViewToFront这两个方法类似,可以设置两个view之间的层级关系,positioned这个参数可以设置NSWindowBelow(在下面)、NSWindowAbove(在上面)和NSWindowOut(在外面), relativeTo这个参数可以设置与哪个view的层级关系。代码:
//
// ViewController.m
// NSViewHierarchicalRelationships
//
// Created by SC Chen on 28/12/2017.
// Copyright © 2017 sc. All rights reserved.
//
#import "ViewController.h"
@interface ViewController()
//@property (strong) IBOutlet NSView *viewOne;
//@property (strong) IBOutlet NSView *viewTwo;
//@property (strong) IBOutlet NSView *viewThree;
@property (nonatomic, strong) NSView *viewOne;
@property (nonatomic, strong) NSView *viewTwo;
@property (nonatomic, strong) NSView *viewThree;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// storyboard设置view层级关系
// [_viewThree setWantsLayer:YES];
// [_viewThree.layer setBackgroundColor:[NSColor yellowColor].CGColor];
//
//
// [_viewOne setWantsLayer:YES];
// [_viewOne.layer setBackgroundColor:[NSColor redColor].CGColor];
//
// [_viewTwo setWantsLayer:YES];
// [_viewTwo.layer setBackgroundColor:[NSColor blueColor].CGColor];
// 纯代码设置view的层级关系
// 设置viewOne在最底下,viewThree在中间,viewTwo在最前面
_viewOne = [[NSView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[_viewOne setWantsLayer:YES];
[_viewOne.layer setBackgroundColor:[[NSColor redColor] CGColor]];
[self.view addSubview:_viewOne];
_viewTwo = [[NSView alloc] initWithFrame:CGRectMake(150, 100, 100, 100)];
[_viewTwo setWantsLayer:YES];
[_viewTwo.layer setBackgroundColor:[[NSColor blueColor] CGColor]];
[self.view addSubview:_viewTwo positioned:NSWindowAbove relativeTo:_viewOne];
_viewThree = [[NSView alloc] initWithFrame:CGRectMake(125, 60, 100, 100)];
[_viewThree setWantsLayer:YES];
[_viewThree.layer setBackgroundColor:[[NSColor yellowColor] CGColor]];
[self.view addSubview:_viewThree positioned:NSWindowBelow relativeTo:_viewTwo];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
// Update the view, if already loaded.
}
@end
运行结果:
viewOne在最底下,viewThree在中间,viewTwo在最前面。