Як використовувати власний шрифт з динамічними розмірами тексту в iOS7


88

В iOS7 є нові API для отримання шрифту, який автоматично підлаштовується під розмір тексту, який користувач встановив у своїх уподобаннях.

Виглядає приблизно так, щоб використовувати його:

UIFont *myFont = [UIFont fontWithDescriptor:[UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size:0];

Тепер будь-який текст, якому ви призначите це, буде переміщуватися вгору та вниз за розміром шрифту, коли користувач змінює налаштування системного розміру тексту. (Не забудьте прослухати name:UIContentSizeCategoryDidChangeNotificationповідомлення та оновити свій вигляд, щоб врахувати зміну розміру).

Як використовувати динамічний текст із шрифтом, відмінним від Helvetica-Neue за замовчуванням?


Чи не пора вам прийняти відповідь?
Khanh Nguyen

Починаючи з ios-11 +, Apple надає підтримку користувацьким динамічним розмірам шрифтів. Для реалізації, будь ласка, подивіться на цю відповідь .
Умайр Алі

Відповіді:


132

За лаштунками цього API, apple має якусь таблицю підстановки, яка повертає певне сімейство шрифтів, розмір та іноді символічні риси (наприклад, напівжирний шрифт), які (наприклад UIFontTextStyleHeadline) та бажаний розмір тексту користувача. Останній - це рядок, вирваний приблизно sharedApplicationтак:

[UIApplication sharedApplication].preferredContentSizeCategory;

(Я вийшов із усіх розмірів / шрифтів / властивостей за замовчуванням для Helvetica-Neue для різних динамічних розмірів тексту). З тих пір ми додали обробку для розмірів доступності, що важливо .

Отже, все, що вам насправді потрібно зробити, це побудувати подібну таблицю пошуку. Наш дизайнер створив для мене просту електронну таблицю:

Таблиця пошуку розміру шрифту

Зверніть увагу, що ми додали пару стилів (підписи 3 та 4), щоб мати на вибір 8 замість 6.

Тоді вам захочеться поставити це десь зручно, наприклад, категорію UIFontDescriptor. Ви хочете, щоб ваш метод повернув UIFontDescriptorподібний API Apple, так що його все ще легко налаштувати за допомогою символічних рис тощо.

Моя категорія виглядає так:

UIFontDescriptor + AvenirNext.h

#import <UIKit/UIKit.h>

extern NSString *const ANUIFontTextStyleCaption3;

@interface UIFontDescriptor (AvenirNext)

+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style;

@end

UIFontDescriptor + AvenirNext.m

#import "UIFontDescriptor+AvenirNext.h"

NSString *const ANUIFontTextStyleCaption3 = @"ANUIFontTextStyleCaption3";
NSString *const ANUIFontTextStyleCaption4 = @"ANUIFontTextStyleCaption4";

@implementation UIFontDescriptor (AvenirNext)
+(UIFontDescriptor *)preferredAvenirNextFontDescriptorWithTextStyle:(NSString *)style {
    static dispatch_once_t onceToken;
    static NSDictionary *fontSizeTable;
    dispatch_once(&onceToken, ^{
        fontSizeTable = @{
          UIFontTextStyleHeadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @26,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @25,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityLarge: @24,
                                    UIContentSizeCategoryAccessibilityMedium: @23,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @23,
                                    UIContentSizeCategoryExtraExtraLarge: @22,
                                    UIContentSizeCategoryExtraLarge: @21,
                                    UIContentSizeCategoryLarge: @20,
                                    UIContentSizeCategoryMedium: @19,
                                    UIContentSizeCategorySmall: @18,
                                    UIContentSizeCategoryExtraSmall: @17,},

       UIFontTextStyleSubheadline: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @24,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @23,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @22,
                                    UIContentSizeCategoryAccessibilityLarge: @22,
                                    UIContentSizeCategoryAccessibilityMedium: @21,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryExtraExtraLarge: @20,
                                    UIContentSizeCategoryExtraLarge: @19,
                                    UIContentSizeCategoryLarge: @18,
                                    UIContentSizeCategoryMedium: @17,
                                    UIContentSizeCategorySmall: @16,
                                    UIContentSizeCategoryExtraSmall: @15,},

              UIFontTextStyleBody: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @21,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @20,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityLarge: @19,
                                    UIContentSizeCategoryAccessibilityMedium: @18,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryExtraExtraLarge: @17,
                                    UIContentSizeCategoryExtraLarge: @16,
                                    UIContentSizeCategoryLarge: @15,
                                    UIContentSizeCategoryMedium: @14,
                                    UIContentSizeCategorySmall: @13,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption1: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @19,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityLarge: @17,
                                    UIContentSizeCategoryAccessibilityMedium: @16,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraExtraLarge: @16,
                                    UIContentSizeCategoryExtraLarge: @15,
                                    UIContentSizeCategoryLarge: @14,
                                    UIContentSizeCategoryMedium: @13,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @12,},
          
          UIFontTextStyleCaption2: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @18,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityLarge: @16,
                                    UIContentSizeCategoryAccessibilityMedium: @15,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraLarge: @14,
                                    UIContentSizeCategoryLarge: @13,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @12,
                                    UIContentSizeCategoryExtraSmall: @11,},
          
        ANUIFontTextStyleCaption3: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @17,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityLarge: @15,
                                    UIContentSizeCategoryAccessibilityMedium: @14,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @14,
                                    UIContentSizeCategoryExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @12,
                                    UIContentSizeCategoryMedium: @12,
                                    UIContentSizeCategorySmall: @11,
                                    UIContentSizeCategoryExtraSmall: @10,},

          UIFontTextStyleFootnote: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @16,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityLarge: @14,
                                    UIContentSizeCategoryAccessibilityMedium: @13,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @13,
                                    UIContentSizeCategoryExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraLarge: @12,
                                    UIContentSizeCategoryLarge: @11,
                                    UIContentSizeCategoryMedium: @11,
                                    UIContentSizeCategorySmall: @10,
                                    UIContentSizeCategoryExtraSmall: @10,},

          ANUIFontTextStyleCaption4: @{
                                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: @15,
                                    UIContentSizeCategoryAccessibilityExtraExtraLarge: @14,
                                    UIContentSizeCategoryAccessibilityExtraLarge: @13,
                                    UIContentSizeCategoryAccessibilityLarge: @13,
                                    UIContentSizeCategoryAccessibilityMedium: @12,
                                    UIContentSizeCategoryExtraExtraExtraLarge: @12,
                                    UIContentSizeCategoryExtraExtraLarge: @11,
                                    UIContentSizeCategoryExtraLarge: @11,
                                    UIContentSizeCategoryLarge: @10,
                                    UIContentSizeCategoryMedium: @10,
                                    UIContentSizeCategorySmall: @9,
                                    UIContentSizeCategoryExtraSmall: @9,},
        };
    });
    
    
    NSString *contentSize = [UIApplication sharedApplication].preferredContentSizeCategory;
    return [UIFontDescriptor fontDescriptorWithName:[self preferredFontName] size:((NSNumber *)fontSizeTable[style][contentSize]).floatValue];
}
+(UIFontDescriptor *)preferredAvenirNextDemiBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [[self preferredAvenirNextFontDescriptorWithTextStyle:style] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold];
}

+(UIFontDescriptor *)preferredAvenirNextBoldFontDescriptorWithTextStyle:(NSString *)style {
    return [UIFontDescriptor fontDescriptorWithName:[self preferredBoldFontName] size:[self preferredAvenirNextFontDescriptorWithTextStyle:style].pointSize];
}

+(NSString *)preferredFontName {
    return @"AvenirNext-Medium";
}
+(NSString *)preferredBoldFontName {
    return @"AvenirNext-Bold";
}

@end

Ми вирішили використовувати той самий базовий шрифт AvenirNext-Medium , а потім жирний і подібний через символічні риси, але ви можете зійти з розуму і вказати різні варіанти ваги для вашого шрифту як частину вашої таблиці пошуку, якщо хочете, наприклад AvenirNext-ExtraBold.

Це все! Ми використовуємо його так:

[UIFont fontWithDescriptor:[UIFontDescriptor preferredAvenirNextFontDescriptorWithTextStyle:UIFontTextStyleHeadline] size: 0]

6
Відмінне рішення, але ви втрачаєте константи доступності: UIContentSizeCategoryAccessibilityMedium, UIContentSizeCategoryAccessibilityLargeі т.д.
Бен Джексон

Ах цікаво. Корисно знати @BenJackson. Дякую!
Боб Спрін,

1
Чому б не розширити UIFont, щоб ви могли просто використовувати [UIFont preferredAvenirFontForTextStyle:UIFontTextStyleHeadline]:? Розмір зайвий у прикладі, який ви подаєте внизу?
cleverbit

2
@richarddas просто дотримуватися шаблону Apple. Розмір 0 ігнорується і просто проходить через правильний розмір з дескриптора.
Боб Спрін

4
Станом на iOS 8.4 Apple трохи змінила
Клаас,

15

Ось як я це роблю в Swift. Мені це подобається, оскільки це більш загально, для нього потрібна лише одна таблиця, і вона повинна добре працювати з будь-яким шрифтом. Спочатку я написав узагальнений множник (у геттері).

var fontSizeMultiplier : CGFloat {
    get {
        switch UIApplication.sharedApplication().preferredContentSizeCategory {
        case UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: return 23 / 16
        case UIContentSizeCategoryAccessibilityExtraExtraLarge: return 22 / 16
        case UIContentSizeCategoryAccessibilityExtraLarge: return 21 / 16
        case UIContentSizeCategoryAccessibilityLarge: return 20 / 16
        case UIContentSizeCategoryAccessibilityMedium: return 19 / 16
        case UIContentSizeCategoryExtraExtraExtraLarge: return 19 / 16
        case UIContentSizeCategoryExtraExtraLarge: return 18 / 16
        case UIContentSizeCategoryExtraLarge: return 17 / 16
        case UIContentSizeCategoryLarge: return 1.0
        case UIContentSizeCategoryMedium: return 15 / 16
        case UIContentSizeCategorySmall: return 14 / 16
        case UIContentSizeCategoryExtraSmall: return 13 / 16
        default: return 1.0
        }
    }
}

Потім я оновлюю шрифт (наприклад, у спостерігачі), використовуючи такий вигляд UIFontDescriptor:

textView.font = UIFont(descriptor: fontDescriptor!, size: fontDescriptor!.pointSize * fontSizeMultiplier)

Це не спрацює, оскільки pointSize збільшується в геометричній прогресії кожного разу, коли ви оновлюєте розмір у налаштуваннях. Якщо ви встановили розмір шрифту за замовчуванням, ви можете використовувати його як базовий і помножити на fontSizeMultiplier.
TejAces 01.03.18

@TejAces - Це добре працює. Я використовую його роками. Оскільки воно повертає буквальні значення, я не бачу, як, на вашу думку, воно збільшиться при зміні налаштувань.
Білл Вайнман,

12

В iOS 11 UIFontMetricsбув представлений клас. Створіть об’єкт FontMetrics для стилю тексту, який вас цікавить. Потім виберіть будь-який потрібний шрифт, розмір якого відповідає стандартному розміру динамічного типу. А потім ви можете попросити об'єкт FontMetrics масштабувати цей шрифт, враховуючи поточні налаштування користувача.

let bodyMetrics = UIFontMetrics(forTextStyle: .body)
let standardFont = ... // any font you want, for standard type size
let font = bodyMetrics.scaledFont(for: standardFont)

8

Код @Bob Spryn швидко переписаний:

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: NSString = "OEMeodedPashutPro-Regular"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 26,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 25,
                    UIContentSizeCategoryAccessibilityExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityLarge: 24,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 22,
                    UIContentSizeCategoryExtraLarge: 21,
                    UIContentSizeCategoryLarge: 20,
                    UIContentSizeCategoryMedium: 19,
                    UIContentSizeCategorySmall: 18,
                    UIContentSizeCategoryExtraSmall: 17
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 24,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 22,
                    UIContentSizeCategoryAccessibilityLarge: 22,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 20,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 18,
                    UIContentSizeCategoryMedium: 17,
                    UIContentSizeCategorySmall: 16,
                    UIContentSizeCategoryExtraSmall: 15
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 20,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 16,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 16,
                    UIContentSizeCategoryExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 14,
                    UIContentSizeCategoryMedium: 13,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityLarge: 16,
                    UIContentSizeCategoryAccessibilityMedium: 15,
                    UIContentSizeCategoryExtraExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraExtraLarge: 14,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 16,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 15,
                    UIContentSizeCategoryAccessibilityExtraLarge: 14,
                    UIContentSizeCategoryAccessibilityLarge: 14,
                    UIContentSizeCategoryAccessibilityMedium: 13,
                    UIContentSizeCategoryExtraExtraExtraLarge: 13,
                    UIContentSizeCategoryExtraExtraLarge: 12,
                    UIContentSizeCategoryExtraLarge: 12,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 10,
                    UIContentSizeCategoryExtraSmall: 10
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory

        let style = Static.fontSizeTable[textStyle] as NSDictionary

        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as NSNumber).floatValue))
    }

}

Використання:

UIFont(descriptor: UIFontDescriptor.preferredDescriptor(UIFontTextStyleBody), size: 0)

1
Xcode 7.2 змусив мене змінити два останні рядки на: let style = Static.fontSizeTable[textStyle] as! NSDictionaryтаreturn UIFontDescriptor(name: SubStruct.preferredFontName as String, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
koen

Було б дуже здорово, якби я міг зробити щось, що відображає бажаний шрифт у Storyboard. Можливо, підкласуючи елементи тексту.
Аарон Братчер,

7

Спробуйте це:

UIFontDescriptor *userHeadLineFont = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
CGFloat userHeadLineFontSize = [userHeadLineFont pointSize];
myFont = [UIFont fontWithName:@"Baskerville" size:userHeadLineFontSize];

Але майте на увазі, що цей код є лише наближенням (Dynamic Type робить набагато більше, ніж просто розмір шрифту).


Чи можете ви детальніше розповісти про парантез? Що більше, ніж масштабування, слід брати до уваги?
hfossli

2
Між шрифтом "динамічний тип" та шрифтом, який справді використовується, є відображення. Наприклад, маленький шрифт може стати жирним. Я не знаю точного відображення. Див. Останнє зображення ("оптичне масштабування динамічного типу") у цій статті: fireballed.org/linked/2013/07/08/ios-7-type, щоб краще зрозуміти.
valfer

1
Це робить те саме, що затверджена правильна відповідь, але якась різниця в кількості рядків. Чудове рішення. Те саме в SWIFT stackoverflow.com/questions/35355695/…
Ваня

Ось робоче посилання на статтю, згадану @valfer в коментарях: Beyond Helvetica: The Real Story Behind Fonts в iOS 7
0xced

6

Подібно до підходу @ bill-weinman , я взяв шкалу і розбив її на функцію, яка не покладається на заданий розмір шрифту 16.

/// The font scale for a given font size.
///
/// - seealso: [Source](https://stackoverflow.com/a/33114525/3643020)
///
/// - Parameter fontSize: The font size.
/// - Returns: The font scale
public func fontScale(for fontSize: CGFloat) -> CGFloat {
    switch UIApplication.shared.preferredContentSizeCategory {
    case UIContentSizeCategory.accessibilityExtraExtraExtraLarge:    return (fontSize + 8) / fontSize
    case UIContentSizeCategory.accessibilityExtraExtraLarge:         return (fontSize + 7) / fontSize
    case UIContentSizeCategory.accessibilityExtraLarge:              return (fontSize + 6) / fontSize
    case UIContentSizeCategory.accessibilityLarge:                   return (fontSize + 5) / fontSize
    case UIContentSizeCategory.accessibilityMedium:                  return (fontSize + 4) / fontSize
    case UIContentSizeCategory.extraExtraExtraLarge:                 return (fontSize + 3) / fontSize
    case UIContentSizeCategory.extraExtraLarge:                      return (fontSize + 2) / fontSize
    case UIContentSizeCategory.extraLarge:                           return (fontSize + 1) / fontSize
    case UIContentSizeCategory.large:                                return 1.0
    case UIContentSizeCategory.medium:                               return (fontSize - 1) / fontSize
    case UIContentSizeCategory.small:                                return (fontSize - 2) / fontSize
    case UIContentSizeCategory.extraSmall:                           return (fontSize - 3) / fontSize
    default:
        return 1.0
    }
}

Потім його можна використовувати із спеціальними шрифтами, як це:

/// Light font of specified size.
///
/// - Parameter size: Font size.
/// - Returns: Light font of specified size.
func lightFont(ofSize size: CGFloat) -> UIFont {
    let scaledSize = size * fontScale(for: size)

    return UIFont(name: "HelveticaNeueLTStd-Lt", size: scaledSize)!
}

Це непогано, якщо ви перебуваєте на етапі, коли ви не хочете все тонко налаштовувати. Також якщо ваш власний шрифт досить маленький і за замовчуванням потребує масштабування.
JanBrinker

FYI - мій підхід не покладається на розмір шрифту. Він повертає значення на основі співвідношення. Він чудово працює із спеціальними / масштабованими шрифтами.
Білл Вайнман,

3

У iOS 11 ви можете використовувати:

var customFont = UIFont.systemFont(ofSize: 17.0)
if #available(iOS 11.0, *) {
    customFont = UIFontMetrics.default.scaledFont(for: customFont)
}
// use customFont...

Див. Також Створення додатків з динамічним типом WWDC 2017 - сесія 245 - час iOS 8:34.


2

Код Swift 2.1-3.0 на основі порту @ smartDonkey коду @Bob Spryn. Також оновлено розмірами Apple від @Klaas .

import UIKit

extension UIFontDescriptor {

    private struct SubStruct {
        static var preferredFontName: String = "Roboto-Light"
    }

    class func preferredDescriptor(textStyle: NSString) -> UIFontDescriptor {
        struct Static {
            static var onceToken : dispatch_once_t = 0
            static var fontSizeTable : NSDictionary = NSDictionary()
        }

        dispatch_once(&Static.onceToken) {
            Static.fontSizeTable = [
                UIFontTextStyleHeadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityExtraLarge: 23,
                    UIContentSizeCategoryAccessibilityLarge: 23,
                    UIContentSizeCategoryAccessibilityMedium: 23,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleSubheadline: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityExtraLarge: 21,
                    UIContentSizeCategoryAccessibilityLarge: 21,
                    UIContentSizeCategoryAccessibilityMedium: 21,
                    UIContentSizeCategoryExtraExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraLarge: 17,
                    UIContentSizeCategoryLarge: 15,
                    UIContentSizeCategoryMedium: 14,
                    UIContentSizeCategorySmall: 13,
                    UIContentSizeCategoryExtraSmall: 12
                ],
                UIFontTextStyleBody: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 53,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 47,
                    UIContentSizeCategoryAccessibilityExtraLarge: 40,
                    UIContentSizeCategoryAccessibilityLarge: 33,
                    UIContentSizeCategoryAccessibilityMedium: 28,
                    UIContentSizeCategoryExtraExtraExtraLarge: 23,
                    UIContentSizeCategoryExtraExtraLarge: 21,
                    UIContentSizeCategoryExtraLarge: 19,
                    UIContentSizeCategoryLarge: 17,
                    UIContentSizeCategoryMedium: 16,
                    UIContentSizeCategorySmall: 15,
                    UIContentSizeCategoryExtraSmall: 14
                ],
                UIFontTextStyleCaption1: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityExtraLarge: 18,
                    UIContentSizeCategoryAccessibilityLarge: 18,
                    UIContentSizeCategoryAccessibilityMedium: 18,
                    UIContentSizeCategoryExtraExtraExtraLarge: 18,
                    UIContentSizeCategoryExtraExtraLarge: 16,
                    UIContentSizeCategoryExtraLarge: 14,
                    UIContentSizeCategoryLarge: 12,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleCaption2: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityExtraLarge: 17,
                    UIContentSizeCategoryAccessibilityLarge: 17,
                    UIContentSizeCategoryAccessibilityMedium: 17,
                    UIContentSizeCategoryExtraExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraExtraLarge: 15,
                    UIContentSizeCategoryExtraLarge: 13,
                    UIContentSizeCategoryLarge: 11,
                    UIContentSizeCategoryMedium: 11,
                    UIContentSizeCategorySmall: 11,
                    UIContentSizeCategoryExtraSmall: 11
                ],
                UIFontTextStyleFootnote: [
                    UIContentSizeCategoryAccessibilityExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityExtraLarge: 19,
                    UIContentSizeCategoryAccessibilityLarge: 19,
                    UIContentSizeCategoryAccessibilityMedium: 19,
                    UIContentSizeCategoryExtraExtraExtraLarge: 19,
                    UIContentSizeCategoryExtraExtraLarge: 17,
                    UIContentSizeCategoryExtraLarge: 15,
                    UIContentSizeCategoryLarge: 13,
                    UIContentSizeCategoryMedium: 12,
                    UIContentSizeCategorySmall: 12,
                    UIContentSizeCategoryExtraSmall: 12
                ],
            ]
        }

        let contentSize = UIApplication.sharedApplication().preferredContentSizeCategory
        let style = Static.fontSizeTable[textStyle] as! NSDictionary
        return UIFontDescriptor(name: SubStruct.preferredFontName, size: CGFloat((style[contentSize] as! NSNumber).floatValue))
    }

}

Помилки на Swift 3 з вашим рішенням:'dispatch_once_t' is unavailable in Swift: Use lazily initialized globals instead
thexande

2

Ось мій погляд на відповідь @ Gobe у Swift 3:

extension UIFontDescriptor {

@nonobjc static var fontSizeTable: [UIFontTextStyle : [UIContentSizeCategory : CGFloat]] = {
    return [
        .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],
    ]
}()

class func currentPreferredSize(textStyle: UIFontTextStyle = .body) -> CGFloat {
    let contentSize = UIApplication.shared.preferredContentSizeCategory
    guard let style = fontSizeTable[textStyle], let fontSize = style[contentSize] else { return 17 }
    return fontSize
}

class func preferredFontDescriptor(fontName: String = "SnellRoundhand", textStyle: UIFontTextStyle = .body) -> UIFontDescriptor {
    return UIFontDescriptor(name: fontName, size: currentPreferredSize())
}
}

Swift5 версія була додана stackoverflow.com/questions/41798080 / ...
marika.daboja

1

Ось як я оновлюю шрифт preferFontForTextStyle:

UIFont *font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
UIFontDescriptor *fontDesc = [font fontDescriptor];
fontDesc = [fontDesc fontDescriptorByAddingAttributes:@{UIFontDescriptorNameAttribute : @"Helvetica",
                                                        UIFontDescriptorSizeAttribute : @16}];

font = [UIFont fontWithDescriptor:fontDesc
                             size:[fontDesc pointSize]];

1

Просто хотів заскочити і сказати, що там є бібліотека, яка допоможе інтегрувати власні шрифти та мати справу зі змінами розміру динамічного типу. Він називається, корисно, Font ( https://github.com/adamyanalunas/Font ), і замість магічного рішення він створює структуру для обробки кожного користувацького шрифту по-різному, видаляючи шаблон.

nb Я автор цієї бібліотеки lil ', і я думаю, що вона акуратна.


0

Починаючи з iOS 11, ви можете програмно налаштувати власні шрифти, налаштовані у візуальному редакторі:

  1. Налаштуйте власний шрифт за допомогою візуального редактора
  2. Відрегулюйте розмір шрифту в методі viewDidLoad:
@IBOutlet weak var leftLangLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    leftLangLabel.font = UIFontMetrics.default.scaledFont(for: leftLangLabel.font)
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.