在 Swift 中自动调整多行 UILabel 的大小

Autoresize multiline UILabel in Swift

我已经尝试了所有方法来自动调整 Swift 中的 UILabel 大小。当它是一行时,我可以自动调整文本大小,但当它是两行时,它就不再起作用了。 UILabel 中的文本通常每 10 秒更改一次。我试过的代码是:

let direction = UILabel(frame: CGRect(x: 95, y: 10, width: screenWidth - 95, height:100))
direction.numberOfLines = 0
direction.adjustsFontSizeToFitWidth = true
direction.lineBreakMode = .byWordWrapping
direction.textAlignment = .center
direction.minimumScaleFactor = 0.2
direction.font = UIFont.boldSystemFont(ofSize: 40)
view.addSubview(direction)
direction.text = "Ffafdafafdfa fafda  dfafaf afa"

func updateDirection(update: String){
    direction.text = update
} 

原文"Ffafdafafdfa fafda dfafaf afa"会自动调整大小,但是当调用updateDirection时字体大小不会从40改变。我也试过将行数设置为2并删除.byWordWrapping。如何让我的 UILabel 自动调整大小?

在没有约束的情况下试试这个:

    let direction = UILabel(frame: CGRect(x: 95, y: 10, width: 375 - 95, height:100))
    direction.numberOfLines = 0
    direction.adjustsFontSizeToFitWidth = true
    direction.textAlignment = .center
    direction.minimumScaleFactor = 0.2
    direction.font = UIFont.boldSystemFont(ofSize: 40)
    view.addSubview(direction)

    direction.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard"

我会试试这个代码 已满

先创建一个函数

func calchight(strin:String) -> CGFloat
   {
       let label =  UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: CGFloat.greatestFiniteMagnitude))
       label.numberOfLines = 0
        label.text = strin
       label.sizeToFit()
        return label.frame.height + 2
   }

然后在你想要调整标签大小时在你正确的地方调用这个函数

/----------------

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
    { 
        let heit = self.calchight(strin: StringObject)

        return (heit)
    }

/------------------------

这段代码很有用,不需要自动布局容器

在为标签指定文本后尝试使用函数 sizetofit()。 喜欢:

direction.sizeToFit()

下面的代码将保持 frame sizeadjust the font sizedirection label content 一致。

let backgroundView = UIView(frame: CGRect(x: 5, y: UINavigationController().navigationBar.frame.height + UIApplication.shared.statusBarFrame.height, width: UIScreen.main.bounds.width - 10, height: UIScreen.main.bounds.width - 100))
let direction = UILabel()

 override func viewDidLoad() {
    super.viewDidLoad()

 direction.backgroundColor = UIColor.green
 direction.numberOfLines = 0
 direction.textAlignment = .center
 direction.font = UIFont.boldSystemFont(ofSize: 40)
 direction.adjustsFontForContentSizeCategory = true
 direction.adjustsFontSizeToFitWidth = true
 direction.text = "This is some multiline label with a background colour" // Set or Initiate random function for your array here.

 backgroundView.backgroundColor = UIColor.red
 view.addSubview(backgroundView)
 backgroundView.addSubview(direction)

 Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(random), userInfo: nil, repeats: true)  

 direction.translatesAutoresizingMaskIntoConstraints = false

 NSLayoutConstraint(item: direction,
                       attribute: .leading,
                       relatedBy: .equal,
                       toItem: backgroundView,
                       attribute: .leadingMargin,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

NSLayoutConstraint(item: direction,
                       attribute: .trailing,
                       relatedBy: .equal,
                       toItem: backgroundView,
                       attribute: .trailingMargin,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true


NSLayoutConstraint(item: direction,
                       attribute: .top,
                       relatedBy: .equal,
                       toItem: backgroundView,
                       attribute: .topMargin,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true

NSLayoutConstraint(item: direction,
                       attribute: .bottom,
                       relatedBy: .equal,
                       toItem: backgroundView,
                       attribute: .bottomMargin,
                       multiplier: 1.0,
                       constant: 0.0).isActive = true


}

func random(sender: Timer) {

    //Place your random func code here.     
}

输出:

UILabel 会将其内容大小视为一行文本,即使 numberOfLines 设置为 non-zero 值,除非也设置了 preferredMaxLayoutWidth

换句话说,如果没有 preferredMaxLayoutWidth,它无法预测如何换行,所以它不打算这样做。似乎在自动布局过程中,UILabel 不知道如何平衡由其外部布局约束设置的宽度与文本换行之间的优先级。

所以它不会在垂直维度上施加任何额外的压力(超过一行的高度),即使它的内容压缩阻力高于其他视图,因为它会假设通过在垂直维度上施加压力横轴,将显示其内容。

所以解决方案是设置preferredMaxLayoutWidth,这样它就可以在包装文本后确定内容的高度,然后使用该内容大小与其他视图协商布局。

您可能想要避免 hard-coding 您 UILabel 的宽度。假设其容器的宽度不会根据自动布局而改变,那么使用它应该是安全的。在这种情况下,我在 UITableViewCellUICollectionViewCell 中,“标题标签”横跨单元格的整个宽度。

override func layoutSubviews() {
    // Tell the label it should wrap text at the same width as this cell's contentView.
    titleLabel.preferredMaxLayoutWidth = contentView.frame.width

    super.layoutSubviews()
}