美文网首页
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