How can I get weight of a UILabel?

故事扮演 提交于 2020-05-14 20:05:07

问题


User from storyboard or programatically can set font weight as regular, semi bold etc.

I want to read weight for any font label.

I tried po label.font.description and font-weight is there and but there is no exposed variable to get weight from font.

Is it possible?


回答1:


To get the font weight string name, use the font descriptor and pass in the face attribute.

Swift 4.2

let font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.bold)
let face = font.fontDescriptor.object(forKey: UIFontDescriptorFaceAttribute) as! String
print("face: \(face)")

Swift 3

let font = UIFont.systemFont(ofSize: 14, weight: UIFontWeightBold)
let face = font.fontDescriptor.object(forKey: UIFontDescriptorFaceAttribute) as! String
print("face: \(face)")



回答2:


It seems that fontDescriptor.fontAttributes won't return all the attributes of a font. Luckily fontDescriptor.object(forKey: .traits) will, so we can hop onto that.

extension UIFont {
    var weight: UIFont.Weight {
        guard let weightNumber = traits[.weight] as? NSNumber else { return .regular }
        let weightRawValue = CGFloat(weightNumber.doubleValue)
        let weight = UIFont.Weight(rawValue: weightRawValue)
        return weight
    }

    private var traits: [UIFontDescriptor.TraitKey: Any] {
        return fontDescriptor.object(forKey: .traits) as? [UIFontDescriptor.TraitKey: Any]
            ?? [:]
    }
}

and then it's as simple as label.font.weight

(This is fundamentally equivalent to https://stackoverflow.com/a/48688000/1288097 but it uses UIKit APIs)




回答3:


Try following sample font extension with Swift 4. (It needs some improvement for all types of font weights)

extension UIFont {

    func getFontWeight() -> UIFont.Weight {

        let fontAttributeKey = UIFontDescriptor.AttributeName.init(rawValue: "NSCTFontUIUsageAttribute")
        if let fontWeight = self.fontDescriptor.fontAttributes[fontAttributeKey] as? String {
            switch fontWeight {

            case "CTFontBoldUsage":
                return UIFont.Weight.bold

            case "CTFontBlackUsage":
                return UIFont.Weight.black

            case "CTFontHeavyUsage":
                return UIFont.Weight.heavy

            case "CTFontUltraLightUsage":
                return UIFont.Weight.ultraLight

            case "CTFontThinUsage":
                return UIFont.Weight.thin

            case "CTFontLightUsage":
                return UIFont.Weight.light

            case "CTFontMediumUsage":
                return UIFont.Weight.medium

            case "CTFontDemiUsage":
                return UIFont.Weight.semibold

            case "CTFontRegularUsage":
                return UIFont.Weight.regular

            default:
                return UIFont.Weight.regular
            }
        }

    return UIFont.Weight.regular
}

Try with label:

let label = UILabel()
var fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.bold)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.black)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.heavy)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.ultraLight)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.thin)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.light)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.medium)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

label.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.semibold)
fontWeight = label.font.getFontWeight()
print("fontWeight - \(fontWeight)")

Here is Apple document for list of Font Weights

The value of this weight is an NSNumber object. The valid value range is from -1.0 to 1.0. The value of 0.0 corresponds to the regular or medium font weight. You can also use a font weight constant to specify a particular weight.




回答4:


It seems that there is no direct way to get it. As a workaround, You could get an indication of what's the weight of the font as follows:

let labelFont = label.font as CTFont
if let fontTraits = CTFontCopyTraits(labelFont) as? [CFString: CFNumber], let fontWeight = fontTraits[kCTFontWeightTrait] {
    print(fontWeight)
}

The UIFont has been casted as CTFont, which generates CFDictionary (by using CTFontCopyTraits(_:)) that contains the value of kCTFontWeightTrait. Note that it would not what is the exact font weight, nevertheless it could be somehow useful to an indication of what is the weight:

Key to access the normalized weight trait from the font traits dictionary. The value returned is a CFNumber representing a float value between -1.0 and 1.0 for normalized weight. The value of 0.0 corresponds to the regular or medium font weight.




回答5:


You can play around with font's symbolic traits:

// is true when font is bold
label.font.fontDescriptor.symbolicTraits.contains(UIFontDescriptorSymbolicTraits.traitBold)

Check docs for more traits.



来源:https://stackoverflow.com/questions/48686358/how-can-i-get-weight-of-a-uilabel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!