昨天看完了蘋果官方的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類,下面來看看該類的實現文件:
- #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
非常簡單,關鍵就是在控制器中添加一個事件觀察者來接收消息:
- [[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等方式獲得:
- 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方法來移除事件觀察者:
- - (void)viewDidUnload
- {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- [super viewDidUnload];
- }
- - (void)dealloc
- {
- [[NSNotificationCenter defaultCenter] removeObserver: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;
- }
- NSString *textStyle = [self.textView tkd_textStyle]; // 先設置樣式
- - (NSString *)tkd_textStyle
- {
- return [self.font tkd_textStyle];
- }
- - (NSString *)tkd_textStyle
- {
- return [self.fontDescriptor tkd_textStyle];
- }
- - (NSString *)tkd_textStyle
- {
- return [self objectForKey:@"NSCTFontUIUsageAttribute"];
- }
- UIFont *font = [UIFont tkd_preferredFontWithTextStyle:textStyle scale:textScaleFactor]; //後設置字體(包括樣式和大小)
- + (UIFont *)tkd_preferredFontWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
- {
- UIFontDescriptor *newFontDescriptor = [UIFontDescriptor tkd_preferredFontDescriptorWithTextStyle:aTextStyle scale:aScale];
- return [UIFont fontWithDescriptor:newFontDescriptor size:newFontDescriptor.pointSize];
- }
- + (UIFontDescriptor *)tkd_preferredFontDescriptorWithTextStyle:(NSString *)aTextStyle scale:(CGFloat)aScale
- {
- UIFontDescriptor *newBaseDescriptor = [self preferredFontDescriptorWithTextStyle:aTextStyle];
- return [newBaseDescriptor fontDescriptorWithSize:lrint([newBaseDescriptor pointSize] * aScale)];
- }
這就是整個程序的工作過程,主要還是參照和使用了IntroduceToTextKit這個Demo。
轉自:http://blog.csdn.net/iunion/article/details/12184983