2017-09-25 32 views
2

在夫特3當前字體重量,我用下面的替換所有字體在BOLD到中等的AppDelegate:改變所有的UILabel字體中的應用取決於使用夫特4

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) 
      } 
     } 
    } 
} 

通過升級到斯威夫特4,我得到一個「致命錯誤:意外發現零而展開的可選值」上

if self.font.fontName.contains("Bold") { 

如何繼續使用Swift 4替換BOLD到MEDIUM中的所有字體?

+0

大概'self'(的UILabel)是零在這一點上。嘗試在後期調用它。 – jonaszmclaren

+0

出於某種原因,某些答案以及我對這些答案的答覆被刪除(​​oO?): 該人建議用UILabel.appearance()替換自己:這不能解決問題。 – cro

+0

基於桑迪查普曼的回答:https://stackoverflow.com/a/28440649/5778002 完全在斯威夫特3上工作。 在迅速4:self.font返回零 – cro

回答

1

我發現這樣做的修復,你基本上要添加@objc,使其工作,加入後,沒有更多的零值

@objc public var substituteFontName : String 
1

雨燕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 { 
+0

海拉酷!謝謝隊友 – Danyl

+0

無論如何,阻止自己== UIFont.self {}是無用的。 – Danyl

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 
} 
+0

感謝您的幫助。無論如何,阻止自己== UIFont.self {}是無用的。 – Danyl