【问题标题】:Center image by first line of UILabel text以 UILabel 文本的第一行居中图像
【发布时间】:2017-11-14 22:22:30
【问题描述】:

我想将图像居中到 UILabel 第一行文本的中心 Y 位置。我使用砌体来设置这样的自动布局约束:

 [_haveReadIndicatorImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.equalTo(self.contentView).offset(SMALL_OFFSET);
        make.height.width.equalTo(@(8));
    }];

    [_topTxtlbl mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_haveReadIndicatorImgView.mas_right).offset(TINY_OFFSET);
        make.top.equalTo(_haveReadIndicatorImgView.mas_top);
        make.right.equalTo(self.arrowImgView.mas_left).offset(-SMALL_OFFSET);
        make.bottom.equalTo(_dateTxtLbl.mas_top).offset(-SMALL_OFFSET);
    }];

它应该非常简单。我只是将 UIImageView 的顶部附加到标签的顶部。

但是看看屏幕。

UIImageView 的上边缘(灰点)和标签是相等的,但是如何让 UIImageView 像这样居中于第一行文本呢?

谢谢。

【问题讨论】:

  • 可能更容易使用NSAttributedStringNSParagraphStylefirstLineHeadIndent 设置为 0,headIndent 设置为 10(对于文本的其余部分),以及使用NSTextAttachment(项目符号的图像,宽度将是headIndent 值)或直接使用项目符号点字符(或字符列表中的另一个)。
  • @Larme 你能举个例子吗?
  • NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithString:@"• MyLongTextHere"]; NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; [style setHeadIndent:15]; [style setFirstLineHeadIndent:0]; [attr addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, [attr length])];?
  • @Larme 谢谢你,但我用不同的方法达到目的,将作为答案发布。

标签: ios objective-c autolayout


【解决方案1】:

我通过 2 个步骤实现以下目标:

1) 计算特定字体文本标签行的预期高度:

+(CGSize)getSimpleSizeBasedOnFont:(CGFloat)font{

    UILabel *lbl = [UILabel new];
    lbl.text = @"Simple text";
    lbl.font = [UIFont systemFontOfSize:font];

    return [lbl.text sizeWithFont:lbl.font
                                constrainedToSize:lbl.frame.size
                                    lineBreakMode:NSLineBreakByWordWrapping];
}
  1. 然后我在 UIImage View 的 Y 中心添加约束,偏移量等于该高度的 50%:

CGFloat lblOffs = [Helper getSimpleSizeBasedOnFont:14].height; [_haveReadIndicatorImgView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(_topTxtlbl.mas_top).offset(lblOffs/2); make.left.equalTo(self.contentView).offset(SMALL_OFFSET); make.height.width.equalTo(@(8)); }];

【讨论】:

    【解决方案2】:

    您可以通过使用lineHeight 作为标签字体来导出第一行的中间部分。

    let lineHeight = ceil(multiLineLabel.lineHeight)
    let center = lineHeight / 2
    

    现在您有了中心,您可以使用 constant: centerhaveReadIndicatorImgViewcenterYAnchor 居中到标签顶部

    【讨论】:

    • 就我而言,label.font.lineHeight 是 16.003,label.sizeThatFits(_:) 是 18。我们可以看到 lineHeight 不够准确。
    • 哦不,我的问题是由标签的paragraphStyle.minimumLineHeight = 18.0引起的,这真的很混乱。你的方法是正确的。
    【解决方案3】:

    其实是有办法的!如果您使用普通的旧版 AutoLayout,可以使用以下 sn-p 来完成:

    // Aligns the icon to the center of a capital letter in the first line
    let offset = label.font.capHeight / 2.0
    
    // Aligns the icon to the center of the whole line, which is different
    // than above. Especially with big fonts this makes a visible difference.
    let offset = (label.font.ascender + label.font.descender) / 2.0
    
    let constraints: [NSLayoutConstraint] = [
      imageView.centerYAnchor.constraint(equalTo: label.firstBaselineAnchor, constant: -offset),
      imageView.trailingAnchor.constraint(equalTo: label.leadingAnchor, constant: -10)
    ]
    NSLayoutConstraint.activate(constraints)
    

    第一个约束将在标签第一行的 Y 中心显示您的图标。第二个将您的图标放在标签左侧,并在它们之间创建一个 10pt 的空间。

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      我最近通过在与多行标签完全相同的位置和字体添加一个隐藏单行标签解决了这个问题,没有底部约束。

      然后您可以简单地将图标图像.centerY 与隐藏标签的.centerY 对齐。

      【讨论】:

        【解决方案5】:

        我的做法不同。

        1. 首先我将我的 imageView 与 FirstBaseLine 的标签对齐。

        2. 然后我采取了那个 LayoutConstraint

        3. 我已经计算出如下偏移量:

          let offset = (label.font.capHeight + imageView.frame.size.height) / 2 //你的项目符号图像

        4. 我已经放弃了与 FirstBaseLine 常量

          的偏移量

          firstBaseLineConstraintWithLabel.constant -= offset

        这是输出

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-24
          • 1970-01-01
          • 1970-01-01
          • 2011-08-09
          • 1970-01-01
          • 2022-11-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多