图片 15

IBInspectable的那二个急需留神的事,你真正明白Storyboard了吧

[textFiled setValue:placeholderColor
forKeyPath:@”_placeholderLabel.textColor”];

Ps.这里说的独有是loadNibNamed并不是initWithNibName。顺带提一下他们俩的差异点。initWithNibName要加载的Xib的类为我们定义的ViewController。loadNibNamed要加载的Xib的类为NSOjbect。他们的加载格局也不如,initWithNibName方法:是延迟加载,这些View上的控件是
nil 的,唯有到须求体现时,才会不是
nil。loadNibNamed是立刻加载,调用这些主意加载的xib对象中的各类要素都曾经存在。

率先我们先看看上边多少个单词我们是或不是都知晓哪些意思

不过每一回都为textField特地写那样一行代码,我们作为一个有追求的人,能或不可能用些更优雅的章程达成这一个供给吗?答案是用IBInspectable,通过IBInspectable可以定义动态属性,就能够在attribute
inspector面板中可视化修改属性值。

- (instancetype)initWithCoder:(NSCoder *)aDecoder
  • outlets
  • referencing outlets
  • IBOutlet
  • IBAction
  • IBOutletCollection
  • IBInspectable
  • IBDesignable

图片 1IBInspectable注明的习性出现在attribute
inspector面板中

归来难题上来,大家来稳重看看崩溃消息。音讯上说Could not load NIB in
bundle,並且还给了小编们三个好像地址同样的事物’NSBundle
</Applications/Xcode.app/Contents/Developer/Platforms/SamsungSimulator.platform/Developer/Library/Xcode/Overlays>
‘,大家得以固定到时Xib在从bundle中读抽取来出错了。

想必过几人在简历上写着通晓Storyboard,那么同学们着实都驾驭Storyboard了啊?拖约束那必将是最基本的了此地本人就不再多说。

下一场大家就足以看到IBInspectable注明的习性了。

上述就是自己和大家分享的IB_DESIGNABLE /
IBInspectable使用进度中蒙受的有些“坑”。

IBOutletCollection

IBOutletCollection,大家使用那么些主要字,能够将分界面上一组一样的控件连接到同三个数组中。比方:

@property(strong,nonatomic)IBOutletCollection NSArray*btnArray;

在swift中的写法为

 @IBOutlet var btnArray: [UIButton]!

好了,小功告成。

此间要求提一下IB_DESIGNABLE的劳作规律。当我们用了IB_DESIGNABLE关键字之后,Xib/StoryBoard会在不运营总体程序的图景下,把那么些View代码编写翻译跑一回,由于尚未前后相继上下文,全数的编译就只在那些view的代码中进行。

outlets和referencing outlets

outlets:显示自个儿全体的习性以及连接对象

图片 2荧屏快速照相二零一四-06-10 晚上12.14.45.png

referencing outlets:表示友好被接二连三到何以东西上

图片 3重写setter方法

总括一下:

IBDesignable和IBInspectable

行使IBInspectable去标识叁个变量,将会使得那个变量在改变时 IB
急迅的渲染你的自定义视图,进而达成视图在 IB
分界面实时修改的功能。IBInspectable不只能够申明在类里声称的变量,还包含extension 和 category 里的变量。被注脚的变量将会在 IB 的 attribute
inspector 面板中冒出,和日常的 View 的质量表现情势同样。

IBDesignable:当使用到 UIView 或 NSView 子类中的时候,@ IBDesignable 让
Interface Builder
知道它应当在画布上直接渲染视图。你会看到您的自定义视图在历次更换后不用编写翻译并运营你的应用程序就能够显得。
Objective-C 是 IB_DESIGNABLE 的宏,swif中只需在类名前拉长 @IBDesignable

举重若轻好说的,间接上代码吧

#import <UIKit/UIKit.h>IB_DESIGNABLE@interface textView : UIView@property (assign, nonatomic) IBInspectable CGFloat borderWidth;@property (strong, nonatomic) IBInspectable UIColor *borderColor;@property (assign, nonatomic) IBInspectable CGFloat cornerRadius;@end

- setBorderColor:(UIColor *)borderColor { self.layer.masksToBounds = YES; self.layer.borderColor = borderColor.CGColor;}- setBorderWidth:borderWidth { self.layer.masksToBounds = YES; self.layer.borderWidth = borderWidth;}- setCornerRadius:cornerRadius { self.layer.masksToBounds = YES; self.layer.cornerRadius = cornerRadius;}

写好代码你会开采你自定义的类的 attribute inspector 面板中多了那多少个属性

图片 4IBInspectable.png图片 5IBDesignable
* IBInspectable.gif

swift的代码

 @IBInspectable var cornerRadius: CGFloat = 0.0 { didSet { layer.cornerRadius = cornerRadius layer.masksToBounds = true } } @IBInspectable var borderColor: UIColor = UIColor() { didSet { layer.borderColor = borderColor.CGColor } } @IBInspectable var borderWidth: CGFloat = 0.0 { didSet { layer.borderWidth = borderWidth } }

当下下边那么些数据都对IBInspectable有效:

  • Int
  • CGFloat
  • Double
  • String
  • Bool
  • CGPoint
  • CGSize
  • CGRect
  • UIColor
  • UIImage

注意:永不在构造函数中期维修改attribute
inspector面板中的属性
:在构造函数中一旦对 attribute inspector
面板中出现的属性举办了起首化的话,会招致那些属性在运维时是依照你构造函数中的初阶化的值来体现,而在IB编辑分界面中却依照attribute inspector
面板的值来显示
,导致编辑时与运作时分界面包车型地铁差别。比如在开头化方法中设置backgroundColor
= UIColor.redColor(),而在 attribute inspector
面板中background的水彩为whiteColor,那将会招致在IB中您看到的那些视图背景为青黑,而运维时视图背景却为深蔚蓝。

那个是Storyboard的一局地,到那边也正是入门,越来越多内容小编会继续立异。近些日子表哥所在商城资金链断了,所以并未有了办事,各位小弟那假诺招人给四弟个空子三弟的对讲机:18611205315微信:zhanming61

最后,大家还要求重写IBInspectable注解属性的setter方法。

而是这里为啥会死循环呢?其实根本原因在于,大家自定义的类的class写成温馨了。

IBOutlet与IBAction

IBOutlet:通过在变量前增加IBOutlet来证实该变量将与分界面上的有些UI对象对应。

@property (weak, nonatomic) IBOutlet UIButton *btn;

IBAction:在形式前扩张IBAction来验证该措施将与界面上的平地风波对应。

- btnClick:(UIButton *)sender{}

图片 6此伏彼起textField并宣称属性

咱们拜候到面板上Designables这里展现的是一个Crashed,Xib / Storyboard
居然也会Crashed!整个app是跑起来了,但是报了2个错,无法忍!那七个错其实是编写翻译时候Xib报的一无所长,并非运维时的错误。

好了自己三个一个批注什么意思

接下去,我们从IB中拖三个UIText菲尔德到Xib中,而且将它的Class属性改为大家自定义的textField。

唯独在加载我们以此View的时候,会走initWithCoder / initWithFrame
方法,在此处方法里面又会去调用super的那个点子,以后大家把那个class写成了本身,依据大家地方调节和测量试验的log,能够看出,initWithCoder以往,会根据以下的路子去调用.

率先我们必要定义贰个UITextField的子类,何况用IBInspectable声澳优(Ausnutria Hyproca)天质量,这里笔者顺手演示一下怎么在Xib设置UITextField的leftView属性。代码如下:

当大家看看Debug的时候,肯定首先想到的便是点Debug。可是很倒霉的是,在这种景况下,点击Debug,每一趟都会告知您“Finishing
debugging instance of XXXX for interface
Builder”,就算你在你自定义的View里面打了断点,也没用。

有的时候大家要求修改UITextField的placeHolder的Color,大家得以在代码中那样写:

IB_DESIGNABLE / IBInspectable 那五个首要字是在WWDC 二〇一四年”What’s New in
Interface Builder”那几个Session里面,用Swift讲过二个例子。也是随着Xcode 6
新投入的要紧字。

c

再对照一下大家创立TableviewCell的经过

图片 7将Class属性改为自定义textField

#if TARGET_INTERFACE_BUILDER NSBundle *bundle = [NSBundle bundleForClass:[self class]]; [bundle loadNibNamed:@"BottomCommentView" owner:self options:nil];#else [[NSBundle mainBundle] loadNibNamed:@"BottomCommentView" owner:self options:nil]; #endif

相似大家会勾选上特别“Also create XIB
file”,创立达成之后,大家就能够在Custom
Class里面把我们那么些cell的类名填上。

此地在Xib / Storyboard
编译的时候,大家供给告诉iOS系统,大家要钦定哪三个bundle类去读取。把上面的代码改成上面那样就能够了。

- (instancetype)initWithFrame:frame

在我们创设完那一个类的时候,我们还要再次创下造三个Xib和这几个类举行关联。

下边这一段要多谢@Andy矢倉
今日头条上面指引笔者,其实系统的子类能够如此做:抽了多少个常用的控件的公共类,顺便用External剥离常用属性,更头晕目眩的位移那几个库IBAnimatable

明天来享受一下作者动用那多少个相当重要字的时候蒙受的有的主题材料和平搞定决进度。

或然那样

@Andy矢倉还指示说,用那个天性最佳是iOS8 +
斯维夫特,OC或然iOS7都会油然则生Failed to
update何况无解,再度多谢@Andy矢倉大神的教导!!!下图是她对系统控件的可视化改动!

self = [super initWithCoder:aDecoder];

可以很醒目标收看,是initWithCoder那几个方法陷入了死循环。由于那一个死循环导致了前后相继Crashed了。

let bundle = NSBundle(forClass: self.dynamicType)let nib = UINib(nibName: String(StripyView), bundle: bundle)

就完蛋了。其实从下边包车型客车栈音讯也得以异常的快看出发生了哪些:

要么这一行

其忽视即是说,“所见即所得”的研究,大家能够将自定义的代码实时渲染到Interface
Builder中。而它们中间的桥梁正是通过四个指令来成功,即@IBDesignable和@IBInspectable。大家经过@IBDesignable告诉Interface
Builder那一个类能够实时渲染到界面中,无论大家drawRect里面多么繁杂,自定义有多复杂,Xib
/
Storyboard都得以把它编译出来,并且渲染显示出来。然而那几个类必得是UIView大概NSView的子类。通过@IBInspectable能够定义动态属性,就可以在Attributes
inspector面板中可视化修改属性值。

 @IBInspectable var integer: Int = 0 @IBInspectable var float: CGFloat = 0 @IBInspectable var double: Double = 0 @IBInspectable var point: CGPoint = CGPointZero @IBInspectable var size: CGSize = CGSizeZero @IBInspectable var customFrame: CGRect = CGRectZero @IBInspectable var color: UIColor = UIColor.clearColor() @IBInspectable var string: String = "" @IBInspectable var bool: Bool = false

图片 8

而是这几个主题素材会直接导致整个app闪退,直接Crashed掉!无法,大家只可以打断点debug一下。

一旦想看Session的话,能够看那三个WWDC
二〇一六的链接whats_new_in_xcode_6whats_new_in_interface_builder苹果官方文书档案

图片 9

when using loadNibNamed:owner:options:, the File’s Owner should be
NSObject, the main view should be your class type, and all outlets
should be hooked up to the view, not the File’s Owner.

图片 10图片 11

大家在ViewController里面拖拽了三个View,并且更改它的class为大家自定义的class,那么接下去全数view的绘图都会付给大家以此自定义view的class,由这些class来治本。这里就分三种景况了。第一种意况就是自家小说一同初给的德姆o的例子,用DrawRect代码绘制出这几个View的旗帜。这里不会冒出任何难点。第三种情景便是大家还想用八个Xib来展现View,这种场地便是Xib/StoryBoard里面再一次加载Xib的景观了。由于现行反革命我们自定义的class有了接管整个view的绘图职分,那么大家就应有在initWithCoder中loadNibName,把整个View在最早化的时候load出来。总部方的剖析,大家找到崩溃的原故是特别递归,这里又必须要调用initWithCoder,大家的并世无两办法就是把class改成父类的class,即UIView,那时候一切就好了,Xib/Storyboard不报错,也能马上呈现出view的旗帜来了。

我们来思虑一下大家自定义View加载的历程。大家以此自定义View断定是放在了二个ViewController上边,代码创造出来可能直接拖拽到Xib
/ Storyboard
上。用代码只怕SB上面拖一个View,这年大家须求钦赐那几个类是何许,那么些不要置疑,是纯属没不平日的。SB上面拖的View的class肯定要挑选我们自定义的这一个View。

那五个重大字不是前天的首要性,看个德姆o就能够采用了。德姆o地址

只要大家前日自定义View的时候也是均等做法,创制完Xib文件之后,File‘s
owner关联好了后头。然后在Custom
Class里面填上了我们自定义的类之后,这年就错了!

经过在英特网寻觅资料,难题其实是如此的。

Ps:倘若你自定义的View不展现在Xib /
Storyboard上,不过程序一运维就又能展现出View来,原因也许有非常大概率是这几个缘故,纵然Xib
/ Storyboard未有报错,因为app没有运转起来,Xib /
Storyboard并不知道上下文,所以未有把我们自定义的View加载出来。

self = [super initWithFrame:frame];

图片 12

图片 13

经过地方的分析之后,大家就了然了难题就出在我们在initWithCoder里面又调用了loadNibName,loadNibName又会去最后调UIClassSwapper
initWithCoder。难道是大家custom
class不对么?相比一下大家自定义tableViewCell的class便是自家,怎么就不曾那一个难点吧。

一经你在Designables 这里把Debug张开,然后断点打到initWithCoder 和
initWithFrame这里,会发掘前后相继连接运转到这一行

Live RenderingYou can use two different attributes—@IBDesignable and
@IBInspectable—to enable live, interactive custom view design in
Interface Builder. When you create a custom view that inherits from
the UIView class or the NSView class, you can add the @IBDesignable
attribute just before the class declaration. After you add the custom
view to Interface Builder (by setting the custom class of the view in
the inspector pane), Interface Builder renders your view in the
canvas.You can also add the @IBInspectable attribute to properties
with types compatible with user defined runtime attributes. After you
add your custom view to Interface Builder, you can edit these
properties in the inspector.

图片 14

来探访毕竟产生了哪些。今后在Xode
7中,大家暗许创制四个View,是不给我们暗中同意生成八个XIB文件,ViewController会有上边那些选项,能够挑选勾上。

从NSBundle加载最早,深入分析完事后会调用到ClassSwapper
的initWithCoder,由于大家class写了团结,这里就沦为死循环了。程序崩溃!这里就跟set方法里面调用点语法赋值同样,Infiniti的递归调用了。

此地当然大家也足以上行下效那个措施做,那大家须求把loadNibName写到别的二个类中去。class如故写本人笔者,用拾贰分类来加载我们这些View,那样就能够不崩溃,不会Infiniti递归了。不过难点又来了,大家敬敏不谢在Xib/Storyboard上实时预览到大家的View了。

file://BottomCommentView/Base.lproj/Main.storyboard: error: IB Designables: Failed to update auto layout status: The agent crashedfile://BottomCommentView/Base.lproj/Main.storyboard: error: IB Designables: Failed to render instance of BottomCommentView: The agent crashed

咱俩来精心看看tableViewCell大家是怎么加载的,大家的Xib的class依旧自身,但是registerWithNibName的不二秘诀调用在tableView中,这样就不会非常递归了。

那多个基本点字是用在大家自定义View上的,近年来不常只可以用在UIView的子类中之所以系统自带的原生的那个控件使用那个根本字都未曾效果。

let nib = UINib(nibName: String(StripyView), bundle: nil)

一旦是碰着了那个难点,是相比严重的,那些主题材料不像难点一,难点一整个app是能够运转的,错误来源于Xib
/ Storyboard编写翻译时候的荒唐,可是并不影响这么些app的运维。

何以我们一向一模一样的做法,到这里就不当了吗?

当本人首先次知道IB_DESIGNABLE /
IBInspectable之后,感到到非常的奇妙,连大家自定义化的View也足以立刻可见了。然而经过一段探究以往就发掘。IB_DESIGNABLE
/
IBInspectable照旧有一点弱点的。IB_DESIGNABLE这几天只好在UIView的子类中用,常用的UIButton加圆角那么些有的时候也无助预览。IBInspectable实质是在Runtime
Attributes设置了值,那也使得IBInspectable只可以利用常用类型。NSDate那类别型无法设置成IBInspectable。

file://BottomCommentView-master/BottomCommentView/Base.lproj/Main.storyboard: error: IB Designables: Failed to update auto layout status: The agent raised a "NSInternalInconsistencyException" exception: Could not load NIB in bundle: 'NSBundle </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Xcode/Overlays> ' with name 'BottomCommentView'file://BottomCommentView/Base.lproj/Main.storyboard: error: IB Designables: Failed to render instance of BottomCommentView: The agent threw an exception.

[NSBundle loadNibName] —— [UINib instantiateWithOwner:options]
——[UINibDecoder
decodeObjectForKey:]——UINibDecoderDecodeObjectForValue——[UIRuntimeConnection
initWithCoder]——[UINibDecoder
decodeObjectForKey:]——UINibDecoderDecodeObjectForValue——[UIClassSwapper
initWithCoder:]——[BottomCommentView initWithCoder:]

历次我们取mainBundle的时候,都以用的私下认可的方式

万一您依据地方的首先个难题之中加多了bundle的代码之后如故不显得,那大概是您代码加的地点不对。

假若是代码手动成立控件的话,会调用initWithFrame方法

设如若透过Xib / Storyboard 拖拽彰显控件的话,会调用initWithCoder方法

When loading the nib, we’re relying on the fact that passing bundle:
nil defaults to your app’s mainBundle at run time.

必要在相应的那八个方法里面去丰富bundle的诀窍。借使为了保险起见,那这七个init方法里面都助长难点一里面包车型客车代码吧。

图片 15