iOS 让自定义的xib在Storyboard中露脸呗

iOS 让自定义的xib在Storyboard中露脸呗_第1张图片
让 Storyboard GeGe 与 Xib MM从此不再形同陌路

其实很早之前就一直有一种将 SB和Xib结合的想法,奈何公司的代码从接手后就有种远离 SB 的不成文规定,(虽然有时候就是管不住手,硬是写了几个界面的SB),又因一直以来公司的业务迭代速度又增无减的情况下,使用 SB 导致的代码的复用率又实在是件让人无奈的事情。但不可置否的是,SB 终会一统江湖,我默默的坚信着

代码会说话,懂得就不用再往下看了,请接住demo


上图大图

iOS 让自定义的xib在Storyboard中露脸呗_第2张图片
SB的控制器显示自定义View

这些简单的搭建相信有经验的你是毫无鸭梨的啦,下面我们说说需要注意几个地方

  • 自定义的 ActView.xib 文件不应该设置 View 文件的 class 属性,而是设置 xib 的 File's Owner 的 class 为ActView(自定的View的文件名),如下图:
    iOS 让自定义的xib在Storyboard中露脸呗_第3张图片
    不设置View 的 Class 值

    iOS 让自定义的xib在Storyboard中露脸呗_第4张图片
    File's Owner 的 class 设为自定的View的文件名

其实上图的两个原则就像我们平时通过 SB/Xib 创建 ViewController 一样,ViewController 对应的 SB/Xib 文件会自动为我们生产一个 View 控件,此时的 View控件则已经被 Controller 的 File's Owner管理了,所以下面的一步也就是将ActView.xib文件中的 View 变为其管理的属性,将 View 连线至ActView.h上


iOS 让自定义的xib在Storyboard中露脸呗_第5张图片
Snip20170902_27.png

但仅仅是这样还不够的,因为即使ActView.h和ActView.m虽然是控制了(被拖拽放进来的)View,但是并无将其加载在自己身上,所以呢,还是得写几行代码告诉ActView文件,把你的脸面给装上才行

@implementation ActView

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setUpInitCotentView];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setUpInitCotentView];
    }
    return self;
}

- (void)setUpInitCotentView {
    
    //这里在Xib / Storyboard 编译的时候,我们需要告诉iOS系统,我们要指定哪一个bundle类去读取。不能获取mainBundle这个默认法法;
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];

    self.contentView = [[bundle loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
    [self addSubview:self.contentView];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.contentView.frame = self.bounds;
}
@end

注意NSBundle *bundle = [NSBundle bundleForClass:[self class]];方法:
此处不能通过mainBundle这个默认法来加载 nib 文件,我们必须得指定自定义 View的bundle类去读取这个 nib 文件,否则xib 也不能在 SB 中露脸
如上执行后,即可在运行时将 xib 应用到 SB 上了。但是要想让 xib 立即 在 SB �显示出来,那就要找到 IB_DESIGNABLE / IBInspectable 这个两个哥们帮帮忙才行了。
如下就是使用IB_DESIGNABLE / IBInspectable后让 xib 可在 SB 中立即变脸的代码,有空再说说他们两的细节吧~

ActView.m文件

#import "ActView.h"

IB_DESIGNABLE
@interface ActView ()

@property (strong, nonatomic) IBInspectable IBOutlet UIView *contentView;
@property (weak, nonatomic) IBOutlet UILabel *titleLB;

#pragma mark - IBInspectable Property
@property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
@property (nonatomic, assign) IBInspectable CGFloat bwidth;
@property (nonatomic, assign) IBInspectable UIColor *bcolor;

@end

@implementation ActView

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [self setUpInitCotentView];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self setUpInitCotentView];
    }
    return self;
}

- (void)setUpInitCotentView {
    
    //
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    self.contentView = [[bundle loadNibNamed:NSStringFromClass([self class]) owner:self options:nil] firstObject];
    [self addSubview:self.contentView];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.contentView.frame = self.bounds;
}

#pragma mark - getter & setter
- (void)setCornerRadius:(CGFloat)cornerRadius{
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius  = _cornerRadius;
    self.layer.masksToBounds = YES;
}

- (void)setBcolor:(UIColor *)bcolor{
    _bcolor = bcolor;
    self.layer.borderColor = _bcolor.CGColor;
}

- (void)setBwidth:(CGFloat)bwidth {
    _bwidth = bwidth;
    self.layer.borderWidth = _bwidth;
}

@end

参考文章:
关于IB_DESIGNABLE / IBInspectable的那些事
在OC和Swift中使用IBDesignable/IBInspectable
iOS 在storyboard中调用xib

你可能感兴趣的:(iOS 让自定义的xib在Storyboard中露脸呗)