iOS自定义控件的问题及解决方法

       今天要写一个同时包含图片和文字的按钮控件,同时支持4种显示方式:图片在文字上面、下面、左边、右边,并且要能以纯代码和xib/storyboard方式创建,以autolayout对内部的图片和文字进行布局。为了支持纯代码方式创建,重写了initWithFrame方法,在其中用代码创建了UIImageView和UILabel,然后用masonry对其进行布局,没有问题。然后,为支持xib/storyboard方式创建,一开始,以为该自定义控件的实现也要以界面方式(实现方法参见:)。于是又创建了xib,重写了initWithCoder方法,在其中以

[[NSBundle mainBundle] loadNibNamed:@"ImageTitleButton" owner:self options:nil];方式从xib加载内容视图。但是,由于布局有4种方式可选,因此不能在xib中添加约束。所以还是采用masonry进行布局(复用纯代码中的布局代码)。结果问题来了,图片的显示是正常的,但是label的约束死活不起效果,总是显示为xib中拖放的位置和大小。几经周折,最后无奈接受了一点:在xib中创建视图,而在代码中为其添加约束,这种方法不可取,经常会出现各种莫名其妙的问题(笔者之前已经因为这种做法导致的各种视图不显示、显示不正常,已经浪费了很多时间。。。)。

       如果xcode输出以下错误信息,而代码添加的约束确实不存在冲突等问题,那有可能就是用代码为xib中的视图创建约束导致的。

       最后,纠结好久没法解决后,就尝试换了一种思路。一开始,想在initWithCoder方法中转调initWithFrame,即如下所示:

       

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

    [self initWithFrame:CGRectZero];

    return self;

}

    结果发现不行,又换成如下方式:

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

    if (self = [super initWithCoder:aDecoder]) {

        [self addSubviews];

    }

    return self;

}

其中addSubviews是代码中创建UIImageView和UILabel的函数:

- (void)addSubviews {

    _imageView = [[UIImageView alloc] init];

    [self addSubview:_imageView];

    _titleLabel = [[UILabel alloc] init];

    [self addSubview:_titleLabel];

}

autolayout还是之前的masonry代码,这次终于成功了。

总结一下,一定不要用用代码为xib中的视图创建约束。如果是界面里添加的视图,就在界面上使用autolayout;如果像本文这样不是布局不是静态的,而是比较灵活、运行时才能确定、且区别较大、必须用代码写约束的,那就在代码中创建视图。这并不影响最后整体的自定义控件从界面创建,因为可以参照上述initWithCoder方法,将界面创建转化为纯代码方式。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值