【问题标题】:Force UILabel to not hyphen words强制 UILabel 不使用连字符
【发布时间】:2020-09-11 11:50:43
【问题描述】:

所以我在 UIView 中有一个普通的 UILabel,里面有一些单词。它是一个 3 行标签,具有 .adjustsFontSizeToFitWidth = true

大多数情况下它可以正常工作,但在某些情况下会出现连字符,如下所示:

但在其他字母组合中,就像我想要/需要的那样,它不会连字符,只是调整大小:

我需要的是强制 UILabel 不要中断/连字符,而是更喜欢调整大小。换行模式在这里没有多大作用。 有没有我想念的方法来关闭连字符或断字? 我还试图找出如何检查单词是否被破坏但也无法找到它,因此我可以调整行数。

编辑:这里是操场代码看看:

import Foundation
import UIKit
import PlaygroundSupport

public class Card: UIView {

var label2: UILabel!

public init(frame: CGRect, withText: String) {
    super.init(frame: frame)
    
    self.backgroundColor = UIColor(red: 0.313, green: 0.89, blue: 0.76, alpha: 1.000)
    
    label2 = UILabel(frame: CGRect(x: bounds.width / 2 - 115, y: (bounds.height/2 - 90), width: 230, height: 180))
    
    label2.textAlignment = .center
    
    label2.text = "stepper; rotory; revolutionizing"
    label2.font = UIFont.boldSystemFont(ofSize: 60)
    label2.textColor = UIColor.white
    
    label2.adjustsFontSizeToFitWidth = true
    label2.translatesAutoresizingMaskIntoConstraints = false
    
    label2.numberOfLines = 0
    
    self.addSubview(label2)
    
    //        label2.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
    //        label2.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -50).isActive = true
    //        label2.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 50).isActive = true
    //        label2.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
    
    
    
}

required public init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}




}


let card = Card(frame: CGRect(x: 10, y: 30, width: 280, height: 200),         withText: "????")

let page = PlaygroundPage.current

let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 500))
view.backgroundColor = UIColor.white
view.addSubview(card)


page.liveView = view

【问题讨论】:

    标签: ios swift uilabel hyphen


    【解决方案1】:

    有两种方法,第一种是:

    yourLabel.text = "stepper;\nrotor;\nrevolutioning;"
    

    只需在任何单词的最后添加 \n...

    第二个: 创建3个标签,带有相对文本,并将其放在垂直stackView中...

    let yourLabel1 = UILabel()
    let yourLabel2 = UILabel()
    let yourLabel3 = UILabel()
    
    yourLabel1.text = "stepper;"
    yourLabel2.text = "rotor;"
    yourLabel3.text = "revolutioning;"
    

    之后创建堆栈视图并添加标签

    let stackView = UIStackView(arrangedSubviews: [label1, label2, label3])
    stackView.axis = .vertical
    stackView.distribution = .fillEqually
    ... etc etc
    

    设置 stackView 约束,一切顺利

    更新您的评论:

    yourLabel.text = "stepper; rotor; revolutioning; xxxxxxx; xx; xxxxxxxxxxxxxx; xxxxx; xxxxxxxxxxxx"
    yourLabel.font = .systemFont(ofSize: 40, weight: .semibold)
    yourLabel.textColor = .black
    yourLabel.adjustsFontSizeToFitWidth = true;
    yourLabel.minimumScaleFactor = 0.2;
    yourLabel.numberOfLines = 0;
    yourLabel.translatesAutoresizingMaskIntoConstraints = false
        
    view.addSubview(yourLabel)
    yourLabel.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    yourLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -50).isActive = true
    yourLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 50).isActive = true
    yourLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    

    具体更新 添加这个扩展:

    extension UILabel{
    
    func adjustedFont()->UIFont {
        let attributes: [NSAttributedString.Key: Any] = [.font: font as Any]
        let attributedString = NSAttributedString(string: text ?? "", attributes: attributes)
        let drawingContext = NSStringDrawingContext()
        drawingContext.minimumScaleFactor = minimumScaleFactor
    
        attributedString.boundingRect(with: bounds.integral.size, options: .usesLineFragmentOrigin, context: drawingContext)
    
        let fontSize = font.pointSize * drawingContext.actualScaleFactor
    
        return font.withSize(fontSize)
    }
    
    func fitLabelWords(){
        layoutIfNeeded()
        let scaledFont = self.adjustedFont()
        let currentFont = scaledFont
        if let txt = text,
            let maxString = txt.components(separatedBy: " ").max(by: {$1.count > $0.count})?.replacingOccurrences(of: "\n", with: ""){
            let maxFontSize: CGFloat = currentFont.pointSize
            let minFontSize: CGFloat = 5.0
    
            var maxS = maxFontSize
            var minS = minFontSize
            let height = currentFont.lineHeight
            let constraintSize = CGSize(width: .greatestFiniteMagnitude, height: height)
            var sizedFont = currentFont
            while(minS <= maxS){
                let currentSize = (minS + maxS) / CGFloat(2)
                sizedFont = currentFont.withSize( CGFloat(currentSize) )
    
                let text = NSMutableAttributedString(string:maxString, attributes:[NSAttributedString.Key.font:sizedFont])
    
                let textRect = text.boundingRect(with: constraintSize, options: [.usesLineFragmentOrigin], context: nil).integral
                let labelSize = textRect.width
    
                //1 is a fudge factor
                if labelSize == ceil(self.bounds.width - 1){
                    break
                }else if labelSize > ceil(self.bounds.width - 1){
                    maxS = currentSize - 0.1
                }else{
                    minS = currentSize + 0.1
                }
            }
    
            if sizedFont.pointSize < currentFont.pointSize{
                self.font = sizedFont
            }
        }
     }
    }
    

    这样设置你的标签:

    label2 = UILabel(frame: CGRect(x: view.bounds.width / 2 - 115, y: (view.bounds.height/2 - 90), width: 230, height: 180))
        
    label2.textAlignment = .center
    label2.text = "stepper; rotory; revolutionizing; skfghjkadsghasdg;"
    label2.numberOfLines = 0
    label2.font = UIFont.boldSystemFont(ofSize: 60)
    label2.textColor = .white
    label2.adjustsFontSizeToFitWidth = true
    label2.minimumScaleFactor = 0.3
    label2.fitLabelWords()
        
     view.addSubview(label2)
    

    【讨论】:

    • 非常感谢您的回答,但我认为这行不通,问题是可以有任意数量的单词,例如 2、4 或 6,可能不会更多但仍然,那是行不通的——在第一种情况下,我不能有 6 行。第二个例子可能会更有问题,因为不同的视图可以有不同的缩放比例?也许我应该指定这应该适合给定的高度/宽度约束(例如图片中)
    • 好吧,也许在第一种情况下,它可以通过缩放线条来适应给定高度的 7 行,但在这种情况下,每行都会有一个单词,这无论如何都不是首选情况。我想要的只是在没有任何单词刹车的情况下进行缩放。因此,如果任何单词需要连字符,它只需调整比例而不是连字符,现在它是根据具体情况决定它想要如何表现:)
    • 尝试将此添加到您的标签中:yourlabel.adjustsFontSizeToFitWidth = true; yourlabel.minimumScaleFactor = 0.2; yourlabel.numberOfLines = 0;
    • 我已经添加了游乐场页面,你可以看看吗?问题是这只出现在某些边缘情况下,所以如果视图有点小或者只添加了一个字母,它就会开始表现得像这样。
    • 我更新了我的答案,看看具体更新...
    猜你喜欢
    • 2013-09-20
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多