解读IBInspectable和IB_DESIGNABLE

前言

很久之前在用YYLabel时,看到头文件里有IBInspectable这个关键字,由于我的开发习惯是用xib做比较多的,当时无意发现,把一个xib控件UIView指定为YYLabel类型时,Xcode面板attributes inspector栏里竟然多了一些YYLabel里面的属性,当时一看觉得很神奇,原来Xcode还可以自定义xib面板里的attributes inspector栏,当时设置了几个属性,运行时也生效了,但是第二天再次打开Xcode时,编译发现出现一个error,但是编译的最重结果success的,虽然不影响使用,但是一直有个红色的error很不爽,于是就用的方式进行创建和设置属性了。

最近在项目中,由于设计师的需求是按钮有个半透明的状态的按钮,类似于UIButton不可点击状态,但是这个按钮是可以响应事件的,用于提示此输入内容错处。所以要考虑在项目中使用自定义的UIButton的子类按钮满足这个需求。为了兼容xib和纯代码两种方式的使用和修改。想到之前看到过的IBInspectable

关于IBInspectable

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.

大意上是根据runtime定义属性,而且是可审查、可看的意思。有点类似于自定义xib中的attributes inspector。可以实现在xib面板中使用自定义属性并可视化的修改。

但是支持的属性不多,包含以下几种


inspector-enable-type

在设计自定义Button时,我考虑使用UIButton工厂的方式创建自定义Button,同时传入一个参数,就可以修改这个Button成为预先定义好的属性样式。只可惜IBInspectable不支持枚举属性,为了使IBInspectable支持,只能退而使用NSInteger属性来定义枚举参数。头文件代码如下:

#import <UIKit/UIKit.h>

/**
 根据项目UI需求,设置通用按组件在不同状态下的样式
 */
typedef NS_ENUM(NSUInteger, IBInspectable HHCustomStyleState){
    HHCustomStyleStateDefault        = 0,    ///< 正常状态
    HHCustomStyleStateDisabled       = 4,    ///< 不可用状态
    HHCustomStyleStateCustom1        = 100   ///< 自定义状态(允许交互的半禁用状态)
};

@interface HHCustomStyleButton : UIButton

/**
 设置自定义按钮状态
 设置参数值对应上面的枚举
 默认值 HHCustomStyleStateDefault
 */
@property (nonatomic, assign) IBInspectable NSInteger cutomStyleState;

+ (instancetype)buttonWithCutomStyleState:(HHCustomStyleState)cutomStyleState;


/**
 提供修改背景接口
 */
@property (nonatomic, strong) UIColor *defaultStateBgColor;
@property (nonatomic, strong) UIColor *disabledStateBgColor;
@property (nonatomic, strong) UIColor *custom1StateBgColor;
@end

此时的xib面板里面


xib面板

不方便的地方时不能像UIButton通过枚举设置State Config,只能用NSInteger来替代枚举。

IBInspectable的使用

上面使用一个枚举样式的NSInteger来表述不同状态,一般情况下是满足项目中的使用了,但是有时候难免UI又会设计一些比较不同的样式,这时就要考虑Button组件扩展性了。

目前的设计是同时支持代码和xib使用,非特殊样式不用做自定义设置,但是加入要做自定义呢。做自定义可以分两种使用场景,一、纯代码创建使用,二、xib中创建使用。

  1. 纯代码中使用,以这样的方式使用
HHCustomStyleButton *btn = [HHCustomStyleButton buttonWithCutomStyleState:HHCustomStyleStateDefault];

以最接近UIButton的操作方式,这样修改或者替换或者使用都比较容易快速上手

  1. xib中的话,直接拖一个UIButton,指定它的类型为自定义的子类类型,本例中是HHCustomStyleButton,同时设置类型cutomStyleState

补充在xib中使用IBInspectable的其它信息:
一般情况下,以及大多数使用IBInspectable的地方,都是是要设置这个类为IB_DESIGNABLE,比如参考YYTextView

IB_DESIGNABLE
@interface YYTextView : UIScrollView <UITextInput>
@property (null_resettable, nonatomic, copy) IBInspectable NSString *text;
@property (nullable, nonatomic, strong) IBInspectable UIColor *textColor;
@property (nullable, nonatomic, strong) IBInspectable NSString *fontName_;

我最初也是这样设置,但是最后放弃使用IB_DESIGNABLE关键字
原因:

  1. 开发时,xib响应卡顿。因为是利用Runtime方式设置属性的,所以每次改动会实时反馈到界面上,但是Xcode这个地方做的不好,所以会卡顿

  2. Xcode自身的IBInspectable有Bug,像文章开头说道的会在编译时报错,同时xib的View变的不可见。

所以我这里没用IB_DESIGNABLE这个关键字,同时避免使用过多的IBInspectable入口来修改Xib界面,就是为了避免Xcode自身的Bug。需要自定义时,把这个控件IBOutlet出来,利用代码修改。

IBInspectable的不足之处

  1. 在Xcode中,使用OC的方式,IBInspectable是有Failed to update的Bug的,而且这个Bug是无解的,貌似有人说在Swift语言下似乎好一点,本人没有亲自尝试这个事情

  2. 每次自定义的Inspectable组件,它的Inspectable属性对应的runtime设置在User Defined Runtime Atttributes中不会自动清理。

总结

  1. IBInspectable一定程度上提供了自定义xib内部满足不了的设置,但是设置内容有限,使用不够方便。

  2. Xcode中的IBInspectable是有Bug的,这个是最严重的问题

  3. 基于自身Bug考虑,以及User Defined Runtime Atttributes中不会自动清理的问题,项目中不太建议大量使用IBInspectable,起码目前不建议

  4. 通过使用子类或者分类扩展的方式,IBInspectable可以方便的在xib中直接设置圆角,比之前使用User Defined Runtime Atttributes有多了一种更好的体验

下载Demo体验一下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,971评论 3 119
  • 寅叶子写《寅叶子》 正至,那年、那月、那日 寅时,我 来到这个世界 在叶氏的族谱上 又添一笔,为叶家担起了 延续香...
    寅叶子阅读 129评论 0 0
  • 大女儿今年即将中考,在第一模的考试成绩出来后,老师宣布只有十个同学达到了报考市一中的分数线,十个达到了市二中的...
    驼安阅读 269评论 0 0
  • 对自己,你可以真实的活着;对他人,永远不要太认真。所谓水至清则无鱼,人至察则无徒。 更多的时候,所谓尽善尽美本身就...
    大浪淘沙S6阅读 355评论 2 1