为整个 iOS 应用程序设置默认字体?
Posted
技术标签:
【中文标题】为整个 iOS 应用程序设置默认字体?【英文标题】:Set a default font for whole iOS app? 【发布时间】:2012-02-01 04:28:46 【问题描述】:我有一个自定义字体,我想将其用于在我的应用程序、标签、文本视图等中显示文本的所有内容。
有没有办法为整个应用设置默认字体(标签默认使用 SystemFont)?
【问题讨论】:
对这种困境进行了大量调查。老实说,我们发现最简单的方法就是为每个控件创建一个(微不足道的)新类。所以对于 UIButton,制作 SJButton。不要忘记同时覆盖 initWithFrame 和 initWithCode。为每个控件(比如 UIButton 等)设置颜色或任何你喜欢的颜色。仔细选择 int 代码中的大小(即,这将是在故事板上设置的大小),然后(根据您的喜好)使用该大小(并设置,比如说,字体,颜色 - 随便什么)。它只有几行代码,非常整洁,从长远来看可以为您节省大量时间。 @JoeBlow 感谢您发布您的发现 - 正要花时间寻找自己的答案 @jj- 对。不要忘记,这些天你肯定必须使用IBDesignable
。希望能帮助到你。还可以考虑这个有趣的 QA:***.com/a/38000466/294884
【参考方案1】:
在 ios 5 中使用 UIAppearance 代理似乎是可能的。
[[UILabel appearance] setFont:[UIFont fontWithName:@"YourFontName" size:17.0]];
这会将字体设置为您应用中所有 UILabel 的自定义字体。您需要为每个控件(UIButton、UILabel 等)重复此操作。
请记住,您需要将 UIAppFonts 值放在 info.plist 中,并包含您要包含的字体的名称。
【讨论】:
感谢您的回复。我能够让它工作。你知道有没有办法在不指定字体大小的情况下指定字体?我的应用中有不同字体大小的标签。 我可以在不覆盖每个实例的磅值的情况下这样做吗?setFont:
方法已弃用
@Anand 你确定吗?我没有看到它在UILabel
中被标记为已弃用。 UIButton
已弃用它,但它使用titleLabel
属性的字体而不是UILabel
,因此只需使用UILabel
的外观代理设置字体就可以了。
@Anand 它不被 UILabel 弃用。【参考方案2】:
斯威夫特 5
根据 Fábio Oliveira 的回答 (https://***.com/a/23042694/2082851),我自己制作了 swift 4。
简而言之,这个扩展用我的自定义方法交换默认函数init(coder:)
、systemFont(ofSize:)
、boldSystemFont(ofSize:)
、italicSystemFont(ofSize:)
。
请注意,它没有完全实现,但您可以根据我的实现交换更多方法。
import UIKit
struct AppFontName
static let regular = "CourierNewPSMT"
static let bold = "CourierNewPS-BoldMT"
static let italic = "CourierNewPS-ItalicMT"
extension UIFontDescriptor.AttributeName
static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
extension UIFont
static var isOverrided: Bool = false
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: AppFontName.regular, size: size)!
@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: AppFontName.bold, size: size)!
@objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: AppFontName.italic, size: size)!
@objc convenience init(myCoder aDecoder: NSCoder)
guard
let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,
let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String else
self.init(myCoder: aDecoder)
return
var fontName = ""
switch fontAttribute
case "CTFontRegularUsage":
fontName = AppFontName.regular
case "CTFontEmphasizedUsage", "CTFontBoldUsage":
fontName = AppFontName.bold
case "CTFontObliqueUsage":
fontName = AppFontName.italic
default:
fontName = AppFontName.regular
self.init(name: fontName, size: fontDescriptor.pointSize)!
class func overrideInitialize()
guard self == UIFont.self, !isOverrided else return
// Avoid method swizzling run twice and revert to original initialize function
isOverrided = true
if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod, mySystemFontMethod)
if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)
if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),
let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:)))
method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)
if 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)
class AppDelegate: UIResponder, UIApplicationDelegate
// Avoid warning of Swift
// Method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions
override init()
super.init()
UIFont.overrideInitialize()
...
【讨论】:
最佳答案!!自动覆盖系统字体,绚丽 如果有人对“NSCTFontUIUsageAttribute”行有疑问:if let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String
为我解决了问题。
似乎不适用于设置文本样式(粗体、标题、标题等)的UILabel
s...仅适用于具有特定大小和系统字体集的字体。 @nahung89
这也会切换一些系统 UI 字体。例如,键盘建议列表和操作表。不知道这是否会导致苹果拒绝该应用
自发布此答案以来已经一年了。有没有人有更“原生”的 Apple 方式来实现这一目标?【参考方案3】:
还有另一个解决方案是覆盖 systemFont。
只需创建一个类别
UIFont+SystemFontOverride.h
#import <UIKit/UIKit.h>
@interface UIFont (SystemFontOverride)
@end
UIFont+SystemFontOverride.m
@implementation UIFont (SystemFontOverride)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize
return [UIFont fontWithName:@"fontName" size:fontSize];
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize
return [UIFont fontWithName:@"fontName" size:fontSize];
#pragma clang diagnostic pop
@end
这将替换默认实现,并且大多数 UIControls 使用 systemFont。
【讨论】:
这符合苹果指南吗? 这更像是一种黑客行为。我没有使用这个 hack 添加我的应用程序注册,因为它没有使用任何私有方法。如果你想要一个更强大的解决方案,我也建议你检查一下:github.com/0xced/FontReplacer 这很好。 Apple 只是不希望您使用未记录的功能。您可以“混搭”公开的方法。 当一个类别的方法与它所扩展的类具有相同的签名时,行为是未定义的。要替换类方法,您应该使用方法调配(这也不是一个好主意)。 正如其他人指出的那样,这种解决方案虽然在大多数情况下可能有效,但在技术上会引入未定义行为的可能性。如果您不想冒险,那么方法调配可能是一个更好的选择。这里的答案通过 swizzling 提供了相同的解决方案:***.com/questions/19542942/…【参考方案4】:如果你使用 Swift,你可以创建一个 UILabel 扩展:
extension UILabel
@objc var substituteFontName : String
get return self.font.fontName
set self.font = UIFont(name: newValue, size: self.font.pointSize)
然后你在哪里进行外观代理:
UILabel.appearance().substituteFontName = applicationFont
在名称为 substituteFontName
的属性上使用 UI_APPEARANCE_SELECTOR
的等效 Objective-C 代码。
加法
如果您想分别设置粗体和常规字体:
extension UILabel
@objc var substituteFontName : String
get return self.font.fontName
set
if self.font.fontName.range(of:"Medium") == nil
self.font = UIFont(name: newValue, size: self.font.pointSize)
@objc var substituteFontNameBold : String
get return self.font.fontName
set
if self.font.fontName.range(of:"Medium") != nil
self.font = UIFont(name: newValue, size: self.font.pointSize)
然后为您的 UIAppearance 代理:
UILabel.appearance().substituteFontName = applicationFont
UILabel.appearance().substituteFontNameBold = applicationFontBold
注意:如果您发现粗体替换不起作用,则默认字体名称可能不包含“中”。根据需要切换该字符串以进行另一场比赛(感谢下面 cmets 中的 Mason)。
【讨论】:
我发现的一个缺点是,当我使用 UIAlertController 启动警报时,具有 .Cancel 样式的按钮与具有 .Default 样式的按钮相同(至少在使用 GillSans 时) )。而通常 .Cancel 将是常规粗细字体,而 .Default 将是粗体。有什么想法吗? 对不起,我的意思是 .Cancel 标签通常是粗体,而 Default 通常是常规重量。 @MasonG.Zhwiti 在这种情况下,我可能会设置UILabel
扩展来为粗体添加一个额外的字体名称。然后在set
中检查字体名称中是否有“粗体”,并在一种情况下忽略该设置,并在另一种情况下使用它。我将编辑并添加一个示例。
@SandyChapman 谢谢!我正在尝试这种新技术,这很有意义,但它似乎对我不起作用。我在 iOS 8.3 模拟器上使用 GillSans 和 GillSans-Bold。你测试过这种技术吗?
@SandyChapman 我知道发生了什么。 iOS 8 的默认字体往往是 HelveticaNeueInterface-Regular 或(粗体)HelveticaNeueInterface-MediumP4。因此,寻找“Bold”永远不会匹配任何东西。我将其更改为 rangeOfString("Medium")
并且有效。【参考方案5】:
从 Hugues BR 的答案中开发,但使用调配方法,我已经找到了一个解决方案,可以成功地将我的应用程序中的所有字体更改为所需的字体。
动态类型的方法应该是您应该在 iOS 7 上寻找的方法。以下解决方案不使用动态类型。
注意事项:
以下代码在其呈现状态下从未提交给 Apple 批准; 有一个较短的版本通过了 Apple 提交,即没有- initWithCoder:
覆盖。但是,这并不能涵盖所有情况;
以下代码存在于我用来设置我的应用程序样式的类中,该类包含在我的 AppDelegate 类中,因此可用于任何地方和所有 UIFont 实例;
我在这里使用 Zapfino 只是为了使更改更加明显;
欢迎您对此代码进行任何改进。
此解决方案使用两种不同的方法来实现最终结果。第一个是覆盖 UIFont 类方法 + systemFontWithSize:
并且与使用我的替代方法的方法类似(这里我使用“Zapfino”来确保替换成功)。
另一种方法是覆盖 UIFont 上的 - initWithCoder:
方法,以用我的替代方法替换任何出现的 CTFontRegularUsage
和类似的。
最后一种方法是必要的,因为我发现在 NIB 文件中编码的 UILabel
对象不会检查 + systemFontWithSize:
方法来获取它们的系统字体,而是将它们编码为 UICTFontDescriptor
对象。
我试图覆盖- awakeAfterUsingCoder:
,但不知何故,它被我的故事板中的每个编码对象调用并导致崩溃。覆盖- awakeFromNib
不允许我读取NSCoder
对象。
#import <objc/runtime.h>
NSString *const FORegularFontName = @"Zapfino";
NSString *const FOBoldFontName = @"Zapfino";
NSString *const FOItalicFontName = @"Zapfino";
#pragma mark - UIFont category
@implementation UIFont (CustomFonts)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+ (void)replaceClassSelector:(SEL)originalSelector withSelector:(SEL)modifiedSelector
Method originalMethod = class_getClassMethod(self, originalSelector);
Method modifiedMethod = class_getClassMethod(self, modifiedSelector);
method_exchangeImplementations(originalMethod, modifiedMethod);
+ (void)replaceInstanceSelector:(SEL)originalSelector withSelector:(SEL)modifiedSelector
Method originalDecoderMethod = class_getInstanceMethod(self, originalSelector);
Method modifiedDecoderMethod = class_getInstanceMethod(self, modifiedSelector);
method_exchangeImplementations(originalDecoderMethod, modifiedDecoderMethod);
+ (UIFont *)regularFontWithSize:(CGFloat)size
return [UIFont fontWithName:FORegularFontName size:size];
+ (UIFont *)boldFontWithSize:(CGFloat)size
return [UIFont fontWithName:FOBoldFontName size:size];
+ (UIFont *)italicFontOfSize:(CGFloat)fontSize
return [UIFont fontWithName:FOItalicFontName size:fontSize];
- (id)initCustomWithCoder:(NSCoder *)aDecoder
BOOL result = [aDecoder containsValueForKey:@"UIFontDescriptor"];
if (result)
UIFontDescriptor *descriptor = [aDecoder decodeObjectForKey:@"UIFontDescriptor"];
NSString *fontName;
if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontRegularUsage"])
fontName = FORegularFontName;
else if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontEmphasizedUsage"])
fontName = FOBoldFontName;
else if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontObliqueUsage"])
fontName = FOItalicFontName;
else
fontName = descriptor.fontAttributes[@"NSFontNameAttribute"];
return [UIFont fontWithName:fontName size:descriptor.pointSize];
self = [self initCustomWithCoder:aDecoder];
return self;
+ (void)load
[self replaceClassSelector:@selector(systemFontOfSize:) withSelector:@selector(regularFontWithSize:)];
[self replaceClassSelector:@selector(boldSystemFontOfSize:) withSelector:@selector(boldFontWithSize:)];
[self replaceClassSelector:@selector(italicSystemFontOfSize:) withSelector:@selector(italicFontOfSize:)];
[self replaceInstanceSelector:@selector(initWithCoder:) withSelector:@selector(initCustomWithCoder:)];
#pragma clang diagnostic pop
@end
【讨论】:
你如何在没有 UIFontDescriptor 的 iOS6 上使用这个实现 我使用解码器键“UIFontTraits”来检查提供的字体是粗体还是斜体,并用我自己的变体替换它。从这里的要点得到它gist.github.com/Daij-Djan/5046612。 感谢您的回答,我现在使用了另一种解决方案。当我再次需要它时,我会检查它:) 感谢@FábioOliveira,它就像一个魅力!您还需要将 #importUIAlertController
) 不会改变字体。【参考方案6】:
要完成Sandy Chapman's answer,这里有一个Objective-C 中的解决方案(把这个类别放在任何你想改变的地方UILabel
Appearance
):
@implementation UILabel (FontOverride)
- (void)setSubstituteFontName:(NSString *)name UI_APPEARANCE_SELECTOR
self.font = [UIFont fontWithName:name size:self.font.pointSize];
@end
接口文件,应该公开声明这个方法,以便以后在你的应用委托等地方使用:
@interface UILabel (FontOverride)
- (void)setSubstituteFontName:(NSString *)name UI_APPEARANCE_SELECTOR;
@end
然后,您可以将Appearance
更改为:
[[UILabel appearance] setSubstituteFontName:@"SourceSansPro-Light"];
【讨论】:
您好,您的意思是“任何地方”,必须在每个视图控制器中添加该代码,并且在您希望更改字体的控制器中使用每个 UILabel? 不,你必须把这段代码一次放在你项目的任何地方;例如在您的 appdelegate 中。 @DamienDebin 我想将粗体字体用于粗体,但这会将粗体变为浅色。有办法吗? 其实可以,但是应该是“Category”还是“Extension”呢?这里解释的区别:***.com/questions/7136124/…【参考方案7】:在查看了几篇帖子后,我为 Swift 4 创建了自己的字体转换,它涵盖了大多数情况,例如:
1st 将字体添加到项目结构和 .plist 文件(同名):
<key>UIAppFonts</key>
<array>
<string>Typo-Light.ttf</string>
<string>Typo-Regular.ttf</string>
<string>Typo-Semibold.ttf</string>
<string>Typo-LightItalic.ttf</string>
</array>
然后
struct Resources
struct Fonts
//struct is extended in Fonts
extension Resources.Fonts
enum Weight: String
case light = "Typo-Light"
case regular = "Typo-Regular"
case semibold = "Typo-Semibold"
case italic = "Typo-LightItalic"
extension UIFontDescriptor.AttributeName
static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
extension UIFont
@objc class func mySystemFont(ofSize: CGFloat, weight: UIFont.Weight) -> UIFont
switch weight
case .semibold, .bold, .heavy, .black:
return UIFont(name: Resources.Fonts.Weight.semibold.rawValue, size: ofSize)!
case .medium, .regular:
return UIFont(name: Resources.Fonts.Weight.regular.rawValue, size: ofSize)!
default:
return UIFont(name: Resources.Fonts.Weight.light.rawValue, size: ofSize)!
@objc class func mySystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: Resources.Fonts.Weight.light.rawValue, size: size)!
@objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: Resources.Fonts.Weight.semibold.rawValue, size: size)!
@objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont
return UIFont(name: Resources.Fonts.Weight.italic.rawValue, size: size)!
@objc convenience init(myCoder aDecoder: NSCoder)
guard
let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,
let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String else
self.init(myCoder: aDecoder)
return
var fontName = ""
switch fontAttribute
case "CTFontRegularUsage", "CTFontMediumUsage":
fontName = Resources.Fonts.Weight.regular.rawValue
case "CTFontEmphasizedUsage", "CTFontBoldUsage", "CTFontSemiboldUsage","CTFontHeavyUsage", "CTFontBlackUsage":
fontName = Resources.Fonts.Weight.semibold.rawValue
case "CTFontObliqueUsage":
fontName = Resources.Fonts.Weight.italic.rawValue
default:
fontName = Resources.Fonts.Weight.light.rawValue
self.init(name: fontName, size: fontDescriptor.pointSize)!
class func overrideDefaultTypography()
guard self == UIFont.self else return
if let systemFontMethodWithWeight = class_getClassMethod(self, #selector(systemFont(ofSize: weight:))),
let mySystemFontMethodWithWeight = class_getClassMethod(self, #selector(mySystemFont(ofSize: weight:)))
method_exchangeImplementations(systemFontMethodWithWeight, mySystemFontMethodWithWeight)
if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod, mySystemFontMethod)
if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)
if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),
let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:)))
method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)
if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))),
let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:)))
method_exchangeImplementations(initCoderMethod, myInitCoderMethod)
最后在Appdelegate
调用创建的方法,如下:
class AppDelegate: UIResponder, UIApplicationDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool
UIFont.overrideDefaultTypography()
return true
【讨论】:
@sheshnath 你能给我们更多的崩溃信息吗? 对不起,错误是我这边的,info.plist中没有列出字体 @midhunp 你能更明确一点,这样它对你不起作用吗?粗体字很适合我。【参考方案8】:对 SWIFT 3.0 和 SWIFT 警告的评论
您可以删除行中的警告消息:
let initCoderMethod = class_getInstanceMethod(self, Selector("initWithCoder:"))
将其替换为:
let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:)))
【讨论】:
大声笑。我不知道 Swift 允许使用它。顺便说一句,我会将其更新为上述答案。谢谢@ucotta!【参考方案9】:对于 Swift 5
以上所有答案都是正确的,但我以根据设备尺寸的方式做了一些不同的事情。 在这里,在 ATFontManager 类中,我将默认字体大小设置为在类的顶部定义为 defaultFontSize,这是字体大小 iphone plus,你可以根据你的要求进行更改。
class ATFontManager: UIFont
class func setFont( _ iPhone7PlusFontSize: CGFloat? = nil,andFontName fontN : String = FontName.helveticaNeue) -> UIFont
let defaultFontSize : CGFloat = 16
switch ATDeviceDetector().screenType
case .iPhone4:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize - 5)!
return UIFont(name: fontN, size: defaultFontSize - 5)!
case .iPhone5:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize - 3)!
return UIFont(name: fontN, size: defaultFontSize - 3)!
case .iPhone6AndIphone7, .iPhoneUnknownSmallSize:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize - 2)!
return UIFont(name: fontN, size: defaultFontSize - 2)!
case .iPhone6PAndIPhone7P, .iPhoneUnknownBigSize:
return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!
case .iPhoneX, .iPhoneXsMax:
return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!
case .iPadMini:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize + 2)!
return UIFont(name: fontN, size: defaultFontSize + 2)!
case .iPadPro10Inch:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize + 4)!
return UIFont(name: fontN, size: defaultFontSize + 4)!
case .iPadPro:
if let fontSize = iPhone7PlusFontSize
return UIFont(name: fontN, size: fontSize + 6)!
return UIFont(name: fontN, size: defaultFontSize + 6)!
case .iPadUnknownSmallSize:
return UIFont(name: fontN, size: defaultFontSize + 2)!
case .iPadUnknownBigSize:
return UIFont(name: fontN, size: defaultFontSize + 4)!
default:
return UIFont(name: fontN, size: iPhone7PlusFontSize ?? 16)!
我已经添加了某些字体名称,更多您可以添加字体名称并在此处输入。
enum FontName : String
case HelveticaNeue = "HelveticaNeue"
case HelveticaNeueUltraLight = "HelveticaNeue-UltraLight"
case HelveticaNeueBold = "HelveticaNeue-Bold"
case HelveticaNeueBoldItalic = "HelveticaNeue-BoldItalic"
case HelveticaNeueMedium = "HelveticaNeue-Medium"
case AvenirBlack = "Avenir-Black"
case ArialBoldMT = "Arial-BoldMT"
case HoeflerTextBlack = "HoeflerText-Black"
case AMCAPEternal = "AMCAPEternal"
该类引用设备检测器,以便根据设备提供适当的字体大小。
class ATDeviceDetector
var iPhone: Bool
return UIDevice().userInterfaceIdiom == .phone
var ipad : Bool
return UIDevice().userInterfaceIdiom == .pad
let isRetina = UIScreen.main.scale >= 2.0
enum ScreenType: String
case iPhone4
case iPhone5
case iPhone6AndIphone7
case iPhone6PAndIPhone7P
case iPhoneX
case iPadMini
case iPadPro
case iPadPro10Inch
case iPhoneOrIPadSmallSizeUnknown
case iPadUnknown
case unknown
struct ScreenSize
static let SCREEN_WIDTH = UIScreen.main.bounds.size.width
static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH,ScreenSize.SCREEN_HEIGHT)
static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH,ScreenSize.SCREEN_HEIGHT)
var screenType: ScreenType
switch ScreenSize.SCREEN_MAX_LENGTH
case 0..<568.0:
return .iPhone4
case 568.0:
return .iPhone5
case 667.0:
return .iPhone6AndIphone7
case 736.0:
return .iPhone6PAndIPhone7P
case 812.0:
return .iPhoneX
case 568.0..<812.0:
return .iPhoneOrIPadSmallSizeUnknown
case 1112.0:
return .iPadPro10Inch
case 1024.0:
return .iPadMini
case 1366.0:
return .iPadPro
case 812.0..<1366.0:
return .iPadUnknown
default:
return .unknown
如何使用。希望对你有所帮助。
//for default
label.font = ATFontManager.setFont()
//if you want to provide as your demand. Here **iPhone7PlusFontSize** variable is denoted as font size for *iphone 7plus and iphone 6 plus*, and it **ATFontManager** class automatically handle.
label.font = ATFontManager.setFont(iPhone7PlusFontSize: 15, andFontName: FontName.HelveticaNeue.rawValue)
【讨论】:
【参考方案10】:这些解决方案都不能在整个应用中通用。我发现有助于在 Xcode 中管理字体的一件事是将情节提要作为源代码打开(在文件导航器中按住 Control 单击情节提要>“打开为”>“源”),然后执行查找和替换。
【讨论】:
【参考方案11】:字体类型始终在代码和 nib/storyboard 中设置。
对于代码,就像Hugues BR said一样,在分类中做可以解决问题。
对于 nib/storyboard,我们可以通过方法 Swizzling awakeFromNib 来更改字体类型,因为 nib/storyboard 中的 UI 元素总是在屏幕上显示之前调用它。
我想你知道Aspects。它是一个基于 Method Swizzling 的 AOP 编程库。 我们为UILabel、UIButton、UITextView创建分类来实现它。
UILabel:
#import "UILabel+OverrideBaseFont.h"
#import "Aspects.h"
@implementation UILabel (OverrideBaseFont)
+ (void)load
[[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo)
UILabel* instance = [aspectInfo instance];
UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
instance.font = font;
error:nil];
@end
用户界面按钮:
#import "UIButton+OverrideBaseFont.h"
#import "Aspects.h"
@implementation UIButton (OverrideBaseFont)
+ (void)load
[[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo)
UIButton* instance = [aspectInfo instance];
UILabel* label = instance.titleLabel;
UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:label.font.pointSize];
instance.titleLabel.font = font;
error:nil];
@end
UITextField:
#import "UITextField+OverrideBaseFont.h"
#import "Aspects.h"
@implementation UITextField (OverrideBaseFont)
+ (void)load
[[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo)
UITextField* instance = [aspectInfo instance];
UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
instance.font = font;
error:nil];
@end
UITextView:
#import "UITextView+OverrideBaseFont.h"
#import "Aspects.h"
@implementation UITextView (OverrideBaseFont)
+ (void)load
[[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo)
UITextView* instance = [aspectInfo instance];
UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
instance.font = font;
error:nil];
@end
就是这样,您可以将 HelveticaNeue-light 更改为带有您的字体名称的宏。
【讨论】:
【参考方案12】:可能不会,您可能会自己在控件上设置字体,但您可以通过集中获取字体类型的位置来简化流程,例如让应用程序委托或其他一些公共类有一个方法返回字体,任何需要设置字体的东西都可以调用该方法,这将在您需要更改字体时有所帮助,您可以在一个地方而不是在您设置字体的任何地方进行更改...另一种选择可以是制作 UI 元素的子类,它们会自动设置字体,但这可能是矫枉过正..
【讨论】:
作为记录,这就是我所做的,但@Randall 需要代表,并提供了一个很好的答案。我只需要支持不到5.0 我不同意你的做法。当您的问题被标记为 iphone-sdk-4.0 时,您选择的答案无效。 @Sam Jarman,Randall 在下面的回答是正确的 - 你可以为未来的访客标记它吗?【参考方案13】:对于 AppDelegate 的 FinishedLaunching()
中的 Xamarin.iOS,将代码如下:-
UILabel.Appearance.Font= UIFont.FromName("Lato-Regular", 14);
为整个应用程序设置字体并在 Info.plist 上添加“UIAppFonts
”键,路径应该是字体文件 .ttf 所在的路径。对我来说,它位于我项目的“字体”文件夹中。
<key>UIAppFonts</key>
<array>
<string>fonts/Lato-Regular.ttf</string>
</array>
【讨论】:
这行得通,但没有用 - 因为现在你的应用程序中的所有文本都是相同的 14 大小......可能没有办法覆盖它以使其具有原始元素字体大小【参考方案14】:正如@Randall 在他的answer 中提到的iOS 5.0+ UIAppearance
代理可用于自定义类read more 的所有实例的外观。
UILabel.appearance().font = .systemFont(ofSize: 17, weight: .regular)
【讨论】:
【参考方案15】:NUI 是 UIAppearance 代理的替代方案。它使您可以通过简单地修改样式表来控制整个应用程序中大量 UI 元素类型的字体(和许多其他属性),该样式表可以在多个应用程序中重复使用。
在标签中添加NUILabel
类后,您可以轻松地在样式表中控制它们的字体:
LabelFontName String Helvetica
如果您有不同字体大小的标签,您可以使用 NUI 的 Label、LargeLabel 和 SmallLabel 类来控制它们的大小,甚至可以快速创建自己的类。
【讨论】:
【参考方案16】:我在swift中使用这种类型的字体类。使用字体扩展类。
enum FontName: String
case regular = "Roboto-Regular"
//MARK: - Set Font Size
enum FontSize: CGFloat
case size = 10
extension UIFont
//MARK: - Bold Font
class var regularFont10: UIFont
return UIFont(name: FontName.regular.rawValue, size:FontSize.size.rawValue )!
【讨论】:
【参考方案17】:我们在 Swift -Xcode 7.2 中使用父视图控制器和子视图控制器(继承)实现了相同的目标。
文件 - 新建 - Cocoa Touch 类 - ParentViewController。
import UIKit
import Foundation
class ParentViewController: UIViewController
var appUIColor:UIColor = UIColor.redColor()
var appFont:UIFont = UIFont(name: "Copperplate", size: 20)!
override func viewDidLoad()
super.viewDidLoad()
func addStatusBar()
let view = UIView(frame:
CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0)
)
view.backgroundColor = appUIColor
self.view.addSubview(view)
制作子视图控制器并与 StoryBoard VC 关联,添加 textLabel。
import UIKit
class FontTestController: ParentViewController
@IBOutlet var testLabel: UILabel!
override func viewDidLoad()
super.viewDidLoad()
testLabel.font = appFont
testLabel.textColor = appUIColor
或者创建一个自定义的 UILabel 类(子分类方法)并将所需的标签关联到它。
import Foundation
import UIKit
class CustomFontLabel: UILabel
required init(coder aDecoder: NSCoder)
super.init(coder: aDecoder)!
backgroundColor = ParentViewController().appUIColor
font = ParentViewController().appFont
textColor = UIColor.blackColor()
注意:在 Parent VC 中声明的字体和颜色在 CustomFontLabel 中实现。优点是我们可以在 Parent VC 中进行一些简单的更改,同时更改 uilabel/any view 的属性。
2)'for' 为子视图循环 UIView。它仅适用于特定的 VC。
override func viewWillLayoutSubviews()
for view in self.view.subviews
if view.isKindOfClass(UITextField)
UITextField.appearance().font = UIFont(name: "Copperplate", size: 20)
if view.isKindOfClass(UILabel)
UILabel.appearance().font = UIFont(name: "Copperplate", size: 20)
【讨论】:
以上是关于为整个 iOS 应用程序设置默认字体?的主要内容,如果未能解决你的问题,请参考以下文章
Android:想要为整个应用程序而不是运行时设置自定义字体