我们正在为 iOS7 设计一个应用程序,我们的设计师想要使用非默认字体(Avenir),但我不想失去动态类型功能。据我了解,动态类型只能与默认系统字体一起使用,即 Helvetica Neue。是否可以使用其他字体,或者此时它不是一个选项?
2 回答
据我了解[UIFont preferredFontForTextStyle:]
,无论文本视图默认大小如何,都会为特定字体样式返回具有固定大小的字体。我希望在“设置”中更改文本大小会将我的应用程序中的文本大小更改一些增量,而不是设置固定值。如iOS 文本编程指南中所述,
用于文本样式描述的目的的实际字体可能会根据许多动态考虑因素而有所不同,包括用户的内容大小类别首选项,它由 UIApplication 属性preferredContentSizeCategory 表示。
我注意到属性preferredContentSizeCategory
会随着在设置中设置文本大小而发生变化。
观察 UIContentSizeCategoryDidChangeNotification 也很重要,这样您就可以在用户更改内容大小类别时重新布局文本。当您的应用收到该通知时,它应该将 invalidateIntrinsicContentSize 消息发送到由 Auto Layout 定位的视图,或将 setNeedsLayout 发送到手动定位的用户界面元素。它应该使首选字体或字体描述符无效,并根据需要获取新的。
所以,我的想法是观察适当的通知,根据preferredContentSizeCategory
属性计算大小增量并将增量应用于文本视图的默认字体大小(在 IB 中或以编程方式设置)。
首选字体标签.h
@interface PreferredFontLabel : UILabel
@property (nonatomic) UIFontDescriptor *defaultFontDescriptor;
@end
首选字体标签.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上可用
使用自定义字体的示例。
https://github.com/jszumski/dynamic-type
看
@implementation UIFont (AvenirContentSize)
了解如何调整字体以匹配默认大小