对iOS中Storyboard的控件进行功能性扩展方案

对iOS中Storyboard的控件进行功能性扩展方案

一、前言:

Storyboard能够让我们对UI界面进行快速的搭建,并利用AutoLayout进行屏幕的适配,它能极大的节省我们的开发时间,同时以便我们能够在代码中完全专注于核心功能的实现上。
但是,对于有多语言需求的项目工程,Storyboard的一般做法是:
1、对新增的国际化语言配置文件中进行重新的翻译处理。
2、把Storyboard中的控件拉到代码中去重新赋值。
这两种实现方式,在处理起来都让人感到比较恶心。当然也有人说可以通过脚本来进行处理,但实现的效果可能并不是那么理想。
在这里,我们提出了另一种解决方案,就是通过编写对应控件的Category,让其在Storyboard上进行功能性扩展。

二、IBInspectable关键字:

在此之前,我们要先介绍一个关键字——IBInspectable。
在NIB、XIB、Storyboard的identifier inspector中,我们可以在User Defined Runtime Attributes对选中的控件进行key-value coded,虽然功能强大,但一个属性的关键字路径,类型和属性值需要在每个实例设置,没有任何自动完成或输入提示,这使得工作很繁琐。而 IBInspectable 属性彻底的解决了这个问题:在 Xcode 6,你现在可以指定任何属性作为可检查项并为你的自定义类建立了一个用户界面。

比如:当我们用IBInspectable去修饰一个控件的某个属性时,Storyboard对应控件的Attributes inspector中将会多出该属性的选项。当我们对该选项进行修改赋值时,identifier inspector中的key-value coded就会相应的做出变化。

三、对Storyboard的控件进行多语言功能扩展:

这里,我们拿UILabel作为示例,当然,UIButton和UITextField等的文本多语言设计思路也是一样的:

  • 1、通过Category对UILabel添加一个BOOL值的属性扩展。
  • 2、用IBInspectable关键字对这个属性进行修饰,使得我们能够在Storyboard中对其进行修改。
  • 3、当我们在Storyboard中对该属性设为true时,我们希望UILabel的text能够作为多语言实现方法NSLocalizedString(key, comment)中的key,从而对UILabel的text重新赋值。

这样一来,我们只需要在Localizable.strings文件中对文案进行键值对编写便可实现本地化,无需再把控件拖进代码中去修改了,也不用新增国际化语言配置文件中去重新翻译了。具体实现代码如下:

UILabel+SBLocalizable.h中:

#import <UIKit/UIKit.h>

@interface UILabel (SBLocalizable)

/**

 是否把当前text作为多语言的key

 */

@property (nonatomic, assign) IBInspectable BOOL textAsKey;

@end

UILabel+SBLocalizable.m中:

#import "UILabel+SBLocalizable.h"

#import <objc/runtime.h>

static const void *kLabelTextKey = &kLabelTextKey;

@implementation UILabel (SBLocalizable)

- (BOOL)textAsKey {

    return [objc_getAssociatedObject(self, @selector(textAsKey)) boolValue];

}

- (void)setTextAsKey:(BOOL)textAsKey {

    objc_setAssociatedObject(self,

                             @selector(textAsKey),

                             @(textAsKey),

                             OBJC_ASSOCIATION_ASSIGN);

    if (textAsKey) {

        objc_setAssociatedObject(self,

                                 kLabelTextKey,

                                 self.text,

                                 OBJC_ASSOCIATION_COPY_NONATOMIC);

        self.text = NSLocalizedString(self.text, nil);

    } else {

        self.text = objc_getAssociatedObject(self, kLabelTextKey);

    }

}

@end

四、对Storyboard的控件进行颜色功能扩展:

看了上面对多语言功能的扩展,我们可以用类型的方法,对控件添加一个UIColor的属性,并用IBInspectable关键字对其进行修饰,这样便可在Storyboard上对该属性的颜色进行修改了。

但是,一旦设计师要求对颜色进行调整,那么,我们便要一个个的去把相应的控件找出来,重新给颜色赋值,这又是一个恶心的任务。于是我们提供了另一种设计思路,这里用UIView作为示例:

  • 1、新建一个UIColor的Category,并用类方法返回我们需要的颜色。
  • 2、通过Category对UIVIew添加一个字符串属性扩展,这里我们就命名为bgColorName吧。
  • 3、用IBInspectable关键字对这个属性进行修饰,使得我们能够在Storyboard中对其进行修改。
  • 4、在Storyboard中UIView控件的新属性上,我们填写刚才新建的UIColor的取得颜色的类方法名。
  • 5、在bgColorName的set方法中,我们把取得的字符串转为UIColor的类方法,并取得对应的颜色,从而给UIView的backgroundColor重新赋值。

这样一来,一旦我们要替换某个颜色时,只要进行全局搜索,并让Storyboard以Source code的方式打开,便可以进行全局替换。具体实现代码如下:

​ UIColor+CorosColor.h中:

#import <UIKit/UIKit.h>

@interface UIColor (CorosColor)
  
+ (UIColor *)clearClr;
+ (UIColor *)whiteClr;
+ (UIColor *)blackClr;
+ (UIColor *)blueClr;
+ (UIColor *)redClr;

@end

​ UIView+BackgroundColor.h中:

#import <UIKit/UIKit.h>

@interface UIView (BackgroundColor)

/**
 背景颜色名称
 */
@property (nullable, nonatomic, strong) IBInspectable NSString *bgColorName;

@end

UIView+BackgroundColor.m中:

#import "UIView+BackgroundColor.h"
#import <objc/runtime.h>


@implementation UIView (BackgroundColor)

- (nullable NSString *)bgColorName {
    return objc_getAssociatedObject(self, @selector(bgColorName));
}

- (void)setBgColorName:(NSString *)bgColorName {
    if (!bgColorName || bgColorName.length == 0) {
        return;
    }
    UIColor *color;
    SEL sel = NSSelectorFromString(bgColorName);
    if ([UIColor respondsToSelector:sel]) {
        color = [UIColor performSelector:sel];
    }
    if (!color) {
        return;
    }
    self.backgroundColor = color;
    
    objc_setAssociatedObject(self,
                             @selector(bgColorName),
                             bgColorName,
                             OBJC_ASSOCIATION_COPY_NONATOMIC);
}


@end

五、结束语:

通过以上对IBInspectable的使用和设计思路,我们就可以根据需要,对相应的控件在Storyboard中进行功能性扩展,从而更好的利用Storyboard在UI搭建上的便利性,使得我们能在更简洁的代码中去专注于核心功能的实现上(PS:大家有空可以看看另一个相当有意思的关键字——IB_DESIGNABLE)。

最后需要注意的地方是,当我们不想使用该Category扩展出来的功能时,仅仅是删去Category代码文件是不够,因为当你在Storyboard中对相应控件的新增属性进行了更改赋值后,identifier inspector中的key-value coded并不会自动去删除对应的属性,这里我们还需要手动去删除对应的编码值。或者我们在删除Category代码文件前,先将Storyboard中控件对应的属性改回默认值Default,然后再删除Category代码文件。

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

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • 在29路公交车上,我费力穿过拥挤的人群走到略微空旷的后车厢,恰巧旁边的人到站,我坐到了倒数第二排靠窗的位置。相对于...
    iammonicaca阅读 110评论 0 0
  • 每个人在年少时,都会有很多美好的梦想。这些对自己未来的期望,随着时间的推移而变化。有的已经变成了现实,而有的在多次...
    残剑阅读 3,287评论 3 25
  • 最近看到的新闻和接受的信息都是关于人工智能,关于人工智能有个预测:未来70%-80%的工作将被人工智能取代。关于这...
    serena245阅读 208评论 0 0