更改首选内容大小后,我的一些可重用单元格标签中的字体大小仍然不变

Posted

技术标签:

【中文标题】更改首选内容大小后,我的一些可重用单元格标签中的字体大小仍然不变【英文标题】:After changing the preferred content size, the font size in some of my reusable cells' labels are still unchanged 【发布时间】:2021-03-29 04:27:27 【问题描述】:

我正在使用具有组合布局的 UICollectionView,其中包含 UICollectionViewListCells。每个单元格包含几个 UILabel。我使用自定义字体粗细设置动态类型

extension UIFont 
    static func preferredFont(for style: TextStyle, weight: Weight) -> UIFont 
        let metrics = UIFontMetrics(forTextStyle: style)
        let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style)
        let font = UIFont.systemFont(ofSize: desc.pointSize, weight: weight)
        return metrics.scaledFont(for: font)
    

来源:https://mackarous.com/dev/2018/12/4/dynamic-type-at-any-font-weight

然后我更改字体大小:

当我滚动浏览我的 UICollectionView 时,一些单元格的字体大小保持不变,而大多数单元格的大小都被正确调整(当使用像 UIFont.preferredFont(forTextStyle: .subheadline) 这样更简单的东西时,一切都完美无缺。获得正确字体大小以响应渲染的最佳方法是什么?首选内容大小的变化?

另外,我正在创建一个包含 SF Symbols https://***.com/a/58341241 的属性字符串,并使用

设置符号的大小
let configuration = UIImage.SymbolConfiguration(textStyle: .title1)

当我更改字体大小时,图像不会动态缩放。当我重新启动应用程序时,这两个问题都消失了。 UIContentSizeCategory.didChangeNotification 发帖时有什么我可以执行的代码,或者解决这两个问题的其他方法吗?

编辑 通过使用https://spin.atomicobject.com/2018/02/02/swift-scaled-font-bold-italic/ 此处列出的方法,我能够解决问题的第一部分。

extension UIFont 
    func withTraits(traits:UIFontDescriptor.SymbolicTraits) -> UIFont 
        let descriptor = fontDescriptor.withSymbolicTraits(traits)
        return UIFont(descriptor: descriptor!, size: 0) //size 0 means keep the size as it is
    

    func bold() -> UIFont 
        return withTraits(traits: .traitBold)
    



let boldFont = UIFont.preferredFont(forTextStyle: .headline).bold()

当首选内容大小发生变化时,我仍然不知道如何让属性字符串中的 sf 符号 UIImage 调整大小。

【问题讨论】:

更改字体大小后是否重新加载数据? 是的 - 我正在使用组合布局,所以我只是应用了具有相同部分和项目的新快照,但它看起来仍然很不稳定。 【参考方案1】:

当首选内容大小发生变化时,让属性字符串调整大小。

    func attributedStringDynamicTypeExample() 
        let font = UIFont(name: "Times New Roman", size: 20)!
        let fontMetrics = UIFontMetrics(forTextStyle: .title3)
        let scaledFont = fontMetrics.scaledFont(for: font)
        
        let attachment = NSTextAttachment()
        attachment.image = UIImage(named: "BigPoppa")
        attachment.adjustsImageSizeForAccessibilityContentSizeCategory = true
        
        let attributes: [NSAttributedString.Key: Any] = [.font: scaledFont]
        let attributedText = NSMutableAttributedString(string: "Your text here!", attributes: attributes)
        attributedText.append(NSAttributedString(attachment: attachment))
        
        label.adjustsFontForContentSizeCategory = true
        label.attributedText = attributedText
    
 

就获得正确字体大小以响应首选内容大小变化的最佳方法而言,我更喜欢像这样覆盖traitCollectionDidChange

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) 
        super.traitCollectionDidChange(previousTraitCollection)
        guard previousTraitCollection?.preferredContentSizeCategory
                != traitCollection.preferredContentSizeCategory
        else  return 
        collectionView.collectionViewLayout.invalidateLayout()
    

但是使用通知应该同样有效:

NotificationCenter.default.addObserver(self,
                   selector: #selector(sizeCategoryDidChange),
                   name: UIContentSizeCategory.didChangeNotification,
                   object: nil)

@objc private func sizeCategoryDidChange() 
            collectionView.collectionViewLayout.invalidateLayout()
        

【讨论】:

以上是关于更改首选内容大小后,我的一些可重用单元格标签中的字体大小仍然不变的主要内容,如果未能解决你的问题,请参考以下文章

问:如何更改 UITableView 中的单元格大小,以显示所有标签?

在这种情况下,如何使用自定义 tableView 单元格处理可重用单元格(从代码中的其他位置更改单元格背景颜色不起作用)

为啥我的 Tableview 重用了一些单元格?

根据单元格宽度更改 UITableViewCell 内容的首选方法

iOS:未使用重用标识符清除单元格内容

Tableview 单元格可重用性,切割标签文本