在Swift 3中,我使用以下内容替换AppDelegate中BOLD到MEDIUM中的所有字体:
UILabel.appearance().substituteFontNameBold = "HelveticaNeue-Medium"
将此扩展名添加到UILabel:
extension UILabel {
var substituteFontNameBold : String {
get { return self.font.fontName }
set {
if self.font.fontName.contains("Bold") {
self.font = UIFont(name: newValue, size: self.font.pointSize)
}
}
}
}
升级到Swift 4后,我收到了“ 致命错误:在展开可选值 时意外发现nil
if self.font.fontName.contains("Bold") {
如何使用Swift 4继续将BOLD中的所有字体替换为标签?
答案 0 :(得分:4)
Swift 4.0
这将帮助您为所有UILabel,UIButton等设置自定义字体。只需创建一个扩展名并替换为此。
var appFontName = "Gudea" //Please put your REGULAR font name
var appFontBoldName = "Gudea" //Please put your BOLD font name
var appFontItalicName = "Gudea" //Please put your ITALIC font name
extension UIFont {
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: appFontName, size: size)!
}
@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: appFontBoldName, size: size)!
}
@objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: appFontItalicName, size: size)!
}
@objc convenience init(myCoder aDecoder: NSCoder) {
if let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor {
if let fontAttribute = fontDescriptor.fontAttributes[UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")] as? String {
var fontName = ""
switch fontAttribute {
case "CTFontRegularUsage":
fontName = appFontName
case "CTFontEmphasizedUsage", "CTFontBoldUsage":
fontName = appFontBoldName
case "CTFontObliqueUsage":
fontName = appFontItalicName
default:
fontName = appFontName
}
self.init(name: fontName, size: fontDescriptor.pointSize)!
}
else {
self.init(myCoder: aDecoder)
}
}
else {
self.init(myCoder: aDecoder)
}
}
class func overrideInitialize() {
if self == UIFont.self {
let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:)))
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!)
let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:)))
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
method_exchangeImplementations(boldSystemFontMethod!, myBoldSystemFontMethod!)
let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:)))
let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:)))
method_exchangeImplementations(italicSystemFontMethod!, myItalicSystemFontMethod!)
let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))) // Trick to get over the lack of UIFont.init(coder:))
let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:)))
method_exchangeImplementations(initCoderMethod!, myInitCoderMethod!)
}
}
}
更新:Swift3.2
替换此行:
if let fontAttribute = fontDescriptor.fontAttributes[UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")] as? String {
使用:
if let fontAttribute = fontDescriptor.fontAttributes["NSCTFontUIUsageAttribute"] as? String {
答案 1 :(得分:3)
我找到了解决这个问题的方法,你基本上必须添加@objc
才能使其正常工作,添加后不再有nil值
@objc public var substituteFontName : String
答案 2 :(得分:1)
这可以通过覆盖系统字体来完成,如下所示:
import UIKit
struct AppFontName {
static let regular = "DINNextLTArabic-Regular"
}
extension UIFontDescriptor.AttributeName {
static let nsctFontUIUsage =
UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}
extension UIFont {
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
return UIFont(name: AppFontName.regular, size: size)!
}
@objc convenience init(myCoder aDecoder: NSCoder) {
if let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor {
let fontName = AppFontName.regular
self.init(name: fontName, size: fontDescriptor.pointSize)!
} else {
self.init(myCoder: aDecoder)
}
}
class func overrideInitialize() {
if self == UIFont.self {
let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:)))
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!)
let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))) // Trick to get over the lack of UIFont.init(coder:))
let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:)))
method_exchangeImplementations(initCoderMethod!, myInitCoderMethod!)
}
}
}
和appDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
UIFont.overrideInitialize()
return true
}