为整个 iOS 应用程序 swift 使用自定义字体
Using custom font for entire iOS app swift
我知道要在屏幕上设置元素的自定义字体我可以简单地做到someLabel.font=UIFont(name: "Exo 2.0", size: 15)
。
我想知道如何使用 swift 为整个应用程序设置它。 (一个 hack 是对应用程序的每个元素执行我所知道的操作,但这将成为可维护性的噩梦)
我看到这个问题已经用 objective-C 标签问过,How to set a custom font for entire iOS app without specifying size 但我对 objective-C 不够熟悉,无法将代码移植到 swift
您可以设置 UILabel 和其他 UIView 的外观:
UILabel.appearance().font = UIFont(name: "yourFont", size: yourSize)
更一般:
AnyUIView.appearance().font = UIFont(name: "yourFont", size: yourSize)
作为更详细的答案和这些好处,我建议使用扩展:
- 无大小覆盖(无论您在设计器中设置什么都会被使用)
- 无样式覆盖(我的代码中实现了粗体、浅体、中体、超细体,但您可以根据需要自定义)
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)
}
}
}
使用扩展的示例:
例如将这些行放在您的起始控制器 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。正如@Christian 提到的,您几乎可以为 AnyUIView
编写自己的扩展
我在 Swift 4 和 iOS 11
中找到了相同的方法
只需要在变量名前加上@objc
关键字即可。
所以变量声明会像这样
@objc public var substituteFontName : String {
get {}
set {}
}
希望这对面临此问题的其他人有所帮助。
终于想通了。我能找到的最干净的方法。 (Swift 4)
解决方案不需要您设置字体大小,也不会覆盖所有字体大小。
UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFontTextStyle(rawValue: "Roboto"))
对于寻找此代码放置位置的用户。我把它放在我的 AppDelegate.swift 文件里面
func application(_ application: UIApplication,
didFinishLaunchingWithOptions...
Swift 4.2
UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle(rawValue: "Roboto"))
答案是已经提供的答案的组合,但我必须尝试组合才能让它在 iOS 13 中工作:
这一切都放在 Table View Controller 中,它符合 UIFontPickerViewControllerDelegate 以便为用户提供选择字体的视图。
这将使用新字体更新所有 UILabel,但保留其他属性。
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)
}
}
}
我知道要在屏幕上设置元素的自定义字体我可以简单地做到someLabel.font=UIFont(name: "Exo 2.0", size: 15)
。
我想知道如何使用 swift 为整个应用程序设置它。 (一个 hack 是对应用程序的每个元素执行我所知道的操作,但这将成为可维护性的噩梦)
我看到这个问题已经用 objective-C 标签问过,How to set a custom font for entire iOS app without specifying size 但我对 objective-C 不够熟悉,无法将代码移植到 swift
您可以设置 UILabel 和其他 UIView 的外观:
UILabel.appearance().font = UIFont(name: "yourFont", size: yourSize)
更一般:
AnyUIView.appearance().font = UIFont(name: "yourFont", size: yourSize)
作为更详细的答案和这些好处,我建议使用扩展:
- 无大小覆盖(无论您在设计器中设置什么都会被使用)
- 无样式覆盖(我的代码中实现了粗体、浅体、中体、超细体,但您可以根据需要自定义)
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)
}
}
}
使用扩展的示例:
例如将这些行放在您的起始控制器 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。正如@Christian 提到的,您几乎可以为 AnyUIView
编写自己的扩展我在 Swift 4 和 iOS 11
中找到了相同的方法只需要在变量名前加上@objc
关键字即可。
所以变量声明会像这样
@objc public var substituteFontName : String {
get {}
set {}
}
希望这对面临此问题的其他人有所帮助。
终于想通了。我能找到的最干净的方法。 (Swift 4) 解决方案不需要您设置字体大小,也不会覆盖所有字体大小。
UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFontTextStyle(rawValue: "Roboto"))
对于寻找此代码放置位置的用户。我把它放在我的 AppDelegate.swift 文件里面
func application(_ application: UIApplication,
didFinishLaunchingWithOptions...
Swift 4.2
UILabel.appearance().font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle(rawValue: "Roboto"))
答案是已经提供的答案的组合,但我必须尝试组合才能让它在 iOS 13 中工作:
这一切都放在 Table View Controller 中,它符合 UIFontPickerViewControllerDelegate 以便为用户提供选择字体的视图。 这将使用新字体更新所有 UILabel,但保留其他属性。
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)
}
}
}