美文网首页
iOS masonry约束立即生效和约束更新

iOS masonry约束立即生效和约束更新

作者: 走在长长地路上 | 来源:发表于2020-09-23 13:48 被阅读0次

需求是这样的,文本内容高度超过半屏,那么textview高度就是半屏,可以滑动显示内容。内容不超过半屏,就按照内容高度设置textview高度。
开始是使用frame布局的,需要计算每个控件的具体位置,当textview高度变化,textview下面放的button和其他view的frame需要重新赋值,因为它们的y值位置变了。使用这种方法太过麻烦,所以想寻找相对简单的方法。Masonry约束是大多数人都在使用的,约束的方法相当多。
但是masonry约束布局有延迟,不是调用了方法,控件的位置就能获取到的。调用了masonry去约束控件,再立马去打印控件的frame,你会发现,frame还是0。
所以当我设置了以下的约束:

    whiteBack = [[UIView alloc] init];
    [self.contentView addSubview:whiteBack];
    
    self.resultTextView = [[UITextView alloc] init];
    self.resultTextView.font = [UIFont boldSystemFontOfSize:36];
    self.resultTextView.textAlignment = NSTextAlignmentCenter;
    [whiteBack addSubview:self.resultTextView];
    
    self.voiceButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [self.voiceButton setImage:kGetImage(@"phrase_detail_voice") forState:UIControlStateNormal];
    [self.voiceButton addTarget:self action:@selector(voiceButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [whiteBack addSubview:self.voiceButton];
    
    line = [[UIView alloc] init];
    line.backgroundColor = kLineColor;
    [whiteBack addSubview:line];
    
    self.originTextView = [[UITextView alloc] init];
    self.originTextView.textColor = kHexColor(@"888C98");
    self.originTextView.textAlignment = NSTextAlignmentCenter;
    self.originTextView.font = [UIFont systemFontOfSize:17];
    [whiteBack addSubview:self.originTextView];

    [whiteBack mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.bottom.equalTo(self.contentView);
    }];
    
    [self.resultTextView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(25);
        make.right.offset(-25);
        make.top.offset(76);
        make.height.mas_equalTo(40);
    }];
    
    [self.voiceButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(whiteBack);
        make.top.equalTo(self.resultTextView.mas_bottom).offset(24);
        make.size.mas_equalTo(CGSizeMake(60, 30));
    }];
    
    [line mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.offset(20);
        make.right.offset(-20);
        make.bottom.equalTo(self.voiceButton.mas_bottom).offset(45);
        make.height.mas_equalTo(0.5);
    }];
    
    [self.originTextView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.resultTextView);
        make.top.equalTo(line.mas_bottom).offset(50);
        make.height.mas_equalTo(40);
    }];

// 刚开始没有添加下面这句
// [whiteBack layoutIfNeeded];

在调用接口拿到文本内容以后,我去更新textveiw的高度:

- (float)heightForTextView:(UITextView *)textView withFont:(UIFont *)font {
    
    CGSize constraint = CGSizeMake(textView.contentSize.width-textView.textContainer.lineFragmentPadding*2 , CGFLOAT_MAX);
    CGRect size = [textView.text boundingRectWithSize:constraint
                                             options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                          attributes:@{NSFontAttributeName: font}
                                             context:nil];
    float textHeight = ceil(size.size.height) + textView.textContainer.lineFragmentPadding*2;
    return textHeight;
}

- (void)resetSubviewsFrame {
    CGFloat otherHeight = 245;
    CGFloat maxHeight = (whiteBack.height - otherHeight)/2;
    
    CGFloat resultH = [self heightForTextView:self.resultTextView withFont:[UIFont boldSystemFontOfSize:36]];
    if (resultH > maxHeight) {
        resultH = maxHeight;
    }
    [self.resultTextView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(resultH);
    }];
    
    CGFloat originH = [self heightForTextView:self.originTextView withFont:[UIFont systemFontOfSize:17]];
    if (originH > maxHeight) {
        originH = maxHeight;
    }
    [self.originTextView mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(originH);
    }];
    
    [whiteBack layoutIfNeeded];
}

页面上的两个textview都没有显示出来,我来回滑动collectionView几次,文本才正常显示出来。
问题是我计算TextView允许的最大高度时候,使用了它们的父视图whiteBack的高度,但是使用whiteBack高度时候,它还是0;
解决办法是在第一次布局时,就使用layoutIfNeeded立即布局,之后再获取whiteBack的高度就有值了。

相关文章

网友评论

      本文标题:iOS masonry约束立即生效和约束更新

      本文链接:https://www.haomeiwen.com/subject/cjnnyktx.html