我问了一个开发人员(Codea的创建者TwoLivesLeft)他们如何在他们的应用程序中进行语法突出显示.他回答 :
@ TD2 Codea编辑器是使用UITextView实现的.突出显示是通过在适当的位置叠加子视图来完成的 - 通常是UILabels.它们从重用池中出列,类似于UITableViewCells的工作方式.在滚动期间,需要重新突出显示从池中拉出标记的线和已移出屏幕的线将其标记转储回池中.
任何人都可以解释我如何获得某个单词的x和y?
我已经使用这个答案来为特定范围的文本创建CGRect.
在这里UITextView我设置了它attributedText(所以我有一堆带有不同字形大小的样式文本).
这对于左对齐的第一行文本非常有用,但在使用NSTextAlignmentJustified或时使用时会产生一些非常奇怪的结果NSTextAlignmentCenter.
当线条缠绕时它也不能正确计算,或者(如果有\n线条断裂).
我得到这样的东西(这是中心对齐):

相反,我期待这个:

这个有一个\n换行符 - 前两个代码位被成功突出显示,但最后一个more code for you to see不是因为文本换行没有考虑到x,y计算中.
- (void)formatMarkdownCodeBlockWithAttributes:(NSDictionary *)attributesDict
withHighlightProperties:(NSDictionary *)highlightProperties
forFontSize:(CGFloat)pointSize
{
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"`.+?`" options:NO error:nil];
NSArray *matchesArray = [regex matchesInString:[self.attributedString string] options:NO range:NSMakeRange(0, self.attributedString.length)];
for (NSTextCheckingResult *match in matchesArray)
{
NSRange range = [match range];
if (range.location != NSNotFound) {
self.textView.attributedText = self.attributedString;
CGRect codeRect = [self frameOfTextRange:range forString:[[self.attributedString string] …Run Code Online (Sandbox Code Playgroud) 编辑
简单的解决方案是将任何帧计算移动viewDidLoad到viewDidAppear:
我很难让下面的代码正常工作
代码返回UITextView中给定NSRange的第一帧.
如果没有换行符,它会起作用,但是当我在UITextView中添加换行符时,我会遇到一些奇怪的行为.
@implementation UITextView (TextFrame)
- (CGRect)frameOfTextRange:(NSRange)range {
UITextPosition *beginning = self.beginningOfDocument;
UITextPosition *start = [self positionFromPosition:beginning offset:range.location];
UITextPosition *end = [self positionFromPosition:start offset:range.length];
UITextRange *textRange = [self textRangeFromPosition:start toPosition:end];
CGRect rect = [self firstRectForRange:textRange];
return [self convertRect:rect fromView:self.textInputView];
}
@end
@implementation DetailViewController
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.searchString) {
CGRect rect = [self.textView frameOfTextRange:[self.textView.text rangeOfString:self.searchString]];
...
}
}
Run Code Online (Sandbox Code Playgroud)