TextKit学习(一)可以调整字体大小的FontResizeDemo
2013-09-30 09:26
281 查看
昨天看完了苹果官方的IntroduceToTextKit这个Demo,了解了有关TextKit的一些新特性,TextKit的出现的确使得文字的处理变得更加便利和多功能化。个人觉得最有趣的是ExclusionPath这个部分。
之后参照这个Demo我写了FontResizeDemo,顾名思义就是当用户在Settings的Text Size中调整字体大小时,本程序的字体相应地做出调整。
先说说Xcode 5-DP2的一些使用感想:
1.操作便利性没有改进:
在iOS7之前,如果在程序中导入新的框架,必须在Building Phases中的Link Binary with Libraries选项中手动添加对应的框架文件,这种方式的确非常麻烦。Xcode 5则解决了手动添加的麻烦,只需要在代码中添加就可以直接使用。所以在WWDC2013中的关于Obj-C新特性的视频中,说完这一特性以后可以清楚听到下面的鼓掌欢呼声。
但是,昨天使用Xcode 5才发现,为了在自己新建的类中使用框架等文件时,必须要在Building Phases中的Compile Sources中手动添加类文件,如果不这么做(即使在类文件中导入了<UIKit/UIKit.h>),最明显的结果就是在写代码时如UIView这样的名词都不会显示代码高亮状态。同样地,如果要使用外部资源中的内容(如book.txt电子书中的内容),也必须手动在Copy Bundle Resources中添加这些资源文件。如果不这样做,那么在程序运行时如果使用了资源中的内容(如在控制台输出电子书中的内容),内容将返回结果null。添加文件后入下图所示:
这样比较下来,必须手动在编译源(Compile Sources)和资源(Bundle Resources)中添加文件,整个开发过程将变得更加麻烦。
2.iOS7 Simulator存在问题
如果使用iOS7模拟器反复调试或退出模拟器重新run一遍,将发现程序在运行开始时卡住,即使在Debug area中点击continue也没有作用。必须关闭程序重新打开工程文件才能在模拟器中正常运行程序。不知道是模拟器存在bug还是我没找对调试的方法。
另外i7模拟器的外观也放弃了i6模拟器的iPhone外观,在明显的就是Home键没有了,要按Home键只能按Command+Shift+H快捷键或者在模拟器的硬件菜单中选择。如果要打开后台,必须连续按两次Command+Shift+H快捷键。在模拟器的使用上,个人觉得还是iOS6的使用更为便利。
回到Demo中来。这个Demo我只写了一个FontResizeViewController类,下面来看看该类的实现文件:
[cpp] view
plaincopy
#import "FontResizeViewController.h"
#import "UITextView+TextKitDemo.h"
#import "UIFont+TextKitDemo.h"
#import "UIFontDescriptor+TextKitDemo.h"
@interface FontResizeViewController ()
@property (nonatomic, strong) NSMutableAttributedString *content; // 文本内容
@end
@implementation FontResizeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 30.0, 320.0, 520.0)];
[self.view addSubview:self.textView];
NSURL *url = nil;
// url = [[NSBundle mainBundle] URLForResource:@"Basic Interaction.rtf" withExtension:nil];
url = [[NSBundle mainBundle] URLForResource:@"book.txt" withExtension:nil];
NSMutableAttributedString *attributedTextHolder = [[NSMutableAttributedString alloc] initWithFileURL:url options:@{} documentAttributes:nil error:nil];
[attributedTextHolder addAttribute:NSFontAttributeName value:[UIFont preferredFontForTextStyle:UIFontTextStyleBody] range:NSMakeRange(0, attributedTextHolder.length)];
// NSLog(@"%@", attributedTextHolder);
self.content = [attributedTextHolder copy];
self.textView.attributedText = self.content;
self.textView.editable = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; // 当不同类别的字体大小发生变化时发送消息给self
}
-(void)preferredContentSizeChanged:(NSNotification *)noti
{
static const CGFloat textScaleFactor = .8;
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
self.textView.font = font;
}
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
非常简单,关键就是在控制器中添加一个事件观察者来接收消息:
[cpp] view
plaincopy
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; // 当不同类别的字体大小发生变化时发送消息给self
另外要注意的是如果以self.content = @"abcdefghijklmnopqrstuvwxyz"的方式简单初始化self.content的内容,那么在调整完文字大小回到程序时self.content的内容可能已经被回收,可以看到文字内容显示为空。因此在将self.content赋值给self.textView.attributedText前,self.content必须要retain一次,也就是self.content必须要以init或者copy等方式获得:
[cpp] view
plaincopy
NSURL *url = nil;
// url = [[NSBundle mainBundle] URLForResource:@"Basic Interaction.rtf" withExtension:nil];
url = [[NSBundle mainBundle] URLForResource:@"book.txt" withExtension:nil];
NSMutableAttributedString *attributedTextHolder = [[NSMutableAttributedString alloc] initWithFileURL:url options:@{} documentAttributes:nil error:nil];
[attributedTextHolder addAttribute:NSFontAttributeName value:[UIFont preferredFontForTextStyle:UIFontTextStyleBody] range:NSMakeRange(0, attributedTextHolder.length)];
// NSLog(@"%@", attributedTextHolder);
self.content = [attributedTextHolder copy];
必须重写viewDidUnload和dealloc方法来移除事件观察者:
[cpp] view
plaincopy
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
重点看看收到消息后调整字体大小的方法:
[cpp] view
plaincopy
-(void)preferredContentSizeChanged:(NSNotification *)noti
{
static const CGFloat textScaleFactor = .8;
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
self.textView.font = font;
}
在这里用到的tkd_textStyle和tkd_preferredFontWithTextStyle:scale:是调整字体样式和大小关键。在这里使用了IntroduceTextKitDemo中的Categories中的类别和方法:
下面来看看取得字体样式的整个流程:
(1)在FontResizeViewController.m中调用UITextView类别的tkd_textStyle方法。
[cpp] view
plaincopy
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
(2)在UITextView+TextKitDemo.m中的tkd_textStyle方法调用UIFont类别的tkd_textStyle方法。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self.font tkd_textStyle];
}
(3)在UIFont+TextKitDemo.m中的tkd_textStyle方法中调用UIFontDecsriptor类别的tkd_textStyle方法。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self.fontDescriptor tkd_textStyle];
}
(4)在UIFontDescriptor+TextKitDemo.m的tkd_textStyle方法中回调字体样式结果。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self objectForKey:@"NSCTFontUIUsageAttribute"];
}
在设置后字体样式后调用tkd_preferredFontWithTextStyle:scale:方法来设置字体,textStyle的参数使用了以上获得的tkd_textStyle,scale的参数则使用了textScaleFactor。整个方法的工作流程是相似的:
(1)FontResizeViewController.m
[cpp] view
plaincopy
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
(2)UIFont+TextKitDemo.m
[cpp] view
plaincopy
+ (UIFont *)tkd_preferredFontWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
{
UIFontDescriptor *newFontDescriptor = [UIFontDescriptor tkd_preferredFontDescriptorWithTextStyle:aTextStyle scale:aScale];
return [UIFont fontWithDescriptor:newFontDescriptor size:newFontDescriptor.pointSize];
}
(3)UIFontDescriptor+TextKitDemo.m
[cpp] view
plaincopy
+ (UIFontDescriptor *)tkd_preferredFontDescriptorWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
{
UIFontDescriptor *newBaseDescriptor = [self preferredFontDescriptorWithTextStyle:aTextStyle];
return [newBaseDescriptor fontDescriptorWithSize:lrint([newBaseDescriptor pointSize] * aScale)];
}
这就是整个程序的工作过程,主要还是参照和使用了IntroduceToTextKit这个Demo。
最后看看程序运行结果:
调整字体前:
调整Text Size到最大:
调整后的文本:
之后参照这个Demo我写了FontResizeDemo,顾名思义就是当用户在Settings的Text Size中调整字体大小时,本程序的字体相应地做出调整。
先说说Xcode 5-DP2的一些使用感想:
1.操作便利性没有改进:
在iOS7之前,如果在程序中导入新的框架,必须在Building Phases中的Link Binary with Libraries选项中手动添加对应的框架文件,这种方式的确非常麻烦。Xcode 5则解决了手动添加的麻烦,只需要在代码中添加就可以直接使用。所以在WWDC2013中的关于Obj-C新特性的视频中,说完这一特性以后可以清楚听到下面的鼓掌欢呼声。
但是,昨天使用Xcode 5才发现,为了在自己新建的类中使用框架等文件时,必须要在Building Phases中的Compile Sources中手动添加类文件,如果不这么做(即使在类文件中导入了<UIKit/UIKit.h>),最明显的结果就是在写代码时如UIView这样的名词都不会显示代码高亮状态。同样地,如果要使用外部资源中的内容(如book.txt电子书中的内容),也必须手动在Copy Bundle Resources中添加这些资源文件。如果不这样做,那么在程序运行时如果使用了资源中的内容(如在控制台输出电子书中的内容),内容将返回结果null。添加文件后入下图所示:
这样比较下来,必须手动在编译源(Compile Sources)和资源(Bundle Resources)中添加文件,整个开发过程将变得更加麻烦。
2.iOS7 Simulator存在问题
如果使用iOS7模拟器反复调试或退出模拟器重新run一遍,将发现程序在运行开始时卡住,即使在Debug area中点击continue也没有作用。必须关闭程序重新打开工程文件才能在模拟器中正常运行程序。不知道是模拟器存在bug还是我没找对调试的方法。
另外i7模拟器的外观也放弃了i6模拟器的iPhone外观,在明显的就是Home键没有了,要按Home键只能按Command+Shift+H快捷键或者在模拟器的硬件菜单中选择。如果要打开后台,必须连续按两次Command+Shift+H快捷键。在模拟器的使用上,个人觉得还是iOS6的使用更为便利。
回到Demo中来。这个Demo我只写了一个FontResizeViewController类,下面来看看该类的实现文件:
[cpp] view
plaincopy
#import "FontResizeViewController.h"
#import "UITextView+TextKitDemo.h"
#import "UIFont+TextKitDemo.h"
#import "UIFontDescriptor+TextKitDemo.h"
@interface FontResizeViewController ()
@property (nonatomic, strong) NSMutableAttributedString *content; // 文本内容
@end
@implementation FontResizeViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 30.0, 320.0, 520.0)];
[self.view addSubview:self.textView];
NSURL *url = nil;
// url = [[NSBundle mainBundle] URLForResource:@"Basic Interaction.rtf" withExtension:nil];
url = [[NSBundle mainBundle] URLForResource:@"book.txt" withExtension:nil];
NSMutableAttributedString *attributedTextHolder = [[NSMutableAttributedString alloc] initWithFileURL:url options:@{} documentAttributes:nil error:nil];
[attributedTextHolder addAttribute:NSFontAttributeName value:[UIFont preferredFontForTextStyle:UIFontTextStyleBody] range:NSMakeRange(0, attributedTextHolder.length)];
// NSLog(@"%@", attributedTextHolder);
self.content = [attributedTextHolder copy];
self.textView.attributedText = self.content;
self.textView.editable = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; // 当不同类别的字体大小发生变化时发送消息给self
}
-(void)preferredContentSizeChanged:(NSNotification *)noti
{
static const CGFloat textScaleFactor = .8;
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
self.textView.font = font;
}
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
非常简单,关键就是在控制器中添加一个事件观察者来接收消息:
[cpp] view
plaincopy
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; // 当不同类别的字体大小发生变化时发送消息给self
另外要注意的是如果以self.content = @"abcdefghijklmnopqrstuvwxyz"的方式简单初始化self.content的内容,那么在调整完文字大小回到程序时self.content的内容可能已经被回收,可以看到文字内容显示为空。因此在将self.content赋值给self.textView.attributedText前,self.content必须要retain一次,也就是self.content必须要以init或者copy等方式获得:
[cpp] view
plaincopy
NSURL *url = nil;
// url = [[NSBundle mainBundle] URLForResource:@"Basic Interaction.rtf" withExtension:nil];
url = [[NSBundle mainBundle] URLForResource:@"book.txt" withExtension:nil];
NSMutableAttributedString *attributedTextHolder = [[NSMutableAttributedString alloc] initWithFileURL:url options:@{} documentAttributes:nil error:nil];
[attributedTextHolder addAttribute:NSFontAttributeName value:[UIFont preferredFontForTextStyle:UIFontTextStyleBody] range:NSMakeRange(0, attributedTextHolder.length)];
// NSLog(@"%@", attributedTextHolder);
self.content = [attributedTextHolder copy];
必须重写viewDidUnload和dealloc方法来移除事件观察者:
[cpp] view
plaincopy
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidUnload];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
重点看看收到消息后调整字体大小的方法:
[cpp] view
plaincopy
-(void)preferredContentSizeChanged:(NSNotification *)noti
{
static const CGFloat textScaleFactor = .8;
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
self.textView.font = font;
}
在这里用到的tkd_textStyle和tkd_preferredFontWithTextStyle:scale:是调整字体样式和大小关键。在这里使用了IntroduceTextKitDemo中的Categories中的类别和方法:
下面来看看取得字体样式的整个流程:
(1)在FontResizeViewController.m中调用UITextView类别的tkd_textStyle方法。
[cpp] view
plaincopy
NSString *textStyle = [self.textView tkd_textStyle]; // 先设置样式
(2)在UITextView+TextKitDemo.m中的tkd_textStyle方法调用UIFont类别的tkd_textStyle方法。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self.font tkd_textStyle];
}
(3)在UIFont+TextKitDemo.m中的tkd_textStyle方法中调用UIFontDecsriptor类别的tkd_textStyle方法。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self.fontDescriptor tkd_textStyle];
}
(4)在UIFontDescriptor+TextKitDemo.m的tkd_textStyle方法中回调字体样式结果。
[cpp] view
plaincopy
- (NSString *)tkd_textStyle
{
return [self objectForKey:@"NSCTFontUIUsageAttribute"];
}
在设置后字体样式后调用tkd_preferredFontWithTextStyle:scale:方法来设置字体,textStyle的参数使用了以上获得的tkd_textStyle,scale的参数则使用了textScaleFactor。整个方法的工作流程是相似的:
(1)FontResizeViewController.m
[cpp] view
plaincopy
UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //后设置字体(包括样式和大小)
(2)UIFont+TextKitDemo.m
[cpp] view
plaincopy
+ (UIFont *)tkd_preferredFontWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
{
UIFontDescriptor *newFontDescriptor = [UIFontDescriptor tkd_preferredFontDescriptorWithTextStyle:aTextStyle scale:aScale];
return [UIFont fontWithDescriptor:newFontDescriptor size:newFontDescriptor.pointSize];
}
(3)UIFontDescriptor+TextKitDemo.m
[cpp] view
plaincopy
+ (UIFontDescriptor *)tkd_preferredFontDescriptorWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
{
UIFontDescriptor *newBaseDescriptor = [self preferredFontDescriptorWithTextStyle:aTextStyle];
return [newBaseDescriptor fontDescriptorWithSize:lrint([newBaseDescriptor pointSize] * aScale)];
}
这就是整个程序的工作过程,主要还是参照和使用了IntroduceToTextKit这个Demo。
最后看看程序运行结果:
调整字体前:
调整Text Size到最大:
调整后的文本:
相关文章推荐
- TextKit学习(一)可以调整字体大小的FontResizeDemo
- TextKit学习(一)可以调整字体大小的FontResizeDemo
- TextKit学习(一)可以调整字体大小的FontResizeDemo
- iOS7新特性之TextKit(一)可以调整字体大小的FontResizeDemo
- UIButton调整字体大小
- 调整屏幕亮度,调整字体大小
- 禁用微信 webview 调整字体大小
- Android重写getResources规避用户调整系统字体大小影响Android屏幕适配
- eclipse 代码及xml调整字体大小设置
- 禁止微信内置浏览器调整字体大小
- Html之特殊字体_code_ strong _ em斜体_两种_下划线_大小_可以叠加_实例
- 如何调整MSN8.0界面的字体大小!
- Eclipse调试:改变颜色, 背景与字体大小 和xml字体调整
- 一个简单的自适应调整字体大小view
- source insight调整字体大小
- UITextView显示html代码,并调整attributedText的字体大小
- eclipse调整字体大小及背景颜色
- Eclipse设置:背景与字体大小和xml文件中字体大小调整
- Android 自定义TextView实现文本内容自动调整字体大小
- MacBook 调整eclipse字体大小