今天发现了APP中的一个bug,导航控制器中的地位按钮在iOS10中不能显示文字,具体代码如下
//定位视图的懒加载代码
- (MLLocationView *)locationView
{
if (!_locationView)
{
_locationView = [[MLLocationView alloc] init];
_locationView.locationStr = @"选择城市";
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(leftBarButtonItemAction:)];
[_locationView addGestureRecognizer:tap];
_locationView.userInteractionEnabled = YES;
}
return _locationView;
}
//添加导航条leftBarButtonItem代码
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.locationView];
//自定义locationView中的代码
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_label = [[UILabel alloc] init];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentLeft;
_label.font = [UIFont systemFontOfSize:14];
[self addSubview:_label];
[_label mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left);
make.top.equalTo(self.mas_top);
make.bottom.equalTo(self.mas_bottom);
make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH * 0.2);
}];
_imageView = [[UIImageView alloc] init];
_imageView.image = [UIImage imageNamed:@"the_drop_down"];
_imageView.contentMode = UIViewContentModeCenter;
[self addSubview:_imageView];
[_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_label.mas_right);
make.centerY.equalTo(self.mas_centerY);
make.right.equalTo(self.mas_right);
}];
}
return self;
}
基于我对barButtonItem的了解,使用initWithCustomView:
方法时,它自身的frame设置与否都不印象,因此我直接就没有设置frame,然后利用masonry的自适应布局实现了定位按钮的自适应宽度.
然而,我发现在ios10上,按钮上的文本不能显示.对于点击也没有反应,因为按钮没有frame.
作为一个新人,还没有完全了解iOS10和iOS11的变更,我只能猜测,所以我做了以下调整.
//按钮的懒懒加载
- (MLLocationView *)locationView
{
if (!_locationView)
{
_locationView = [[MLLocationView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH * 0.3, 44)];
_locationView.locationStr = @"选择城市";
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(leftBarButtonItemAction:)];
[_locationView addGestureRecognizer:tap];
_locationView.userInteractionEnabled = YES;
}
return _locationView;
}
//内部控价的约束也做了调整
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_label = [[UILabel alloc] init];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentLeft;
_label.font = [UIFont systemFontOfSize:14];
[self addSubview:_label];
[_label mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left);
make.top.equalTo(self.mas_top);
make.bottom.equalTo(self.mas_bottom);
make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH * 0.2);
}];
_imageView = [[UIImageView alloc] init];
_imageView.image = [UIImage imageNamed:@"the_drop_down"];
_imageView.contentMode = UIViewContentModeCenter;
[self addSubview:_imageView];
[_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_label.mas_right);
make.centerY.equalTo(self.mas_centerY);
}];
}
return self;
}
然后我又发现,这样在iOS10上能正常显示了,但是在iOS11上,按钮没有frame了,因此不能响应点击手势.这让我很疑惑,因为我对按钮设置了frame啊.
这就真的只能猜了.我对比了一下前后的代码区别,发现在控件内部,我没有对子控件右边和locationView的右边建立约束关系.所以我做了一次尝试
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
_label = [[UILabel alloc] init];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentLeft;
_label.font = [UIFont systemFontOfSize:14];
[self addSubview:_label];
[_label mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.mas_left);
make.top.equalTo(self.mas_top);
make.bottom.equalTo(self.mas_bottom);
make.right.equalTo(self.mas_right).multipliedBy(0.6);
make.width.mas_lessThanOrEqualTo(SCREEN_WIDTH * 0.2);
}];
_imageView = [[UIImageView alloc] init];
_imageView.image = [UIImage imageNamed:@"the_drop_down"];
_imageView.contentMode = UIViewContentModeCenter;
[self addSubview:_imageView];
[_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(_label.mas_right);
make.centerY.equalTo(self.mas_centerY);
}];
}
return self;
}
成功解决了这个问题,但是我现在很疑惑,不明白为什么.查了一些资料,都是导航条时最麻烦的,因为高度封装,没有接口.现在深有体会.现在我能确定的是,我需要设置控件的frame,而且必须在控件内部建立完整的约束关系.