Using custom font for entire iOS app swift

前端 未结 5 1346
南方客
南方客 2020-11-29 04:48

I know that to set a custom font of an element on the screen I can simply dosomeLabel.font=UIFont(name: \"Exo 2.0\", size: 15).

I was wondering how one

相关标签:
5条回答
  • 2020-11-29 05:13

    You can set the appearance of the UILabel and other UIViews:

    UILabel.appearance().font = UIFont(name: "yourFont", size: yourSize)
    

    More General:

    AnyUIView.appearance().font = UIFont(name: "yourFont", size: yourSize)
    
    0 讨论(0)
  • 2020-11-29 05:13

    As a more detailed answer and with these benefits I recommend using extensions:

    • No size override (whatever you set in designer will be used)
    • No style override (Bold, Light, Medium, UltraLight is implemented in my code but you can customize it as you need)
    import UIKit
    
    extension UILabel {
        @objc var substituteFontName : String {
            get {
                return self.font.fontName;
            }
            set {
                let fontNameToTest = self.font.fontName.lowercased();
                var fontName = newValue;
                if fontNameToTest.range(of: "bold") != nil {
                    fontName += "-Bold";
                } else if fontNameToTest.range(of: "medium") != nil {
                    fontName += "-Medium";
                } else if fontNameToTest.range(of: "light") != nil {
                    fontName += "-Light";
                } else if fontNameToTest.range(of: "ultralight") != nil {
                    fontName += "-UltraLight";
                }
                self.font = UIFont(name: fontName, size: self.font.pointSize)
            }
        }
    }
    
    extension UITextView {
        @objc var substituteFontName : String {
            get {
                return self.font?.fontName ?? "";
            }
            set {
                let fontNameToTest = self.font?.fontName.lowercased() ?? "";
                var fontName = newValue;
                if fontNameToTest.range(of: "bold") != nil {
                    fontName += "-Bold";
                } else if fontNameToTest.range(of: "medium") != nil {
                    fontName += "-Medium";
                } else if fontNameToTest.range(of: "light") != nil {
                    fontName += "-Light";
                } else if fontNameToTest.range(of: "ultralight") != nil {
                    fontName += "-UltraLight";
                }
                self.font = UIFont(name: fontName, size: self.font?.pointSize ?? 17)
            }
        }
    }
    
    extension UITextField {
        @objc var substituteFontName : String {
            get {
                return self.font?.fontName ?? "";
            }
            set {
                let fontNameToTest = self.font?.fontName.lowercased() ?? "";
                var fontName = newValue;
                if fontNameToTest.range(of: "bold") != nil {
                    fontName += "-Bold";
                } else if fontNameToTest.range(of: "medium") != nil {
                    fontName += "-Medium";
                } else if fontNameToTest.range(of: "light") != nil {
                    fontName += "-Light";
                } else if fontNameToTest.range(of: "ultralight") != nil {
                    fontName += "-UltraLight";
                }
                self.font = UIFont(name: fontName, size: self.font?.pointSize ?? 17)
            }
        }
    }
    

    Samples for using Extensions:

    e.g. put these lines in your starting controller viewDidLoad

    UILabel.appearance().substituteFontName = "IRANSans"; // USE YOUR FONT NAME INSTEAD
    UITextView.appearance().substituteFontName = "IRANSans"; // USE YOUR FONT NAME INSTEAD
    UITextField.appearance().substituteFontName = "IRANSans"; // USE YOUR FONT NAME INSTEAD
    

    P.S. as @Christian mentioned, you can write your own extensions for almost AnyUIView

    0 讨论(0)
  • 2020-11-29 05:14

    FINALLY figured this out. Cleanest way I could find. (Swift 4) Solution doesn't require you to set font sizes and won't override all font sizes.

      UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFontTextStyle(rawValue: "Roboto"))
    

    For those looking for where to place this code. I put it in my AppDelegate.swift file inside of

     func application(_ application: UIApplication, 
     didFinishLaunchingWithOptions...
    

    Swift 4.2

     UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle(rawValue: "Roboto"))
    
    0 讨论(0)
  • 2020-11-29 05:18

    The answer is a combination of the answers offered already, but I had to try a combination of things to get it working in iOS 13:

    This is all placed in a Table View Controller, which is made to conform to the UIFontPickerViewControllerDelegate in order to offer a view for the user to pick the font. This will update all the UILabels with the new font, but keep the other attributes.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath)
    
        if cell === fontCell {
            if #available(iOS 13, *) {
                let configuration = UIFontPickerViewController.Configuration()
                configuration.includeFaces = true
    
                let fontVC = UIFontPickerViewController(configuration: configuration)
                fontVC.delegate = self
    
                present(fontVC, animated: true)
            } else {
                let ac = UIAlertController(title: "iOS 13 is required", message: "Custom fonts are only supported by devices running iOS 13 or above.", preferredStyle: .alert)
                ac.addAction(UIAlertAction(title: "OK", style: .default))
                present(ac, animated: true)
            }
        }
    }
    
    }
    
    @available(iOS 13.0, *)
    extension AppearanceTableViewController: UIFontPickerViewControllerDelegate {
        func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
            // attempt to read the selected font descriptor, but exit quietly if that fails
            guard let descriptor = viewController.selectedFontDescriptor else { return }
    
            let font = UIFont(descriptor: descriptor, size: 20)
            UILabel.appearance().substituteFontName = font.fontName
        }
    }
    
    extension UILabel {
        @objc public var substituteFontName : String {
            get {
                return self.font.fontName;
            }
            set {
                let fontNameToTest = self.font.fontName.lowercased()
                var fontName = newValue
                if fontNameToTest.range(of: "bold") != nil {
                    fontName += "-Bold"
                } else if fontNameToTest.range(of: "medium") != nil {
                    fontName += "-Medium"
                } else if fontNameToTest.range(of: "light") != nil {
                    fontName += "-Light"
                } else if fontNameToTest.range(of: "ultralight") != nil {
                    fontName += "-UltraLight"
                }
                self.font = UIFont(name: fontName, size: self.font.pointSize)
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-29 05:31

    I found out a way to do same in Swift 4 with iOS 11

    Only need to add @objc keyword before variable name. So variable declaration will be like this

    @objc public var substituteFontName : String {
        get {}
        set {}
    }
    

    Hope this helps others who are facing this issue.

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