xib的有的觉醒,一天一点xib

引言

下边大家来上学比xib更有力的SB

引言

那二日突然想起此前看到过局地种类中用到了object,
好奇心起,就顺手回溯下xib的施用呢

哪些了然SB?

最简便的通晓就是:一个.storyboard文件约等于七个根据VC使用的.xib文件,因而大家得以见到,SB(唯其如此依据VC,不只怕依照View),我们有五个VC的类是足以和贰个SB文件建立关联的,使用方法:

SecVC *secVC = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecVC"];

之前的一天一点xib:2初识xib有过介绍,
通过这些法子,大家传入差异VC的identifier,就会得到分化的VC对象。

xib优缺点分析

1.有必然的学费

2.尚无代码表明清晰

3.弄错不易察觉,无法调试,尤其是“连线”出了难点

4.文本易抵触,且难消除,不便利团队合营,尤其是在协会中用SB

5.履行功用没有代码高

6.奇迹不便宜封装

7.灵活性不强,尤其界面灵活多变, 中度不定

8.行使富文本卡顿现象分明

缘何是强大了?

xib可以按照View、VC甚至自身单身的使用,而SB只好依据VC使用,为何说比xib更抓实劲呢?重要是上边的七个原因:

1.SB支持segue

2.SB对cell的支撑更做实硬

优点

1.费用作用高

2.削减大气胶水代码

3.透过xib可以高速、高效的上学控件

4.适配性明显优化代码(auto layout、size classes)

5.可视化

6.在肯定程度上修修改改方便

什么是segue?

想象我们点击3个VC中的button后跳转到另贰个VC的场景,平日用的都是navigationController的push,或然present1个模态视图,即便有xib的情状下,要形成跳转其实也不容易,要把按钮拖到@implementation中落到实处1个IBAction的章程,然后在其间写上:

[self.navigationController pushViewController:Sec animated:YES]

或者

[self presentViewController:Sec animated:YES completion:nil]

要想简化那一个没有技术含量的进度,就要用到SB的segue。

我们在二个VC中选取要暴发跳转的按钮,按control拖动到另3个VC上就会现出1个菜系,在菜单上你就可以挑选跳转的格局push、present,那样不用写一行代码就能成功页面间的跳转,而八个VC之间的像纽扣一样用线连着多个VC的的事物就是segue,是一个UIStoryboardSegue对象,大家得以省略的精通成是旗开马到页面跳转有关职能的一个类,是还是不是很简短?

VC View 使用xib

segue固然简易,怎么着传参?

作者们领略用SB的segue来完成也页面跳转十分便民,不过假使要向跳转的页面传参该怎么做?

万一大家要点击ViewController这些VC里的一个按钮,跳转到SecVC这些VC中,把testTitle这一个参数传过去。第2步依然要选中按钮,拖到SecVC里,然后选中那么些segue,给它2个id值,确保用代码可以找到它,然后在ViewController中编码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"sec"]) {
        SecVC *secVC = (SecVC *)segue.destinationViewController;
        secVC.testTite = @"hello world";
    }
}

设置SB中segue的identifier,紧要就是要在此间运用,因为七个button暴发的两个页面跳转都以回调这一个函数,所以要用identifier来区分是哪位segue,跳哪个页面,传哪些参数。
id的sender就是触发跳转的不得了button或任何控件。

1 创制方法

VC在成立的时候可以之间勾选创造 xib

图片 1

image

View不能直接勾选创造,须要command+N接纳View创设二个xib,一般的话,我们需求创制二个相对应的类,
在左侧栏第多少个挑选(show the identity inspector)上面的custom class->
class中填入您要与该xib绑定的UIView子类的名字

不显然的跳转怎么着行使segue?

转眼风貌日常出现:甲VC中有个button,点击后有只怕跳转到乙页面,也可能跳转的丙页面,怎么解?

我们即使大家要点击ViewController这几个VC里的1个按钮,有只怕要跳到SecVC,有只怕要跳thirdVC。
1.在SB中准备segue。

注意大家这一次创设的segue的法门并不是选中button按control拖到另贰个VC中,而是选中VC,右键选中triggered
segues里manual前面的+拖动到另3个VC里,那些很重大,而且照旧要给segue壹个id。

2.编码完结跳转:

- (IBAction)testSegue:(id)sender
{
    BOOL flag = NO;
    if (flag) {
        [self performSegueWithIdentifier:@"sec" sender:sender];
    } else {
        [self performSegueWithIdentifier:@"third" sender:sender];
    }
}

代码达成segue跳转也很简单:

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender

首先个参数是segue的id,首个参数是接触那几个跳转的控件。
在segue跳转页面的进度中还会调1个函数,我们可以重写那么些函数,来控制是不是让那么些跳转载生。eg:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
    if (_islogin) {
        return YES;
    } else {
        NSLog(@"您还没有登录,请先登录"); //用log举个例子
        return NO;
    }
}

2 早先化方法

VC加载xib的方法
小编们的父类在初叶化的时候去自动帮大家找与之对应的xib文件,那么难题来了,父类怎么领会小编有没有xib文件呢?是那般,父类会判断有没有和大家那一个要开始化的VC相同名字的xib文件,若是有就会加载该xib文件,假如没有,父类就觉得大家该VC没有xib文件,就会走正规的init方法。

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

假若假定大家的VC类的名字与相应的xib文件名字分裂的时候,大家就必须调用这一个先导化方法来创建VC实例了;

[[ViewController alloc] initWithNibName:@"xxx" bundle:[NSBundle mainBundle]]

xxx填写xib文件的名字, 名字不相同也是足以的

更灵敏的segue

一经您熟识精通了segue他骨子里可以做过多事务,其实segue并不仅能成功跳转,还有一类segue叫做relationship
segue,以前是支持大家了然,所以说的相比较简单,其实大家选中1个NavigationController按control键拖动到另三个VC上的话也得以生成segue,大家选中root
view
controller,就将Nav的rootViewController属性设置成了那个VC,那一个segue就是relationship
segue,同样,拖动二个tabbarController也会并发viewControllers的relationship
segue。

2 view加载xib

TestView *tView = [[NSBundle mainBundle] loadNibNamed:@"TestView" owner:self options:nil].firstObject;

上述代码再一次证实xib文件是能源文件,放在main
bundle中,@”TestView”是xib文件的称呼,后边五个参数权且不要精通,就固定传self和nil就行,值得说的是,loadNibNamed:
owner:
options方法再次来到的是1个数组,而不直接是目标,那是考虑到了Mac开发会有多个目的回来的事态,在iOS开发中就唯有3个,固定取第三个就好。

注:一般的UIView对象,代码开端化的时候都会调用initWithFrame:方法,不过用xib创造的UIView对象是不会调用此方式的,因为该对象的Frame在xib文件中就足以分明了。以xib的款型保留控件对象的进程实际上叫做固化(archive),通过xib文件创设控件的进程叫做解固(unarchive),固化是iOS持久化的一种相比较好的缓解方案,未来有机遇会说说iOS持久化的各类法子的上下,那里不再长远,而与稳定有关的起初化函数是:

- (instancetype)initWithCoder:(NSCoder *)aDecoder

之所以,当以xib创建UIView对象的时候这几个函数会调用,从前在initWithFrame:中要做的作业,可以放在initWithCoder:中,或然放在:

- (void)awakeFromNib
{
    [super awakeFromNib];
    //...
}

更好的应用Cell

用xib的时候,要想用cell,日常是树立3个cell子类,1个与之对应的.xib文件。用SB的时候要想用cell就归纳的多了,因为cell是足以一向拖动到tableView里的,直接在tableView里管理cell设置属性,当然假使是繁体的cell依然要子类话对应的.h、.m的。

SB在使用cell分两种情景:1静态cell,2动态cell。

SB文件的利用

鉴于SB文件与VC一般是一对多的关系,所以大家不仅要精通将要创造的那一个VC的实例对象是加载的哪位SB,而且还要领会加载的是该SB中的哪个具体的VC

SecVC *secVC = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"SecVC"];

局地项目有七个sb举行跳转, 一般的话要求找到万分sb的起来入口十二分VC

SecVC *secVC = [[UIStoryboard storyboardWithName:@"Demo" bundle:[NSBundle mainBundle]] instantiateInitialViewController];

静态cell

安装静态cell:

留神静态cell一定要基于UITableViewController,否则会报错。
体现静态cell的tableView是决不调用自身必须完毕的datasource协议的

您会很奇异,为啥必须调用的datasource协议都毫无落成?答案是静态,静态的cell,意义就在于你在xib中设置成什么样,他就显现怎么着,不会再调用datasource向你要cell了,因为在SB文件中早已分明下来了。

在做一些“死”页面的时候SB的静态cell是很好的接纳,静态cell也不是什么都不能做,静态cell里的button依旧得以拖到@implementation中形成IBAction的,可是是力不从心生成IBOutlet属性或字段的。

固然你强行的给三个静态的cell钦命了三个cell的类,也是无力回天向其中间拖入IBOutlet的。那就是静态cell的局限性,可是假诺你要安装的数据不多照旧得以考虑用静态cell,因为你能够通过给cell上的控件设tag来找到它之所以赋值。

争辩消除

xib、SB文件有三种查看格局,当文件冲突的时候一般的interface
builder格局打开文件会破产。

那时右键该xib或SB文件,采用source
code格局打开文件,之后消除争辨的笔触与消除project.pbxproj文件争辩的法子是千篇一律的,文件中全局搜索<<<<或>>>>定位到错误地方,依据实际情状,删除一个本子的代码,保留另1个版本的代码,直到文件中具有争辩都消除掉。

动态cell的使用

在上图中安装content属性为Dynamic
Prototypes就足以了。使用动态cell的话就要在VC中贯彻那七个必须贯彻的datasource协议了,下边举个简单的事例:
1.给cell钦点一个class

2.给cell设置id,重用机制使用,别的品质就不详细表达了,和此外控件的属性大约。

3.给cell添加一些控件,并拖到TestCell源文件中生成IBOutlet的属性,在VC中贯彻那多少个必须贯彻的情商章程:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TestCell *testCell = (TestCell *)[tableView dequeueReusableCellWithIdentifier:@"testCell"];
    testCell.testLabel.text = @"hello world";
    return testCell;
}

此间注意,不须要在tableView:cellForRowAtIndexPath:中创立cell了,那是与xib使用cell最大的区分,上边是xib使用cell的主意举例:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TestCell *testCell = (TestCell *)[tableView dequeueReusableCellWithIdentifier:@"testCell"];
    if (!testCell) {
        testCell = [[NSBundle mainBundle] loadNibNamed:@"TestCell" owner:self options:nil];
    }
    testCell.testLabel.text = @"hello world";
    return testCell;
}

那是很首要的,千万记住,因为我们是直接拖cell到SB文件的tableView里的,所以平昔从录取池里取就好了。

那边稍微提二个地方:我们这里取重用cell用的是函数:
dequeueReusableCellWithIdentifier:,而系统中还有另贰个起用的函数:dequeueReusableCellWithIdentifier:forIndexPath:这几个函数比大家代码中用的不行好,是我们用的不行api的优化版,它是iOS6引入的api,完全符合大家一般app对版本包容的须要,那里谢谢简书用户coderzcj在评论中给我留言,感谢您。我继续会再写一篇小说专门说说系统对xib优化的工作的,非凡多谢大家的帮忙。

File Owner

Files
Owner指这些xib文件的所属文件是哪个人,不难的乃是xib文件和哪个人建立起相互,用户通与该xib展现的页面举行互相的时候,什么人来处理背后的逻辑。具体来讲xib文件能拖动“连线”到哪个源文件中去建立IBAction、IBOutlet、delegate、datasource等。

貌似依据View创立的xib的Files
Owner都内定为3个VC(但貌似选用都会创制3个相对应的类,然后指向该类)。基于VC创建的xib,创造的时候系统就早已把该xib文件的Files
Owner指向了该VC,一般那种状态就不对Files Owner做修改了。

图片 2

1490498-5f79953535024ab1.jpg

总结

SB的segue和cell使用是它最粗心思的地点,当然以前xib能做的设置,SB也都能做,而且多个.xib对应多少个SB文件,使文件量减少了累累,可是倘诺想单独用View的地点恐怕要用xib。

迎接大家和自作者互换交流,若文章中有不当和尾巴,恳请指正,多谢。

IBAction

确立IBAction连线的法子:

1.选中需求连线的靶子,按住control键,拖动该控件到Files
Owner类的@implementatio中放手,填写方法名即可。
树立IBAction连线的不二法门:

1.选中须要连线的目的,按住control键,拖动该控件到Files
Owner类的@implementatio中甩手,填写方法名即可。

图片 3

1490498-56ce8578de3b63d8.gif

2.先在@implementatio中定义3个措施,在再次回到值中写IBAction,然后点击前边的空心圆,拖动到xib的靶子上,两者就确立了“连线”的关系。

图片 4

1490498-fe72df4448bcd619.gif

IBOutlet

也是“连线”的一种,用于标记属性或变量,此形式将Files
Owner中的属性或字段,与xib中的有个别对象通过“连线”建立起涉嫌。

IBOutlet建立“连线”与查看“连线”的格局与IBAction相同。但要注意的是:假如拖动“线”到@interface里,就生成属性,若是拖动到@interface{}里大概拖动“线”到@implementatio中的{}里就转变变量。

此处大约说一下:在@implementation中{}里写变量(一般不这么干)和在@interface
XXClass()(匿名Category)里的{}中写变量是一致的,都以匿名的。

有点用却实用的

依据View成立的xib,是可以“连线”到温馨View所在类中的,如果给该xib设置了Files
Owner的习性后,可以而且“连线”到Files Owner的类中。

小编们兴许会赶上那种状态:要卷入2个View为二个单独的类,该View是可互相的,点击后,要发生变化,同时又要把互相的轩然大波传递给VC,如若用代码的话,就要把事件从View类传递给VC类,而一旦你包装的类用了xib,那么事情就大概多了,同时“连线”到View类和调谐Files
Owner类对应的VC中,在View类中处理UI的变更,在VC中拍卖逻辑,而不须要其余事件的传递,当用户交互的时候,那两根“连线”都会被回调。

SB使用

xib可以依据View、VC甚至本身单独的运用,而SB只好依照VC使用,为啥说比xib更狠抓大呢?重即使下面的三个原因:

1.SB支持segue

2.SB对cell的支撑更做实有力

图片 5

1490498-c779b4a50255c30f.gif

)]

大家在3个VC中精选要发生跳转的按钮,按control拖动到另一个VC上就会产出1个食谱,在菜单上您就足以挑选跳转的艺术push、present,这样不用写一行代码就能不负众望页面间的跳转,而两个VC之间的像纽扣一样用线连着三个VC的的事物就是segue,是八个UIStoryboardSegue对象,我们得以简单的知道成是成就页面跳转有关功用的三个类,是否很粗略?

segue尽管简易,怎样传参?

我们知道用SB的segue来完毕也页面跳转十二分便宜,不过如果要向跳转的页面传参该如何做?

一旦大家要点击ViewController这一个VC里的3个按钮,跳转到SecVC那么些VC中,把testTitle这些参数传过去。第①步依旧要选中按钮,拖到SecVC里,然后选中这么些segue,给它2个id值,确保用代码可以找到它,然后在ViewController中编码:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"sec"]) {
        SecVC *secVC = (SecVC *)segue.destinationViewController;
        secVC.testTite = @"hello world";
    }
}

安装SB中segue的identifier,紧要就是要在那里运用,因为三个button暴发的多少个页面跳转都是回调这一个函数,所以要用identifier来区分是哪个segue,跳哪个页面,传哪些参数。

id的sender就是触发跳转的百般button或任何控件。

图片 6

1490498-f26590ab61a5b9bf.gif

不明确的跳转如何使用segue?

转眼现象平日出现:甲VC中有个button,点击后有只怕跳转到乙页面,也说不定跳转的丙页面,怎么解?

小编们只要大家要点击ViewController那几个VC里的3个按钮,有恐怕要跳到SecVC,有或然要跳thirdVC。
1.在SB中准备segue。

图片 7

1490498-a890aa691ffb90b7.gif

留意大家这一次创造的segue的办法并不是选中button按control拖到另一个VC中,而是选中VC,右键选中triggered
segues里manual前面的+拖动到另贰个VC里,那些很重点,而且依旧要给segue三个id。

更灵活的segue

万一你熟悉了解了segue他实在可以做过多政工,其实segue并不仅能落成跳转,还有一类segue叫做relationship
segue,从前是扶助我们明白,所以说的比较不难,其实我们选中一个NavigationController按control键拖动到另二个VC上的话也得以生成segue,大家选中root
view
controller,就将Nav的rootViewController属性设置成了这几个VC,这么些segue就是relationship
segue,同样,拖动一个tabbarController也会冒出viewControllers的relationship
segue。

更好的接纳Cell

用xib的时候,要想用cell,寻常是起家一个cell子类,1个与之对应的.xib文件。用SB的时候要想用cell就简单的多了,因为cell是足以一向拖动到tableView里的,直接在tableView里管理cell设置属性,当然倘使是复杂的cell如故要子类话对应的.h、.m的。

SB在利用cell分三种意况:1静态cell,2动态cell。

静态cell

图片 8

1490498-240e6c7c16d2536a.jpg

专注静态cell一定要基于UITableViewController,否则会报错。
展现静态cell的tableView是绝不调用自身必须兑现的datasource协议的

您会很惊叹,为啥必须调用的datasource协议都无须完结?答案是静态,静态的cell,意义就在于你在xib中设置成什么样,他就突显怎样,不会再调用datasource向你要cell了,因为在SB文件中早就鲜明下来了。

在做一些“死”页面的时候SB的静态cell是很好的挑三拣四,静态cell也不是怎么着都不大概做,静态cell里的button还可以拖到@implementation中形成IBAction的,不过是心有余而力不足生成IBOutlet属性或字段的。

即便你强行的给2个静态的cell指定了一个cell的类,也是力不从心向其内部拖入IBOutlet的。那就是静态cell的局限性,然而若是您要安装的多少不多恐怕可以考虑用静态cell,因为您可以透过给cell上的控件设tag来找到它之所以赋值。

动态cell的使用

在上图中安装content属性为Dynamic
Prototypes就足以了。使用动态cell的话就要在VC中落到实处那八个必须完成的datasource协议了,下边举个简易的例子:
1.给cell内定二个class
2.给cell设置id,重用机制使用,其余质量就不详细表达了,和其他控件的习性几乎。

添加tableHeaderView和tableFooterView

没错,没有听错,不用代码,“拖”出header于footer,其实很简短,选中tablView,在控件中找到View拖到tableView上,往最上方拖动,知道看到左右有三个圈的时候甩手,这一个View就是tableHeaderView了,同理,往最下方拖,就是tableFooterView。

图片 9

1490498-cd74b79914fce993.gif

LaunchScreen.storyboard

从iOS8上马索爱多了4.7″和5.5″的二种配备,那使得适配尤其错综复杂,尤其是设置运营图,如若考虑到横竖屏的话,要做过多张图,最重大的是,运维图是最占体量的事物,为了更好、更方面的配置运维图,LaunchScreen.storyboard现身了,不难的话,运转的时候会加载这么些SB文件,大家得以同过它更便利的设置运转图,可以用auto
layout减弱运维图数量的应用,但此功效只扶助iOS8及其上述的系统。
那就是说问题来了,小编要想适配更低的系统怎么做?答:不用。
怎么样禁止该意义?

图片 10

1490498-f548fcc2e8376e63.jpg

Storyboard Entry Point

万一大家用xcode6恐怕更高版本的xcode创制工程以来,你会发觉自动就有了贰个Main.storyboard

application:didFinishLaunchingWithOptions:中平昔不一行代码运营就一直不难点,并不像之前那么,要创制window,钦命rootViewController,这几个是何等兑现的?

图片 11

1490498-b860cb27ad9a3659.jpg

xcode自动配置了3个SB文件,而以上的那总体都有xcode自动帮我们落成了。

那就是说难点来了:3个SB是能够对应七个VC的,他选哪些VC作为window的rootViewController?答案是Storyboard
Entry
Point,这几个事物就是用来钦命尤其作为rootViewController的,也等于说,xcode会找到表示为Storyboard
Entry
Point的至极VC加载它成为rootViewController,而后来的跳转就由咱们事先介绍的法门:

图片 12

1490498-f108e0c05c1f70b0.jpg

勾选就是安装了Storyboard Entry Point,设置了Storyboard Entry
Point的VC会有二个向右的箭头指向它,注意你在Main
Interface里选的SB文件中自然要有VC勾选了那个,不然xcode是不了解怎样设置rootViewController的,你不要顾虑多选的题材,你一旦采取1个新的VC,旧的不得了VC就自然没有了Storyboard
Entry Point,然而倘诺您又打消了勾选那么旧的VC并不会活动又添加Storyboard
Entry Point的,要小心。

高冷用法

图片 13

1490498-6baf58be612c8e95.jpg

IBAction与IBOutlet

那是大家最常接触的两个,大家对它们已经有了很好的认识,那里只简简单单的说一下。

对此2个类来说,方法和属性(在此间属性与字段合在一齐表示三个定义)是最根本的八个成分,而IBAction与IBOutlet就是各自标识方法与质量的,它们标识着由它们修饰的不二法门和质量是来自xib的,我猜它们是给编译器看的。

IBInspectable

在OC中使用IBInspectable,在swift中使用@IBInspectable

它是xcode6引入的新效率,它修饰的习性可能实例变量,会显得在xib中的属性栏中(Show
the Attributes
inspector),大家事先讲的事物都以xib是怎么影响代码的,而IBInspectable是可以用代码影响xib的,大概本人的抒发不是很不错,如故看贰个有血有肉事例吗。

  @interface ViewController : UIViewController

//gj_testFlag用IBInspectable修饰后,就能在xib中看到这个属性了,当然也可以用xib进行赋值了
@property (assign, nonatomic) IBInspectable BOOL gj_testFlag;

@end
```![1490498-0a46dcda9e2d9982.jpg](http://upload-images.jianshu.io/upload_images/2318672-eca4b84372b52bf8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

###IB_DESIGNABLE
在OC中将IB_DESIGNABLE写在@implementation前,在swift中将@IBDesignable写在class前

它也是xcode6引入的新功能,它的作用是可以在不运行的情况下把你的代码显示在xib或SB文件中。

两点说明:

1.这是一个针对UI显示的功能,所以只能是在UIView及其子类或者NSView及其子类上生效。

2.要想使IBDesignable起作用必须把代码写在drawRect里才能显示,同样的代码,我写在了awakeFromNib里就不会再xib中看出效果,只有写在了drawRect才可以。

举个例子:

我们建一个工程,新建一个TestView类继承自UIVIew,在Main.storyboard里拖一个View,class设置为TestView,背景设置成灰色。

![1490498-e7e06b420aa167ad.jpg](http://upload-images.jianshu.io/upload_images/2318672-8003435c42d37fe8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

IB_DESIGNABLE
@implementation TestView

  • (void)drawRect:(CGRect)rect {
    UIBezierPath *firtPath =
    [UIBezierPath bezierPathWithOvalInRect:CGRectMake(10, 10, 180,
    180)];
    CAShapeLayer *shapeL = [CAShapeLayer layer];
    shapeL.lineWidth = 20;
    shapeL.path =firtPath.CGPath;
    shapeL.strokeStart = 0;
    shapeL.strokeEnd = 1;
    shapeL.strokeColor = [UIColor yellowColor].CGColor;
    shapeL.fillColor = [UIColor clearColor].CGColor;
    [self.layer addSublayer:shapeL];
    self.layer.cornerRadius = 30;
    self.layer.masksToBounds = YES;
    }

@end

![1490498-bb8d92cace1eaaab.jpg](http://upload-images.jianshu.io/upload_images/2318672-a03e52aaefce99ac.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



###IBOutletCollection(ClassName):
将基于IBOutlet创建的对象放在一个NSarray里。
@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *testViewArr;
创建了一个array,里面放的是用IBOutlet创建的UIView.

注意最好用strong进行修饰,而且如果你声明的不是NSArray,即便是UIColor,系统也不会报错,你打印这个color发现,系统用的还是NSArray。这个array的顺序是连线时候的顺序,但是不排除不同版本的xcode会改变这个顺序,所以最好不要依赖这个顺序。

也可以像拖IBOutlet那样创建:

###Files Owner的应用举例
有这样一个场景,VC中有一个textfield要设置inputAccessoryView属性,该属性的view显示起来很复杂,有多个按钮,每个按钮对应不同的事件。

一般的做法是用代码写一个这样的view赋值给inputAccessoryView属性,其实这个例子可以用xib实现的更优雅,不用写代码就可以完成(当然点击每个按钮后的事件处理代码是要自己写的)。

例子中要考虑的重点是:
如果创建了一个AccessoryView.xib去拖出这样一个view,虽然不用“画”UI了,但是我们要建一个AccessoryView.h、AccessoryView.m类去与xib文件对应,在AccessoryView.m中把它上面的按钮事件记录下来,一旦触发事件,要通过delegate或通知等其他形式把事件从AccessoryView类传递给VC类,这样使事情更加的麻烦了,如何解决?

有人会想:创建AccessoryView.h、AccessoryView.m是没有必要的,因为他们除了传递事件,根本没做任何事情,这样的话就不创建他们,只有AccessoryView.xib文件,然后把xib中的按钮分别拖动到VC类中建立起IBAction的“连线”关系,事情就搞定了。

这个思路很好,但是我们会发现,并不能实现AccessoryView.xib与VC中的“连线”,因为VC类根本不认识这个xib,因此该VC是不允许这个xib通过“连线”向它内部添加代码的,如何解决这个问题?——Files Owner!

将AccessoryView.xib的Files Owner指定成该VC的类,此时再拖“连线”到VC就可以了,这样xib中按钮的事件就能直接回调到VC中我们设置的方法里了。
![1490498-39be8c63b59f1de8.jpg](http://upload-images.jianshu.io/upload_images/2318672-7f59af2081958963.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

xib文件是可以不依托于UIView子类、UIViewController子类单独使用的,只是这种情况比较少见,这是一个例子。