Is there a neat way to represent a fraction as an attributed string?

前端 未结 3 1021
梦如初夏
梦如初夏 2021-01-24 02:27

i was wondering if there was a builtin method to represent

var someFraction = \"1/12\"

as an attributed string? i.e. the \"1\" is

相关标签:
3条回答
  • 2021-01-24 02:50

    Using the above UIFont extension:

    static func fractionFont(forTextStyle textStyle: UIFontTextStyle) -> UIFont {
    
        let font = UIFont.preferredFont(forTextStyle: .title1)
        let descriptor = font.fontDescriptor.addingAttributes(
            [
                UIFontDescriptor.AttributeName.featureSettings: [
                    [
                        UIFontDescriptor.FeatureKey.featureIdentifier: kFractionsType,
                        UIFontDescriptor.FeatureKey.typeIdentifier: kDiagonalFractionsSelector,
                        ],
                ]
            ] )
    
        return UIFont(descriptor: descriptor, size: font.pointSize)
    
    }
    

    Then the following function somewhere:

    func fractionMutableAttributedString(for string: String) -> NSMutableAttributedString {
    
        let attributes: [NSAttributedStringKey: Any] = [.foregroundColor: UIColor.blue]
        let attributedText = NSMutableAttributedString(string: string, attributes: attributes)
    
        let substring = string.split(separator: " ") // Do we have a fractional value?
        if substring[1].contains("/") {
             let range = (string as NSString).range(of: String(substring[1]))
            attributedText.addAttribute(NSAttributedStringKey.font, value: UIFont.fractionFont(forTextStyle: .title1), range: range)
         }
    
         return attributedText
    
    }
    

    and the use as:

    let string = "3 5/6"
    label.attributedText = fractionMutableAttributedString(for: string)
    

    to produce the correct fraction.

    0 讨论(0)
  • 2021-01-24 02:58

    You could use unicode to display fractions instead of using Attributed strings. This link has a source code written in objective C . You can easily port it in swift.

    0 讨论(0)
  • 2021-01-24 03:08

    If you want to have arbitrary fractions represented correctly, you should set the UIFontFeatureTypeIdentifierKey and UIFontFeatureSelectorIdentifierKey to kFractionsType and kDiagonalFractionsSelector respectively for UIFontDescriptorFeatureSettingsAttribute in a custom UIFontDescriptor. For example you can say something like:

    let label = UILabel(frame: CGRect(x: 0.0, y: 0.0, width: 1000.0, height: 100.0))
    let pointSize : CGFloat = 60.0
    let systemFontDesc = UIFont.systemFontOfSize(pointSize,
        weight: UIFontWeightLight).fontDescriptor()
    let fractionFontDesc = systemFontDesc.fontDescriptorByAddingAttributes(
        [
            UIFontDescriptorFeatureSettingsAttribute: [
                [
                    UIFontFeatureTypeIdentifierKey: kFractionsType,
                    UIFontFeatureSelectorIdentifierKey: kDiagonalFractionsSelector,
                ], ]
        ] )
    label.font = UIFont(descriptor: fractionFontDesc, size:pointSize)
    label.text = "The Fraction is: 23/271"
    

    with the following result:

    You can find more information here

    Swift 3.0

    extension UIFont
    {
        static func fractionFont(ofSize pointSize: CGFloat) -> UIFont
        {
            let systemFontDesc = UIFont.systemFont(ofSize: pointSize).fontDescriptor
            let fractionFontDesc = systemFontDesc.addingAttributes(
                [
                    UIFontDescriptorFeatureSettingsAttribute: [
                        [
                            UIFontFeatureTypeIdentifierKey: kFractionsType,
                            UIFontFeatureSelectorIdentifierKey: kDiagonalFractionsSelector,
                        ], ]
                ] )
            return UIFont(descriptor: fractionFontDesc, size:pointSize)
        }
    }
    
    let label = UILabel()
    label.backgroundColor = .white
    let pointSize: CGFloat = 45.0
    let string = "This is a mixed fraction 312/13"
    let attribString = NSMutableAttributedString(string: string, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: pointSize), NSForegroundColorAttributeName: UIColor.black])
    attribString.addAttributes([NSFontAttributeName: UIFont.fractionFont(ofSize: pointSize)], range: (string as NSString).range(of: "12/13"))
    label.attributedText = attribString
    label.sizeToFit()
    

    0 讨论(0)
提交回复
热议问题