您的位置:首页 > 其它

DTCoreText项目使用浅析 (2)

2013-12-16 23:10 447 查看
前一篇提到生成NSAttributedString,接下面就是如何将NSAttributedString展示出来

DTAttributedTextContentView的主要结构

@interface DTAttributedTextContentView : UIView
{
NSAttributedString *_attributedString;
DTCoreTextLayoutFrame *_layoutFrame;

UIEdgeInsets edgeInsets;

NSMutableDictionary *customViewsForAttachmentsIndex;
}

- (id)initWithAttributedString:(NSAttributedString *)attributedString width:(CGFloat)width;

- (void)resetWithLayouterWithFrame:(DTCoreTextLayouter *)layouter layoutFrame: (DTCoreTextLayoutFrame *)layoutFrame frame:(CGRect)frame;

- (void)layoutSubviewsInRect:(CGRect)rect;
- (void)relayoutText;
- (void)removeAllCustomViews;
- (void)removeAllCustomViewsForLinks;

- (CGSize)attributedStringSizeThatFits:(CGFloat)width;
- (CGSize)suggestedFrameSizeToFitEntireStringConstraintedToWidth:(CGFloat)width; // obeys the edge insets

// properties are overwritten with locking to avoid problem with async drawing
@property (atomic, strong) DTCoreTextLayouter *layouter;
@property (atomic, strong) DTCoreTextLayoutFrame *layoutFrame;

@property (nonatomic, strong) NSMutableSet *customViews;


其中有两个布局相关的元素:

@property (atomic, strong) DTCoreTextLayouter *layouter;
@property (atomic, strong) DTCoreTextLayoutFrame *layoutFrame;


其中DTCoreTextLayoutFrame有个重要的方法叫做

- (void)_buildLines

这里就开始根据attributedString做各种段落和行数的设置了,局限于Coretext的知识,这里我无法给出一个详细的说明

DTAttributedTextContentView重载了layoutSubviews和实现了- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;

NSAttributedString *layoutString = [theLayoutFrame attributedStringFragment];
NSArray *lines;
if (CGRectIsInfinite(rect))
{
lines = [theLayoutFrame lines];
}
else
{
lines = [theLayoutFrame linesVisibleInRect:rect];
}


接着遍历line

for (DTCoreTextLayoutLine *oneLine in lines)
{
NSRange lineRange = [oneLine stringRange];

NSUInteger skipRunsBeforeLocation = 0;

for (DTCoreTextGlyphRun *oneRun in oneLine.glyphRuns)


针对每个单元,查找link和attachment的属性,这里还对attachment的view做了缓存优化

if (_delegateFlags.delegateSupportsCustomViewsForAttachments)
{
newCustomAttachmentView = [_delegate attributedTextContentView:self viewForAttachment:attachment frame:frameForSubview];
}
else if (_delegateFlags.delegateSupportsGenericCustomViews)
{
NSAttributedString *string = [layoutString attributedSubstringFromRange:runRange];
newCustomAttachmentView = [_delegate attributedTextContentView:self viewForAttributedString:string frame:frameForSubview];
}


委托生成对应的custom view, 这里可以做些图文混排的工作,比如图片、链接等

这里补充下,这里custom view生成时,可以动态调整相关高度,也就是说不用去更新nsattributedstring,动态加载图片就是这样处理的。

等custom view生成完毕后,开始调用

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx

DTCoreTextLayoutFrame *theLayoutFrame = self.layoutFrame;

// need to prevent updating of string and drawing at the same time
SYNCHRONIZE_START(selfLock)
{
[theLayoutFrame drawInContext:ctx drawImages:shouldDrawImages];

if (_delegateFlags.delegateSupportsNotificationAfterDrawing)
{
[_delegate attributedTextContentView:self didDrawLayoutFrame:theLayoutFrame inContext:ctx];
}
}
SYNCHRONIZE_END(selfLock)


DTCoreTextLayoutFrame这个方法负责将构造出来的DTCoreTextLayoutLine数组,通过CoreText绘制到图形上下文中,还利用CoreGraphics画线、背景等一系列效果;这里也可以定制部分特殊效果功能。

这样DTCoreText的基本流程就完成了,里面很多细节没有涉及,和CoreText相关的功能还待学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: