私は2つの方法を試しました:
_label.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.body)
label.adjustsFontForContentSizeCategory = true
_
これは正常に機能します。設定で優先テキストサイズを変更した場合でも、アプリに戻る前であっても、テキストサイズは自動的に変更されます。 しかしシステムフォント(サンフランシスコ)でのみ機能します。
カスタムフォントを使用するには、UIFontDescriptor
に拡張子を追加します。
_//from this answer http://stackoverflow.com/a/35467158/2907715
extension UIFontDescriptor {
private struct SubStruct {
static var preferredFontName: String = "Avenir-medium"
}
static let fontSizeTable : NSDictionary = [
UIFontTextStyle.headline: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 23,
UIContentSizeCategory.accessibilityExtraExtraLarge: 23,
UIContentSizeCategory.accessibilityExtraLarge: 23,
UIContentSizeCategory.accessibilityLarge: 23,
UIContentSizeCategory.accessibilityMedium: 23,
UIContentSizeCategory.extraExtraExtraLarge: 23,
UIContentSizeCategory.extraExtraLarge: 21,
UIContentSizeCategory.extraLarge: 19,
UIContentSizeCategory.large: 17,
UIContentSizeCategory.medium: 16,
UIContentSizeCategory.small: 15,
UIContentSizeCategory.extraSmall: 14
],
UIFontTextStyle.subheadline: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 21,
UIContentSizeCategory.accessibilityExtraExtraLarge: 21,
UIContentSizeCategory.accessibilityExtraLarge: 21,
UIContentSizeCategory.accessibilityLarge: 21,
UIContentSizeCategory.accessibilityMedium: 21,
UIContentSizeCategory.extraExtraExtraLarge: 21,
UIContentSizeCategory.extraExtraLarge: 19,
UIContentSizeCategory.extraLarge: 17,
UIContentSizeCategory.large: 15,
UIContentSizeCategory.medium: 14,
UIContentSizeCategory.small: 13,
UIContentSizeCategory.extraSmall: 12
],
UIFontTextStyle.body: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 53,
UIContentSizeCategory.accessibilityExtraExtraLarge: 47,
UIContentSizeCategory.accessibilityExtraLarge: 40,
UIContentSizeCategory.accessibilityLarge: 33,
UIContentSizeCategory.accessibilityMedium: 28,
UIContentSizeCategory.extraExtraExtraLarge: 23,
UIContentSizeCategory.extraExtraLarge: 21,
UIContentSizeCategory.extraLarge: 19,
UIContentSizeCategory.large: 17,
UIContentSizeCategory.medium: 16,
UIContentSizeCategory.small: 15,
UIContentSizeCategory.extraSmall: 14
],
UIFontTextStyle.caption1: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 18,
UIContentSizeCategory.accessibilityExtraExtraLarge: 18,
UIContentSizeCategory.accessibilityExtraLarge: 18,
UIContentSizeCategory.accessibilityLarge: 18,
UIContentSizeCategory.accessibilityMedium: 18,
UIContentSizeCategory.extraExtraExtraLarge: 18,
UIContentSizeCategory.extraExtraLarge: 16,
UIContentSizeCategory.extraLarge: 14,
UIContentSizeCategory.large: 12,
UIContentSizeCategory.medium: 11,
UIContentSizeCategory.small: 11,
UIContentSizeCategory.extraSmall: 11
],
UIFontTextStyle.caption2: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 17,
UIContentSizeCategory.accessibilityExtraExtraLarge: 17,
UIContentSizeCategory.accessibilityExtraLarge: 17,
UIContentSizeCategory.accessibilityLarge: 17,
UIContentSizeCategory.accessibilityMedium: 17,
UIContentSizeCategory.extraExtraExtraLarge: 17,
UIContentSizeCategory.extraExtraLarge: 15,
UIContentSizeCategory.extraLarge: 13,
UIContentSizeCategory.large: 11,
UIContentSizeCategory.medium: 11,
UIContentSizeCategory.small: 11,
UIContentSizeCategory.extraSmall: 11
],
UIFontTextStyle.footnote: [
UIContentSizeCategory.accessibilityExtraExtraExtraLarge: 19,
UIContentSizeCategory.accessibilityExtraExtraLarge: 19,
UIContentSizeCategory.accessibilityExtraLarge: 19,
UIContentSizeCategory.accessibilityLarge: 19,
UIContentSizeCategory.accessibilityMedium: 19,
UIContentSizeCategory.extraExtraExtraLarge: 19,
UIContentSizeCategory.extraExtraLarge: 17,
UIContentSizeCategory.extraLarge: 15,
UIContentSizeCategory.large: 13,
UIContentSizeCategory.medium: 12,
UIContentSizeCategory.small: 12,
UIContentSizeCategory.extraSmall: 12
],
]
final class func preferredDescriptor(textStyle: String) -> UIFontDescriptor {
let contentSize = UIApplication.shared.preferredContentSizeCategory
let style = fontSizeTable[textStyle] as! NSDictionary
return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
}
}
_
およびviewDidLoad()
:
_label.font = UIFont(descriptor: UIFontDescriptor.preferredDescriptor(textStyle: UIFontTextStyle.body.rawValue), size: 0)
NotificationCenter.default.addObserver(self, selector:#selector(self.userChangedTextSize(notification:)), name: NSNotification.Name.UIContentSizeCategoryDidChange, object: nil)
_
これがuserChangedTextSize
関数です。
_func userChangedTextSize(notification: NSNotification) {
label.font = UIFont(descriptor: UIFontDescriptor.preferredDescriptor(textStyle: UIFontTextStyle.body.rawValue), size: 0)
}
_
問題この方法では、ユーザーがアプリに戻るまでテキストサイズが変更されないため、ユーザーは古いテキストサイズが新しいサイズに変更されます。これは理想的ではありません。 。
バックグラウンドで自動的にサイズが変わるカスタムフォントという、両方の長所を利用できますか?
この方法の問題は、ユーザーがアプリに戻るまでテキストサイズが変更されないことです。その後、ユーザーは古いテキストサイズが新しいサイズに変更されるのを確認しますが、これは理想的ではありません。
これはおそらくより良いUXになるだろうというあなたの考えを共有しますが、あなたはそれを少し考えすぎていると思います。
システムが提供するアプリ(連絡先など)を見ると、ユーザーがアプリに戻るまで更新は行われませんであることがはっきりとわかります。
ちなみに、Swift 3:のためにコードを少しリファクタリングすることができます。
extension UIFontDescriptor {
private struct SubStruct {
static var preferredFontName: String = "Avenir-medium"
}
static let fontSizeTable: [UIFontTextStyle: [UIContentSizeCategory: CGFloat]] = [
.headline: [
.accessibilityExtraExtraExtraLarge: 23,
.accessibilityExtraExtraLarge: 23,
.accessibilityExtraLarge: 23,
.accessibilityLarge: 23,
.accessibilityMedium: 23,
.extraExtraExtraLarge: 23,
.extraExtraLarge: 21,
.extraLarge: 19,
.large: 17,
.medium: 16,
.small: 15,
.extraSmall: 14
],
.subheadline: [
.accessibilityExtraExtraExtraLarge: 21,
.accessibilityExtraExtraLarge: 21,
.accessibilityExtraLarge: 21,
.accessibilityLarge: 21,
.accessibilityMedium: 21,
.extraExtraExtraLarge: 21,
.extraExtraLarge: 19,
.extraLarge: 17,
.large: 15,
.medium: 14,
.small: 13,
.extraSmall: 12
],
.body: [
.accessibilityExtraExtraExtraLarge: 53,
.accessibilityExtraExtraLarge: 47,
.accessibilityExtraLarge: 40,
.accessibilityLarge: 33,
.accessibilityMedium: 28,
.extraExtraExtraLarge: 23,
.extraExtraLarge: 21,
.extraLarge: 19,
.large: 17,
.medium: 16,
.small: 15,
.extraSmall: 14
],
.caption1: [
.accessibilityExtraExtraExtraLarge: 18,
.accessibilityExtraExtraLarge: 18,
.accessibilityExtraLarge: 18,
.accessibilityLarge: 18,
.accessibilityMedium: 18,
.extraExtraExtraLarge: 18,
.extraExtraLarge: 16,
.extraLarge: 14,
.large: 12,
.medium: 11,
.small: 11,
.extraSmall: 11
],
.caption2: [
.accessibilityExtraExtraExtraLarge: 17,
.accessibilityExtraExtraLarge: 17,
.accessibilityExtraLarge: 17,
.accessibilityLarge: 17,
.accessibilityMedium: 17,
.extraExtraExtraLarge: 17,
.extraExtraLarge: 15,
.extraLarge: 13,
.large: 11,
.medium: 11,
.small: 11,
.extraSmall: 11
],
.footnote: [
.accessibilityExtraExtraExtraLarge: 19,
.accessibilityExtraExtraLarge: 19,
.accessibilityExtraLarge: 19,
.accessibilityLarge: 19,
.accessibilityMedium: 19,
.extraExtraExtraLarge: 19,
.extraExtraLarge: 17,
.extraLarge: 15,
.large: 13,
.medium: 12,
.small: 12,
.extraSmall: 12
]
]
final class func preferredDescriptor(textStyle: UIFontTextStyle) -> UIFontDescriptor {
let contentSize = UIApplication.shared.preferredContentSizeCategory
let style = fontSizeTable[textStyle]!
return UIFontDescriptor(name: SubStruct.preferredFontName, size: style[contentSize]!)
}
}
NSDictionary
またはNSNumber
にキャストして、間接的にfloatValue
を取得する必要はありません。
このようにして、コールサイトは次のより読みやすいコードを使用できます。
func userChangedTextSize(notification: NSNotification) {
label.font = UIFont(descriptor: .preferredDescriptor(textStyle: .body), size: 0)
}
編集:私は今同じことに取り組んでいるので、上記を(SO一般的に見られる解決策で)もっと簡単なものに改善しました。
import UIKIt
extension UIFont {
private struct CustomFont {
static var fontFamily = "Avenir"
}
/// Returns a bold version of `self`
public var bolded: UIFont {
return fontDescriptor.withSymbolicTraits(.traitBold)
.map { UIFont(descriptor: $0, size: 0) } ?? self
}
/// Returns an italic version of `self`
public var italicized: UIFont {
return fontDescriptor.withSymbolicTraits(.traitItalic)
.map { UIFont(descriptor: $0, size: 0) } ?? self
}
/// Returns a scaled version of `self`
func scaled(scaleFactor: CGFloat) -> UIFont {
let newDescriptor = fontDescriptor.withSize(fontDescriptor.pointSize * scaleFactor)
return UIFont(descriptor: newDescriptor, size: 0)
}
class func preferredCustomFont(forTextStyle textStyle: UIFontTextStyle) -> UIFont {
// we are using the UIFontDescriptor which is less expensive than creating an intermediate UIFont
let systemFontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle)
let customFontDescriptor = UIFontDescriptor.init(fontAttributes: [
UIFontDescriptorFamilyAttribute: CustomFont.fontFamily,
UIFontDescriptorSizeAttribute: systemFontDescriptor.pointSize // use the font size of the default dynamic font
])
// return font of new family with same size as the preferred system font
return UIFont(descriptor: customFontDescriptor, size: 0)
}
}
使用法
func userChangedTextSize(notification: NSNotification) {
label.font = UIFont.preferredCustomFont(forTextStyle: .headline)
// or in Bold / Italic:
// label.font = UIFont.preferredCustomFont(forTextStyle: .headline).bolded
// label.font = UIFont.preferredCustomFont(forTextStyle: .headline).italicized
}
Swift 4:アクセシビリティをサポートするカスタムスケーリングされたフォント(ドイツ語BITV)
//UIFont+CustomScaledFont.Swift
import UIKit
extension UIFont {
/// Scaled and styled version of any custom Font
///
/// - Parameters:
/// - name: Name of the Font
/// - textStyle: The text style i.e Body, Title, ...
/// - Returns: The scaled custom Font version with the given textStyle
static func scaledFont(name:String, textStyle: UIFont.TextStyle) -> UIFont {
let fontDescriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: textStyle)
guard let customFont = UIFont(name: name, size: fontDescriptor.pointSize) else {
fatalError("Failed to load the \(name) font.")
}
return UIFontMetrics.default.scaledFont(for: customFont)
}
}
プロジェクトにカスタムフォントを正常に追加した後...
使用可能なフォント名を印刷します:
for family in UIFont.familyNames {
for name in UIFont.fontNames(forFamilyName: family) {
print(name)
}
}
設定例:
myLabel.text = "My scaled custom Font"
myLabel.font = UIFont.scaledFont(name: "MyCustomFontName-Bold", textStyle: .title1)
myLabel.adjustsFontForContentSizeCategory = true
アクセシビリティインスペクター(MacOS)でテストする