我正在向应用程序中添加动态类型,并且尝试通过以下代码触发UIContentSizeCategoryDidChangeNotification通知时,更新以编程方式创建的UILabel的框架:

private func configureNotificationCenter() {
    NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange) , name: NSNotification.Name("UIContentSizeCategoryDidChangeNotification"), object: nil)
}

@objc private func contentSizeCategoryDidChange() {
    self.delegate?.didChangeContentSize()
}

然后在要更新UILabel的 View 中,更新框架:
func didChangeContentSize() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: {
        self.label.sizeToFit()
    })
}

由于某些原因,如果不调用DispatchQueue.main.asyncAfter ...,则无法正确设置框架。刚开始,我尝试在没有0.1秒延迟的情况下调用DispatchQueue.main,因为我知道UI更新应该始终在主线程上,但是似乎没有什么区别。

虽然延迟0.1秒并不是什么大问题,而且我认为没有任何用户会注意到,但了解发生了什么以及为什么需要延迟很重要。

编辑:这是我创建标签的方式
label = UILabel(frame: CGRect(x: 0, y: 100, width: view.frame.width, height: 200))
label.backgroundColor = .red
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.text = "Test title that should resize"
label.adjustsFontForContentSizeCategory = true
label.textAlignment = .center

let userFont =  UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title1)
let pointSize = userFont.pointSize
let customFont = UIFont(name: "AvenirNext-DemiBold", size: pointSize)
label.font = UIFontMetrics.default.scaledFont(for: customFont!)

label.sizeToFit()
view.addSubview(label)

最佳答案

这听起来很像是“自动布局”问题。当您不延迟时,“自动版式”将调整标签的固有尺寸并在修改标签的框架后运行,因此sizeToFit来得太早并且使用了以前的固有尺寸。

当您延迟0.1秒时,自动版式将首先运行并设置标签的固有尺寸,然后sizeToFit()调用将使用该新固有尺寸来设置框架。

使用自动版式

通过使用自动版式,使事情变得更轻松。无需设置frame大小,sizeToFit和通知,而只需设置标签的前,后和上边缘的约束,当字体大小更改时,“自动布局”将自动调整标签的大小:

label = UILabel()
label.backgroundColor = .red
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.text = "Test title that should resize"
label.adjustsFontForContentSizeCategory = true
label.textAlignment = .center

let userFont =  UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title1)
let pointSize = userFont.pointSize
let customFont = UIFont(name: "AvenirNext-DemiBold", size: pointSize)
label.font = UIFontMetrics.default.scaledFont(for: customFont!)

view.addSubview(label)

label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
label.topAnchor.constraint(equalTo: view.topAnchor).isActive = true

关于ios - 为什么从NotificationCenter调整标签的大小需要延迟才能按预期进行更新?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49183838/

10-12 03:00