У меня есть подкласс UIView, который реализует код для рисования CoreText.В приложении этот UIView рисуется внутри UIScrollView.Вот код, который я в настоящее время использую в drawRect: для рендеринга NSAttributedString:
CGContextRef context = UIGraphicsGetCurrentContext();
float viewHeight = self.bounds.size.height;
CGContextTranslateCTM(context, 0, viewHeight);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1.0, 1.0));
CGMutablePathRef path = CGPathCreateMutable();
CGRect bounds = CGRectMake(PADDING_LEFT, -PADDING_TOP, self.bounds.size.width-20.0, self.bounds.size.height);
CGPathAddRect(path, NULL, bounds);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFMutableAttributedStringRef)attrString);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CFRelease(path);
CTFrameDraw(frame, context);
В моем NSAttributedString у меня есть определенные текстовые атрибуты для цвета текста.
Что мне нужно помочь сконцептуально, как это должно быть достигнуто?Меня смущают различные методы рисования рамок, слоев и т. Д. Я пытался просмотреть несколько книг и других ресурсов, но мне кажется, что мне не хватает некоторых базовых вещей.
Вот мои требования:
- Очевидно, что при изменении ориентации выделение необходимо перерисовать в новом месте.
- Необходимо выделить программным способом цвет подсветки для отдельных выделений.
- Идеально для работы, мне не нужно перерисовывать весь CoreText UIView, когда я просто изменяю цвет подсветки одного выделения.
- Отдельные Rects должны иметь возможность группироваться вместеобразуют одно выделение, поскольку выделение может охватывать диапазон, выходящий за пределы одного CTLine.
- В конечном счете, я хочу реализовать UIMenuController в представлении CoreText, поэтому я считаю, что выделение следует рисовать под CoreText UIView?
Буду очень признателен за любую помощь.
Вот что у меня естьдо сих пор пробовал:
Я добавил новый UIView в качестве подпредставления к UIScrollView, чтобы содержать основные моменты.Затем я добавляю отдельные UIViews для основных моментов.Когда я создаю фиктивные «тестовые» выделения, они правильно отображаются в представлении CoreText.Я также могу легко изменить цвет подсветки.Однако, когда я собираюсь получить фактическую информацию о линиях из представления CoreText для создания реальных бликов, он возвращает ноль линий.Может ли это быть из-за того, что drawRect еще не закончил рисование или что-то еще?
Вот несколько вопросов:
- Должен ли я добавить UIView в качестве подпредставления к UIScrollView, чтобы содержать всеосновные моменты с дополнительными подпредставлениями для каждого отдельного основного момента?Затем сохраните каждую выделенную область UIView во вложенном NSArray?
- Если я изменю цвет подсветки под CoreText UIView, это приведет к перерисовке всего UIView?Если да, то как я могу проектировать вокруг этого?
- Это правда, что если я хочу, чтобы CoreText UIView получал входные данные для UIMenuController, я должен поместить объекты подсветки под CoreText UIView?
Я видел этот проект с открытым исходным кодом:
https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML
Это удивительно, что он может сделать, но гораздо сложнее и детальнее, чем мне нужно.Код отображает каждый отдельный глиф, используя CoreText, и разрешает выделение, а это здорово.Тем не менее, я стараюсь сделать свой код простым и легким.Я очень мало знаю о CoreGraphics, CoreAnimation или CoreText.
Я также видел этот вопрос:
Базовый текст - получить координаты пикселей из NSRange
Ответ на вопрос предоставляет вызовы для определения границ Rect для данного диапазона в данной строке.Я думаю, что могу выяснить эти звонки.
ОБНОВЛЕНИЕ
Вот что я сделал сейчас.Я уверен, что это неправильно, но это единственный способ найти способ заставить его работать ...
- Создать UIView в качестве контейнера для добавления в UIScrollView в качестве подпредставления.
- Передайте UIView в CoreTextView.Я также передаю массив диапазонов строк в CoreTextView, чтобы указать, какие строки должны быть выделены.
- Добавить CoreTextView как подпредставление UIScrollView.Таким образом, UIView находится под CoreTextView.
- В функции drawRect: CoreTextView я рисую CoreText.Затем я вызываю функцию для вычисления основных моментов.
- Каждый NSRange проверяется по строкам и вычисляется CGRect каждого совпадения в строке.
- CGRect используется для создания нового UIView. Этот UIView добавляется как subView контейнера UIView. Он также добавляется в NSArray, чтобы я мог отслеживать его и при необходимости изменять цвет подсветки для отдельной подсветки.
Это не вызывает drawRect каждый раз, когда в контейнер добавляется подсветка или изменяется цвет. Однако я знаю, что это не идеальное решение. Проблемы с этим решением:
- Когда UIViewController вызывает setNeedsDisplay для CoreTextView, невозможно узнать, когда он завершил рисование. Я все еще не могу найти способ сделать обратный вызов, чтобы сказать ViewController, что можно приступить к следующей задаче.
- Добавляя UIViews к другому контейнеру UIView, drawRect технически рисует элементы вне своего прямоугольника, который, как я знаю, является нет-нет.
- Я уверен, что это не самый эффективный способ сделать это, хотя, похоже, он работает довольно хорошо.