如何将 UILabel 文本顶部和底部空间居中

Posted

技术标签:

【中文标题】如何将 UILabel 文本顶部和底部空间居中【英文标题】:How to center UILabel text top and bottom spaces 【发布时间】:2020-10-19 13:00:40 【问题描述】:

我在 tableview 单元格中的内容视图的 stackview 中有一个 UILabel。一切正常,单元格正在调整大小,但我无法将 UILabel 中的文本居中。我总是在文本底部有奇怪的空格。查看屏幕截图。

黄色:内容视图 绿色:堆栈视图 蓝色:标签

其他信息:单元格没有静态高度。黄色视图具有顶部底部和尾随和前导约束以及水平和垂直对齐到超级视图与堆栈视图相同的东西。我通过代码激活和停用的唯一具有恒​​定高度的是按钮。所以它根据单元格隐藏和显示。 Stackview 按比例填充。

UILabelsizeToFit

也试过了:

detailLbl.textAlignment = .center
detailLbl.lineBreakMode = .byWordWrapping //also tried byClipping
detailLbl.baselineAdjustment = .alignCenters

我将里面的文本解析为 HTML

"<p><font color=\"#cd1719\">V/. </font>…The Word of the Lord.<br><b></b><font color=\"#cd1719\">R/. </font><b>Thanks be to God.</b></p>"

第二张截图

"<h6 lang=\"en\" style=\"color=#cd1719 !important; font-weight: normal !important\"><font color=\"#cd1719\" weight=\"normal\"><i>The alleluia is said or sung.</i></font></h6>"

这是我用来解析 htmlNSAttributedString 扩展

 extension NSAttributedString 

    convenience init(htmlString html: String, font: UIFont? = nil, useDocumentFontSize: Bool = true) throws 
        let options: [NSAttributedString.DocumentReadingOptionKey : Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ]

        let data = html.data(using: .utf8, allowLossyConversion: true)
        guard (data != nil), let fontFamily = font?.familyName, let attr = try? NSMutableAttributedString(data: data!, options: options, documentAttributes: nil) else 
            try self.init(data: data ?? Data(html.utf8), options: options, documentAttributes: nil)
            return
        

        let fontSize: CGFloat? = useDocumentFontSize ? nil : font!.pointSize
        let range = NSRange(location: 0, length: attr.length)
        attr.enumerateAttribute(.font, in: range, options: .longestEffectiveRangeNotRequired)  attrib, range, _ in
            if let htmlFont = attrib as? UIFont 
                let traits = htmlFont.fontDescriptor.symbolicTraits
                var descrip = htmlFont.fontDescriptor.withFamily(fontFamily)

                if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitBold.rawValue) != 0 
                    descrip = descrip.withSymbolicTraits(.traitBold)!
                

                if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitItalic.rawValue) != 0 
                    descrip = descrip.withSymbolicTraits(.traitItalic)!
                
                
                attr.addAttribute(.font, value: UIFont(descriptor: descrip, size: fontSize ?? htmlFont.pointSize), range: range)
            
        

        self.init(attributedString: attr)
    


这就是我在代码中使用它的方式

if let attributedString = try? NSAttributedString(htmlString: htmlTxt, font: UIFont(name: "Avenir-Roman", size: CGFloat(Constants.defualtContentDescriptionFontSize)), useDocumentFontSize: false) 
        cell.detailLbl.attributedText = attributedString

【问题讨论】:

显示约束代码?你为桌子设置了静态高度吗? @Sh_Khan 没有静态高度。黄色视图具有顶部底部和尾随和前导约束以及水平和垂直对齐到超级视图与堆栈视图相同的东西。我通过代码激活和停用的唯一具有恒​​定高度的是按钮。所以它根据单元格隐藏和显示。 Stackview 按比例填充 @KeghamK。 - 不要使用按比例填充...使用Fill。不要更改按钮的高度限制。设置按钮的.isHidden 属性以显示/隐藏它。隐藏时,堆栈视图将自动删除它所占用的空间。 @DonMag 也试过了,但它没有用。是的,无需更改隐藏的约束就足够了,但底部仍然有这个空间 @KeghamK。 - 显示您用于解析 html 的代码。尝试在主视图中仅使用 UILabel 开始 - 忘记将其嵌入到表格视图单元格的堆栈视图中。 【参考方案1】:

部分问题在于您使用的是格式化 html 文本,其中包含“额外空间”。

例如,您的第一个 html 文本行包含 &lt;p&gt; &lt;/p&gt; 标记。

此代码创建两个绿色背景标签,每个标签宽度相同,没有高度限制:

class ViewController: UIViewController, UIScrollViewDelegate 

    override func viewDidLoad() 
        super.viewDidLoad()

        let firstLabel = UILabel()
        firstLabel.backgroundColor = .green
        firstLabel.numberOfLines = 0
        firstLabel.translatesAutoresizingMaskIntoConstraints = false

        let secondLabel = UILabel()
        secondLabel.backgroundColor = .green
        secondLabel.numberOfLines = 0
        secondLabel.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(firstLabel)
        view.addSubview(secondLabel)

        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            
            // first label 40-pts from top, 20-pts on each side
            firstLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            firstLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            firstLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),

            // second label 40-pts from bottom of first label, 20-pts on each side
            secondLabel.topAnchor.constraint(equalTo: firstLabel.bottomAnchor, constant: 40.0),
            secondLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            secondLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            
        ])
        
        var htmlTxt = "<p><font color=\"#cd1719\">V/. </font>…The Word of the Lord.<br><b></b><font color=\"#cd1719\">R/. </font><b>Thanks be to God.</b></p>"
        
        if let attributedString = try? NSAttributedString(htmlString: htmlTxt, font: UIFont(name: "Avenir-Roman", size: 24.0), useDocumentFontSize: false) 
            firstLabel.attributedText = attributedString
            //cell.detailLbl.attributedText = attributedString
        

        htmlTxt = "<font color=\"#cd1719\">V/. </font>…The Word of the Lord.<br><b></b><font color=\"#cd1719\">R/. </font><b>Thanks be to God.</b>"
        
        if let attributedString = try? NSAttributedString(htmlString: htmlTxt, font: UIFont(name: "Avenir-Roman", size: 24.0), useDocumentFontSize: false) 
            secondLabel.attributedText = attributedString
            //cell.detailLbl.attributedText = attributedString
        
    


输出:

两者的区别?对于第二个标签,我在使用您的扩展程序处理 html 之前删除了 &lt;p&gt; &lt;/p&gt; 标记。

您的第二个 html 文本将其定义为 h6 ...这是带有该字符串的输出:

同样,两者的区别在于我在处理html之前删除了h6标签。

你可能需要修改你的扩展来移除段落标签,或者设置一个忽略它们的段落样式。

【讨论】:

谢谢亲爱的,这是正确的答案。我也删除了stackview。我只会用空字符串替换

标记的出现,我相信它会被调整

以上是关于如何将 UILabel 文本顶部和底部空间居中的主要内容,如果未能解决你的问题,请参考以下文章

像素完美UILabel

如何在框架中水平(向上/向下)居中 UILabel 文本?

在 UIStackView 中垂直居中三个 UILabel

如何从底部对齐 UILabel 文本?

自动布局动画保持 UILabel 居中

使用自动布局将 UIButton 和 UILabel 居中