iOS11导航条frame设置失效

2017-11-20  本文已影响27人  codermali

今天发现了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,而且必须在控件内部建立完整的约束关系.

上一篇 下一篇

猜你喜欢

热点阅读