如何不通过Attributed String禁用iOS自定义字体的连字效果?
iOS 禁用自定义字体连字(无需全量改用Attributed String)
如果你不想把所有文本都改成Attributed String,有几个更高效的方案可以解决自定义字体的连字问题:
1. 封装禁用连字的自定义字体方法
通过UIFontDescriptor给字体添加禁用连字的属性,封装成工具方法后,直接替换原来的字体调用即可,不用修改文本组件的类型:
import UIKit extension UIFont { static func customFontWithoutLigatures(name: String, size: CGFloat) -> UIFont? { guard let baseDescriptor = UIFontDescriptor(name: name, size: size) else { return UIFont.systemFont(ofSize: size) } // 添加禁用连字的特征设置 let noLigaturesAttributes: [UIFontDescriptor.AttributeName: Any] = [ .featureSettings: [ [ UIFontDescriptor.FeatureKey.featureIdentifier: kLigaturesType, UIFontDescriptor.FeatureKey.typeIdentifier: kCommonLigaturesOffSelector ] ] ] let modifiedDescriptor = baseDescriptor.addingAttributes(noLigaturesAttributes) return UIFont(descriptor: modifiedDescriptor, size: size) } }
用法
原来你用:
label.font = UIFont(name: "YourCustomFont", size: 17)
现在替换成:
label.font = UIFont.customFontWithoutLigatures(name: "YourCustomFont", size: 17)
2. 全局设置组件默认字体
如果你的应用大部分文本都用同一个自定义字体,可以通过UIKit的外观代理(Appearance)全局设置组件的默认字体为上面封装的禁用连字版本,一次性搞定所有同类型组件:
// 在App启动时(比如AppDelegate的application(_:didFinishLaunchingWithOptions:)或SceneDelegate的scene(_:willConnectTo:options:)中) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 设置UILabel默认字体 if let defaultFont = UIFont.customFontWithoutLigatures(name: "YourCustomFont", size: UILabel.appearance().font.pointSize) { UILabel.appearance().font = defaultFont } // 同理可设置UITextField、UITextView等 if let textFieldFont = UIFont.customFontWithoutLigatures(name: "YourCustomFont", size: UITextField.appearance().font?.pointSize ?? 17) { UITextField.appearance().font = textFieldFont } return true }
3. SwiftUI 全局Modifier
如果是SwiftUI项目,可以自定义一个View Modifier,快速给Text添加禁用连字的属性:
import SwiftUI struct DisableLigaturesModifier: ViewModifier { var fontName: String var size: CGFloat func body(content: Content) -> some View { content .font( Font.custom(fontName, size: size) .fontDescriptor( .init().addingAttributes([ .featureSettings: [ [ UIFontDescriptor.FeatureKey.featureIdentifier: kLigaturesType, UIFontDescriptor.FeatureKey.typeIdentifier: kCommonLigaturesOffSelector ] ] ]) ) ) } } extension View { func disableLigatures(fontName: String, size: CGFloat) -> some View { self.modifier(DisableLigaturesModifier(fontName: fontName, size: size)) } }
用法
Text("Your Text With Ligatures") .disableLigatures(fontName: "YourCustomFont", size: 17)
这些方案都不需要全量替换成Attributed String,通过修改字体本身的属性或者全局配置,就能批量解决连字问题,大幅减少修改成本。
内容的提问来源于stack exchange,提问作者Alexander Popov
相关产品推荐
相关产品推荐

