Tag: textkit

在iOS上使用TextKit进行文本分页

Textkit的框架 对于显示在视图上的字符串,它需要经历几个过程:存储字符串->排版->显示。 TextStorage类是用于存储字符串的容器,因此首先必须将字符串(无论是纯文本还是富文本格式)打包到TextStorage中 ,然后LayoutManager将管理文本的布局,之后是TextContainer类将控制位置和页面大小,请注意TextContainer和TextView的大小均不正确,这将在本文后面提到。 设置完所有内容后,您可以使用UITextView或UILabel在视图上显示文本。 在实际开发中,我的建议是在某些尺寸问题的情况下使用TextView 。 分页 使用TextKit进行分页非常简单。 根据Apple的官方文档,LayoutManager和TextContainer可以一起完成分页工作,同时,如果您有其他要求,则需要一种算法。 从上图中, LayoutManager从TextStorage读取字符串,并根据添加到LayoutManager的TextContainer的数量执行页面布局。 如果只有一个TextContainer ,则将仅排版第一页的数据,而另一页将被丢弃。 如果有多个TextContainer ,则可以完成大文本分页。 码 // 1. 从文件中读取字符串。 NSString * textString = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@“ Text” ofType:@“ txt”]编码:NSUTF8StringEncoding错误:无]; // 2. 将字符串打包到存储中。 NSTextStorage *存储= [[NSTextStorage alloc] initWithString:textString]; // 3. 为存储添加布局管理。 NSLayoutManager * layoutManager = [[NSLayoutManager alloc] init]; [存储addLayoutManager:layoutManager]; 同时(是) { // 4. […]

NSLayoutManager boundingRectForGlyphRange由某些点closures

我想在UITextView中“突出显示”特定的单词,而不是用纯色(可能通过NSAttributedString ),而是使用渐变,也许还有一些奇特的效果。 因此,我决定有必要手动创build一个视图,并使用给定文本的边界矩形覆盖(或底层)。 令我惊讶的是,这竟然是相当简单的。 例子是在UIViewController里面, txtView是一个UITextView作为IBOutlet连接: override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // Converting to NSString as I need a NSRange for glphyRangeForCharacterRange // (a normal String in Swift returns a Range) let charRange = (txtView.text as NSString).rangeOfString("dolor sit er elit") assert(charRange.location != NSNotFound, "Character Range could not be found.") let glyphRange = txtView.layoutManager.glyphRangeForCharacterRange(charRange, actualCharacterRange: nil) […]

NSAttributedString为UITextView sizeThatFits和boundingRectWithSize报告不正确的大小,并设置了正确的选项

我有一个NSAttributedString报告一个boundingRectWithSize(和扩展UITextView不正确地计算其sizeThatFits)当字体大小从用于创build它的字体大小减less。 它不会发生在我做类似的操作的所有NSAttributedStrings,所以这里是重现的步骤。 使用不包含完整Unicode字符集的非标准字体。 确保string包含此“不受支持”集中的字符。 iOS会将它们渲染为Helvetica,大小适中。 在您的NSAttributedString中缩放字体的所有字体属性。 我的代码这样做产生的问题看起来像这样。 从UITextView子类中: NSMutableAttributedString *mutableString = [self.attributedText mutableCopy]; [mutableString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, mutableString.length) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) { if (value) { UIFont *oldFont = (UIFont *)value; UIFont *newFont = [oldFont fontWithSize:oldFont.pointSize – 1]; [mutableString removeAttribute:NSFontAttributeName range:range]; [mutableString addAttribute:NSFontAttributeName value:newFont range:range]; } }]; self.attributedText = [mutableString copy]; 我注意到,当在while循环中运行这个代码时,检查sizeThatFits来知道文本何时足够小,以至于在某些情况下我会产生一个零竞赛。 对于任何小于我开始使用的字体值的情况,高度计算为60px,这恰好是50px。 […]

UIPageViewController / TextKit在分页上回stream文本

我正在使用TextKit支持的多页阅读应用程序,该应用程序基于WWDC 2013的“高级文本布局和与文本工具箱的效果”会话(但是其中一些代码是从不完整的示例中重新构build的)。 基本的结构是计算你的文本所需的页面数量,然后为每个页面创build一个NSTextContainer,并将其添加到NSLayoutManager。 每当UIPageViewController请求下一页或上一页时,您将创build一个新的UITextView,并通过从NLayoutManger的NSTextContainers数组中select正确的一个来设置其后备文本容器。 不幸的是,我有一个问题,在第一页,第一次,我回到任何给定的页面文本得到重新stream转。 这是它的样子: 这不是最明显的效果(如果你错过了,当回页时注意屏幕的顶部),但有点迷惑,我想尽可能消除它。 鉴于文本容器应该在前面计算,我不明白为什么它回stream的文本,或如何防止它。 有谁知道问题是什么? 编辑 :添加一个代码示例。 @interface ReaderViewController () <UIPageViewControllerDataSource> @property (nonatomic, assign) NSUInteger numberOfPages; @property (nonatomic, retain) UIPageViewController *pageViewController; @property (nonatomic, retain) NSTextStorage *currentDocument; @property (nonatomic, retain) NSLayoutManager *layoutManager; @end @implementation ReaderViewController – (instancetype)initWithDocument:(NSTextStorage *)document { if ((self = [super init])) { _currentDocument = document; } return self; } […]

使用CALayer来突出显示跨越多行的UITextView中的文本

这是为了使用CALayer突出显示而在UITextView中获取CGRect文本的延续。 我无法获得每个线段中的范围正确的矩形。 NSString* searchString = @"Returns the range of characters that generated"; NSRange match = [[[self textView]text]rangeOfString:searchString]; NSRange matchingGlyphRange = [manager glyphRangeForCharacterRange:match actualCharacterRange:NULL]; [manager enumerateLineFragmentsForGlyphRange:matchingGlyphRange usingBlock: ^(CGRect lineRect, CGRect usedRect, NSTextContainer *textContainer, NSRange lineRange, BOOL *stop) { NSRange currentRange = NSIntersectionRange(lineRange, matchingGlyphRange); [manager enumerateEnclosingRectsForGlyphRange:currentRange withinSelectedGlyphRange:NSMakeRange(NSNotFound, 0) inTextContainer:textContainer usingBlock: ^(CGRect rect, BOOL* stop) { if (usedRect.origin.y […]