How to display non-slashed zero character in Swift for the system font SF Mono

64 Views Asked by At

The system font SF Mono has two variations for the number zero (0) and number one (1).

By default, a slashed zero character is displayed for text with system font SF Mono.

In the MacOS Font Book, both a slashed zero and non-slashed zero have the code U+0030.

How can I specify a non-slashed zero on a UIButton title in Swift?

Thanks!


Example of a non-slashed zero character:

enter image description here

1

There are 1 best solutions below

0
user4806509 On

This answer uses the Stylistic Alternatives feature in CoreText.


Source:

This link describes the set of currently defined typographic and layout features available from applications using CoreText.

https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type35


Try this code:

import UIKit

class ViewController: UIViewController {
    
    // Set the status bar of the view to hidden
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.setNeedsStatusBarAppearanceUpdate()
    }
    override var prefersStatusBarHidden : Bool {
        return true
    }
    override var childForStatusBarHidden : UIViewController? {
        return nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the background color of the view to systemGray5
        view.backgroundColor = .systemGray5

        // Create a UIButton
        let button = UIButton(type: .system)

        // Set the title of the button to "100"
        button.setTitle("100", for: .normal)

        // Set the font of the button title to SFMono with a size of 150
        button.titleLabel?.font = UIFont.monospacedSystemFont(ofSize: 150, weight: .regular)

        // Set the background color of the button to systemYellow
        button.backgroundColor = .systemYellow

        // Set the tint color of the button to black
        button.tintColor = .black

        // Make the button rounded by setting its corner radius to 25
        button.layer.cornerRadius = 25

        // Ensure that the rounded corners are displayed correctly
        button.clipsToBounds = true

        // Define the font descriptor for the custom font
        let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body).withDesign(.monospaced)?.addingAttributes([
            .featureSettings: [
                
                // Set the stylistic alternative for "0"
                [
                UIFontDescriptor.FeatureKey.type: kStylisticAlternativesType,
                UIFontDescriptor.FeatureKey.selector: kStylisticAltThreeOnSelector
                ],
                
                // Set the stylistic alternative for "1"
                [
                UIFontDescriptor.FeatureKey.type: kStylisticAlternativesType,
                UIFontDescriptor.FeatureKey.selector: kStylisticAltFourOnSelector
            ]
                
            ]
        ])

        // Create the custom font
        let font = UIFont(descriptor: fontDescriptor!, size: 150)

        // Create an attributed string with the custom font
        let attributedString = NSAttributedString(string: "100", attributes: [.font: font])

        // Apply the attributed string to the button
        button.setAttributedTitle(attributedString, for: .normal)

        // Add the button to the view
        view.addSubview(button)

        // Center the button in the view
        button.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }
}

Running the code displaying stylistic alternatives for "0" and "1":

enter image description here