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

时间:2013-09-12 07:36:17

标签: ios fonts ios7

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

2 个答案:

答案 0 :(得分:15)

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

  

用于文本样式描述的目的的实际字体可能会因许多动态注意事项而有所不同,包括用户的内容大小类别首选项,它由UIApplication属性preferredContentSizeCategory表示。

我注意到属性preferredContentSizeCategory会因设置中的文字大小而发生变化。

  

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

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


PreferredFontLabel.h

@interface PreferredFontLabel : UILabel

@property (nonatomic) UIFontDescriptor *defaultFontDescriptor;

@end

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

的UIApplication + ContentSize.h

@interface UIApplication (ContentSize)

@property (nonatomic, readonly) NSInteger contentSizeDelta;

@end

的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

我添加了属性字符串支持,演示可在GitHub

上找到

答案 1 :(得分:0)

自定义字体的示例。

https://github.com/jszumski/dynamic-type

请参阅 @implementation UIFont (AvenirContentSize)

了解如何调整字体以匹配默认尺寸