支持图文混排在教程:《Core Text Tutorial for iOS: Making a Magazine App》 中有介绍,我们在解析 DOM 树遇到图片节点时,则将该内容转成一个空格,随后设置该空格在绘制时,需要我们自己指定宽高相关信息,而宽高信息在图片节点中都有提供。这样,CoreText 引擎在绘制时,就会把相关的图片位置留空,之后我们将图片异步下来下来后,使用 CoreGraph 相关的 API 将图片再画在界面上,就实现了图文混排功能。
判断第 2 步得到的 index 是否在第一步记录的各个链接的区间范围内,如果在范围内,则表示用户点击了某一个链接。
这段逻辑的关键代码如下:
// test touch point is on link or not + (LinkData *)touchLinkInView:(UIView *)view atPoint:(CGPoint)point data:(CTTableViewCellData *)data { CTFrameRef textFrame = data.ctFrame; CFArrayRef lines = CTFrameGetLines(textFrame); if (!lines) returnnil; CFIndex count = CFArrayGetCount(lines); LinkData *foundLink = nil;
// CoreText context coordinates are the opposite to UIKit so we flip the bounds CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformMakeTranslation(0, view.bounds.size.height), 1.f, -1.f);
for (int i = 0; i < count; i++) { CGPoint linePoint = origins[i]; CTLineRef line = CFArrayGetValueAtIndex(lines, i); CGRect flippedRect = [self getLineBounds:line point:linePoint]; CGRect rect = CGRectApplyAffineTransform(flippedRect, transform);
NSMutableAttributedString *truncationString = [[attributedString attributedSubstringFromRange:NSMakeRange(lastLineRange.location, lastLineRange.length)] mutableCopy]; if (lastLineRange.length > 0) { // Remove any whitespace at the end of the line. unichar lastCharacter = [[truncationString string] characterAtIndex:lastLineRange.length - 1]; if ([[NSCharacterSet whitespaceAndNewlineCharacterSet] characterIsMember:lastCharacter]) { [truncationString deleteCharactersInRange:NSMakeRange(lastLineRange.length - 1, 1)]; } } [truncationString appendAttributedString:tokenString];
CTLineRef truncationLine = CTLineCreateWithAttributedString((__bridge CFAttributedStringRef)truncationString); CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, self.size.width, truncationType, truncationToken); if (!truncatedLine) { // If the line is not as wide as the truncationToken, truncatedLine is NULL truncatedLine = CFRetain(truncationToken); } CFRelease(truncationLine); CFRelease(truncationToken);