使用
TextKit
框架創建多列布局的文字
參考
- GitHub 源碼:shinobicontrols/iOS7-day-by-day
- 天天品嘗iOS7甜點 :: Day 21 :: Multi-column TextKit text rendering
TextKit Demo
#import "SCViewController.h"
@interface SCViewController () {
NSLayoutManager *_layoutManager;
NSTextStorage *_textStorage;
}
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@end
@implementation SCViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1.將文本內容導入 NSTextStorage 文本存儲對象
NSURL *contentURL = [[NSBundle mainBundle] URLForResource:@"content" withExtension:@"txt"];
_textStorage = [[NSTextStorage alloc] initWithFileURL:contentURL
options:@{NSDocumentTypeDocumentAttribute:NSPlainTextDocumentType}
documentAttributes:NULL
error:NULL];
// 2.創建 NSLayoutManager 布局管理對象
_layoutManager = [[NSLayoutManager alloc] init];
[_textStorage addLayoutManager:_layoutManager];
// 布局文本內容
[self layoutTextContainers];
}
// 循環每個列,創建新的 NSTextContainer 來指定文本的大小,然后使用屏幕上面的 UITextView 進行渲染它。
- (void)layoutTextContainers {
NSUInteger lastRenderedGlyph = 0; // 循環終止變量
CGFloat currentXOffset = 0; // X軸偏移量
// numberOfGlyphs 代表字形總數
while (lastRenderedGlyph < _layoutManager.numberOfGlyphs) {
// 列的大小,高 = 接近根視圖的高,寬 = 根視圖的一半。
CGRect textViewFrame = CGRectMake(currentXOffset, 10,
CGRectGetWidth(self.view.bounds) / 2,
CGRectGetHeight(self.view.bounds) - 20);
CGSize columnSize = CGSizeMake(CGRectGetWidth(textViewFrame) - 20,
CGRectGetHeight(textViewFrame) - 10);
// 3.創建 NSTextContainer 對列區域中的字形進行布局。
NSTextContainer *textContainer = [[NSTextContainer alloc] initWithSize:columnSize];
[_layoutManager addTextContainer:textContainer];
// 4.創建并添加 UITextView 來顯示文字
UITextView *textView = [[UITextView alloc] initWithFrame:textViewFrame
textContainer:textContainer];
textView.scrollEnabled = NO;
[self.scrollView addSubview:textView];
// 更新追蹤最后的呈現字形的變量和當前列的位置
// 增加當前的偏移量
currentXOffset += CGRectGetWidth(textViewFrame);
// 并找到我們剛剛呈現的字形的索引
lastRenderedGlyph = NSMaxRange([_layoutManager glyphRangeForTextContainer:textContainer]);
}
// 根據 X 軸的偏移量更新 scrollView 的寬度
CGSize contentSize = CGSizeMake(currentXOffset, CGRectGetHeight(self.scrollView.bounds));
self.scrollView.contentSize = contentSize;
}
@end