iOS7:我们可以使用除动态类型的Helvetica Neue字体以外的其他字体吗?

tad*_*asz 10 fonts ios ios7

我们正在为iOS7设计一个应用程序,我们的设计师想要使用非默认字体(Avenir),但我不想放松动态类型功能.据我所知,动态类型只能与默认系统字体一起使用,即Helvetica Neue.是否可以使用其他字体或此时它不是一个选项?

vok*_*lam 16

据我所知,[UIFont preferredFontForTextStyle:]无论文本视图的默认大小如何,都会返回特定字体样式的固定大小的字体.我希望在"设置"中更改文字大小会将我的应用中的文字大小更改为某个增量而不是设置固定值.如iOS文本编程指南中所述,

用于由文本样式描述的目的的实际字体可以基于许多动态考虑因素而变化,包括用户的内容大小类别首选项,其由UIApplication属性preferredContentSizeCategory表示.

我注意到属性preferredContentSizeCategory在设置中响应设置文本大小而更改.

观察UIContentSizeCategoryDidChangeNotification也很重要,这样您就可以在用户更改内容大小类别时重新布局文本.当您的应用收到该通知时,它应该将invalidateIntrinsicContentSize消息发送到由Auto Layout定位的视图,或者将setNeedsLayout发送到手动定位的用户界面元素.它应该使首选字体或字体描述符无效并根据需要获取新字体.

因此,我的想法是观察适当的通知,根据preferredContentSizeCategory属性计算大小增量并将delta应用于文本视图的默认字体大小(在IB中设置或以编程方式设置).


PreferredFontLabel.h

@interface PreferredFontLabel : UILabel

@property (nonatomic) UIFontDescriptor *defaultFontDescriptor;

@end
Run Code Online (Sandbox Code Playgroud)

PreferredFontLabel.m

#import "PreferredFontLabel.h"
#import "UIApplication+ContentSize.h"

@implementation PreferredFontLabel

- (id)init
{
    self = [super init];
    if (self) {
        [self setup];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.defaultFontDescriptor = self.font.fontDescriptor;

    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(contentSizeCategoryDidChange)
     name:UIContentSizeCategoryDidChangeNotification
     object:nil];

    [self contentSizeCategoryDidChange];
}

- (void)setDefaultFontDescriptor:(UIFontDescriptor *)defaultFontDescriptor
{
    _defaultFontDescriptor = defaultFontDescriptor;

    [self contentSizeCategoryDidChange];
}

- (void)contentSizeCategoryDidChange
{
    CGFloat preferredSize = [self.defaultFontDescriptor.fontAttributes[UIFontDescriptorSizeAttribute] floatValue];
    preferredSize += [UIApplication sharedApplication].contentSizeDelta;

    self.font = [UIFont fontWithDescriptor:self.defaultFontDescriptor size:preferredSize];
    [self invalidateIntrinsicContentSize];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil];
}

@end
Run Code Online (Sandbox Code Playgroud)

UIApplication的+ ContentSize.h

@interface UIApplication (ContentSize)

@property (nonatomic, readonly) NSInteger contentSizeDelta;

@end
Run Code Online (Sandbox Code Playgroud)

UIApplication的+ ContentSize.m

#import "UIApplication+ContentSize.h"

@implementation UIApplication (ContentSize)

- (NSInteger)contentSizeDelta
{
    static NSArray *contentSizeCategories;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        contentSizeCategories = @[UIContentSizeCategoryExtraSmall,
                                  UIContentSizeCategorySmall,
                                  UIContentSizeCategoryMedium,
                                  UIContentSizeCategoryLarge,
                                  UIContentSizeCategoryExtraLarge,
                                  UIContentSizeCategoryExtraExtraLarge,
                                  UIContentSizeCategoryExtraExtraExtraLarge
                                  UIContentSizeCategoryAccessibilityMedium,
                                  UIContentSizeCategoryAccessibilityLarge,
                                  UIContentSizeCategoryAccessibilityExtraLarge,
                                  UIContentSizeCategoryAccessibilityExtraExtraLarge,
                                  UIContentSizeCategoryAccessibilityExtraExtraExtraLarge];
    });

    // assume UIContentSizeCategoryLarge is default category
    NSInteger contentSizeDelta = [contentSizeCategories indexOfObject:self.preferredContentSizeCategory];

    if(contentSizeDelta != NSNotFound) {
        contentSizeDelta -= [contentSizeCategories indexOfObject:UIContentSizeCategoryLarge];

        return contentSizeDelta;
    } else {
        return 0;
    }
}

@end
Run Code Online (Sandbox Code Playgroud)

我添加了属性字符串支持,在GitHub上提供了demo