64
Core Text github.com/anyvoid/CoreTextDemo

Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

  • Upload
    others

  • View
    36

  • Download
    0

Embed Size (px)

Citation preview

Page 2: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Константин КиселёвВедущий разработчик

Page 3: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Содержание

๏Основы Core Text

• Маркируем области в тексте

• Два столбца• Обтекание текстом

3

Page 4: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рецепты Юлии Высоцкой

4

Page 5: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рецепты Юлии Высоцкой

При нажатии на ссылку со временем открывается установка таймера

5

Page 6: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рецепты Юлии Высоцкой

6

Page 7: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Бар Депозит – Управление Баром

Во время набора имени в поиске участки совпадения

подсвечиваются в выпадающем меню

7

Page 8: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рендеринг текста

UIKit

Core Text

Quartz Core

8

Page 9: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

UIKit

• Ничего сложного

• UIFont

• UILabel, UITextView, UIWebView

• Минимальные возможности настройки отображения

• в iOS 6 можно задавать NSAttributedString !

9

Page 10: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рендеринг текста

UIKit

Core Text

Quartz Core

10

Page 11: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Quartz Core

• Непосредственная отрисовка глифов• CGFontRef

• Фиксированная информация о шрифте

• Использование — корректировка отображения

11

Page 12: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename( [fontPath UTF8String] );

CGFontRef font = CGFontCreateWithDataProvider( fontDataProvider );

CGGlyph glyphs[glyphCount];

for ( size_t i = 0; i < glyphCount; ++i ) { ... glyphs[i] = CGFontGetGlyphWithGlyphName( font, glyphName ); ... }

CGContextSetFont( context, font ); CGContextSetFontSize( context, fontSize );

CGContextShowGlyphsAtPoint( context, p.x, p.y, glyphs, glyphCount );

Quartz Core

12

Page 13: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename( [fontPath UTF8String] );

CGFontRef font = CGFontCreateWithDataProvider( fontDataProvider );

CGGlyph glyphs[glyphCount];

for ( size_t i = 0; i < glyphCount; ++i ) { ... glyphs[i] = CGFontGetGlyphWithGlyphName( font, glyphName ); ... }

CGContextSetFont( context, font ); CGContextSetFontSize( context, fontSize );

CGContextShowGlyphsAtPoint( context, p.x, p.y, glyphs, glyphCount );

Quartz Core

13

Page 14: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CGDataProviderRef fontDataProvider = CGDataProviderCreateWithFilename( [fontPath UTF8String] );

CGFontRef font = CGFontCreateWithDataProvider( fontDataProvider );

CGGlyph glyphs[glyphCount];

for ( size_t i = 0; i < glyphCount; ++i ) { ... glyphs[i] = CGFontGetGlyphWithGlyphName( font, glyphName ); ... }

CGContextSetFont( context, font ); CGContextSetFontSize( context, fontSize );

CGContextShowGlyphsAtPoint( context, p.x, p.y, glyphs, glyphCount );

Quartz Core

14

Page 15: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Рендеринг текста

UIKit

Core Text

Quartz Core

15

Page 16: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• Оптимальное сложность/возможности• CTFontRef

• CTFrame, CTLine, CTRun, CTGlyph

• Можно использовать в нескольких потоках, но с ограничениями. . .

16

Page 17: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• Все функции

• Объекты, не задающие размещение текста:

- CTFont

- CTFontDescriptor

- ...

• Объекты, задающие размещение:

- CTFrameSetter

- CTTypeSetter

- CTFrame

- CTRun

- CTLine

- ...

Потокобезопасно Непотокобезопасно

17

Page 18: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

СFAttributedString CTFrameSetter

CTTypeSetter CTFrame

CGPath CTLine

CTLine

CTRun

CTRun

CTGlyph CTGlyph

18

Page 19: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• CTFrame – область вывода всего текста

• CTLine – одна строка

• CTRun – последовательность символов с одинаковыми атрибутами

• CTGlyph – один символ шрифта

19

Page 20: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

CTFrame

CTLine

This is CTRun Next CTRun The End.

20

Page 21: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

- (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext();

// Делаем текущую матрицу единичной CGContextSetTextMatrix( context, CGAffineTransformIdentity ); // Добавляем к матрице перенос по вертикали CGContextTranslateCTM( context, 0, rect.size.height ); // Добавляем отражение по вертикали CGContextScaleCTM( context, 1, -1 ); // ...

Core Text

• Отраженная и сдвинутая по вертикали система координат

21

Page 22: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CGFloat width = rect.size.width, height = rect.size.height; CGFloat rect = CGRectMake(0, 0, width, height);

CGMutablePathRef mutablePath = CGPathCreateMutable(); CGPathAddRect( mutablePath, NULL, rect ); CTFrameRef frame = CTFramesetterCreateFrame(

frameSetter, frameRange, mutablePath, NULL );

• Создаем CTFrameSetter из CFAttributedString

• Далее получаем CTFrame, используя CGPath

CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString( attrStr );

Core Text

22

Page 23: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString( attrStr );

CGFloat width = rect.size.width, height = rect.size.height; CGFloat rect = CGRectMake(0, 0, width, height);

CGMutablePathRef mutablePath = CGPathCreateMutable(); CGPathAddRect( mutablePath, NULL, rect ); CTFrameRef frame = CTFramesetterCreateFrame(

frameSetter, frameRange, mutablePath, NULL );

• Создаем CTFrameSetter из CFAttributedString

• Далее получаем CTFrame, используя CGPath

Core Text

23

Page 24: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Полученный CTFrame является моделью, по которой отрисовывается текст в графическом контексте после вызова

• Аналогичные функции для отрисовки отдельных CTLine, CTRun

Core Text

CTFrameDraw( frame, context );

CGContextSetTextPosition(context, p.x, p.y); CTLineDraw(line, context); CTRunDraw(run, context, CFRangeMake(0, 0));

24

Page 25: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Полученный CTFrame является моделью, по которой отрисовывается текст в графическом контексте после вызова

• Аналогичные функции для отрисовки отдельных CTLine, CTRun

CTFrameDraw( frame, context );

Core Text

CGContextSetTextPosition(context, p.x, p.y); CTLineDraw(line, context); CTRunDraw(run, context, CFRangeMake(0, 0));

25

Page 26: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

CTFrameDraw( frame, context );

• Полученный CTFrame является моделью, по которой отрисовывается текст в графическом контексте после вызова

• Аналогичные функции для отрисовки отдельных CTLine, CTRun

Core Text

CGContextSetTextPosition(context, p.x, p.y); CTLineDraw(line, context); CTRunDraw(run, context, CFRangeMake(0, 0));

26

Page 27: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Проход по всем участкам фрейма: NSArray* lines = (__bridge NSArray *)CTFrameGetLines( frame ); for ( int lineIndex = 0; lineIndex < length; ++lineIndex ) { CTLineRef line =

(__bridge CTLineRef)[lines objectAtIndex: lineIndex];

NSArray* runs = (__bridge NSArray *)CTLineGetGlyphRuns( line );

for ( int runIndex = 0; runIndex < runs.count; ++runIndex ) { CTRunRef run =

(__bridge CTRunRef)[runs objectAtIndex: runIndex]; // ... } }

Core Text

27

Page 28: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Проход по всем участкам фрейма: NSArray* lines = (__bridge NSArray *)CTFrameGetLines( frame ); for ( int lineIndex = 0; lineIndex < length; ++lineIndex ) { CTLineRef line =

(__bridge CTLineRef)[lines objectAtIndex: lineIndex];

NSArray* runs = (__bridge NSArray *)CTLineGetGlyphRuns( line );

for ( int runIndex = 0; runIndex < runs.count; ++runIndex ) { CTRunRef run =

(__bridge CTRunRef)[runs objectAtIndex: runIndex]; // ... } }

Core Text

28

Page 29: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Проход по всем участкам фрейма: NSArray* lines = (__bridge NSArray *)CTFrameGetLines( frame ); for ( int lineIndex = 0; lineIndex < length; ++lineIndex ) { CTLineRef line =

(__bridge CTLineRef)[lines objectAtIndex: lineIndex];

NSArray* runs = (__bridge NSArray *)CTLineGetGlyphRuns( line );

for ( int runIndex = 0; runIndex < runs.count; ++runIndex ) { CTRunRef run =

(__bridge CTRunRef)[runs objectAtIndex: runIndex]; // ... } }

Core Text

29

Page 30: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Проход по всем участкам фрейма: NSArray* lines = (__bridge NSArray *)CTFrameGetLines( frame ); for ( int lineIndex = 0; lineIndex < length; ++lineIndex ) { CTLineRef line =

(__bridge CTLineRef)[lines objectAtIndex: lineIndex];

NSArray* runs = (__bridge NSArray *)CTLineGetGlyphRuns( line );

for ( int runIndex = 0; runIndex < runs.count; ++runIndex ) { CTRunRef run =

(__bridge CTRunRef)[runs objectAtIndex: runIndex]; // ... } }

Core Text

30

Page 31: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Texty

x

При определенных

условиях вещество

трансформирует межядерный

фонон

origin

origin + ascent

origin – descent

31

Page 32: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Получаем origin-ы для строк:

• Получаем frame строки:

• Получаем frame для CTRun:

lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

lineHeight = ascent + descent + leading;

runWidth = CTRunGetTypographicBounds( run, CFRangeMake(0, 0),&runAscent, &runDescent, &runLeading );

topY = lineOrigins[lineIndex].y + ascent;leftX = CTLineGetOffsetForStringIndex(line, runRange.location, NULL);runHeight = runAscent + runDescent + runLeading;

CGPoint lineOrigins[lines.count];CTFrameGetLineOrigins(

frame, CFRangeMake(0, lines.count), lineOrigins);

Core Text

32

Page 33: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Получаем origin-ы для строк:

• Получаем frame строки:

• Получаем frame для CTRun:

lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

lineHeight = ascent + descent + leading;

runWidth = CTRunGetTypographicBounds( run, CFRangeMake(0, 0),&runAscent, &runDescent, &runLeading );

topY = lineOrigins[lineIndex].y + ascent;leftX = CTLineGetOffsetForStringIndex(line, runRange.location, NULL);runHeight = runAscent + runDescent + runLeading;

CGPoint lineOrigins[lines.count];CTFrameGetLineOrigins(

frame, CFRangeMake(0, lines.count), lineOrigins);

Core Text

33

Page 34: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Получаем origin-ы для строк:

• Получаем frame строки:

• Получаем frame для CTRun:

lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

lineHeight = ascent + descent + leading;

runWidth = CTRunGetTypographicBounds( run, CFRangeMake(0, 0),&runAscent, &runDescent, &runLeading );

topY = lineOrigins[lineIndex].y + ascent;leftX = CTLineGetOffsetForStringIndex(line, runRange.location, NULL);runHeight = runAscent + runDescent + runLeading;

CGPoint lineOrigins[lines.count];CTFrameGetLineOrigins(

frame, CFRangeMake(0, lines.count), lineOrigins);

Core Text

34

Page 35: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

runWidth = CTRunGetTypographicBounds( run, CFRangeMake(0, 0),&runAscent, &runDescent, &runLeading );

topY = lineOrigins[lineIndex].y + ascent;leftX = CTLineGetOffsetForStringIndex(line, runRange.location, NULL);runHeight = runAscent + runDescent + runLeading;

• Получаем origin-ы для строк:

• Получаем frame строки:

• Получаем frame для CTRun:

lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

lineHeight = ascent + descent + leading;

CGPoint lineOrigins[lines.count];CTFrameGetLineOrigins(

frame, CFRangeMake(0, lines.count), lineOrigins);

Core Text

35

Page 36: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Получаем origin-ы для строк:

• Получаем frame строки:

• Получаем frame для CTRun:

lineWidth = CTLineGetTypographicBounds(line, &ascent, &descent, &leading);

lineHeight = ascent + descent + leading;

runWidth = CTRunGetTypographicBounds( run, CFRangeMake(0, 0),&runAscent, &runDescent, &runLeading );

topY = lineOrigins[lineIndex].y + ascent;leftX = CTLineGetOffsetForStringIndex(line, runRange.location, NULL);runHeight = runAscent + runDescent + runLeading;

CGPoint lineOrigins[lines.count];CTFrameGetLineOrigins(

frame, CFRangeMake(0, lines.count), lineOrigins);

Core Text

36

Page 37: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• Полезные свойства параграфов:• межстрочный интервал

• выравнивание по горизонтали

• line break mode

• отступ красной строки

• . . .37

Page 38: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• CTParagraphStyleSetting

• CTParagraphStyleRef

CTParagraphStyleSetting parSet[] = { {kCTParagraphStyleSpecifierAlignment, sizeof(value), &value}, {kCTParagraphStyleSpecifierLineSpacing, ...}, {kCTParagraphStyleSpecifierLineBreakMode, ...} ...};

NSInteger optsNum = sizeof(parSet) / sizeof(CTParagraphStyleSetting);

CTParagraphStyleRef parStyle = CTParagraphStyleCreate( parSet, optsNum);

38

Page 39: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Core Text

• Установка свойств параграфов доступна:- iOS < 6: ТОЛЬКО при инициализации

NSAttributedString / NSMutableAttributedString

- iOS 6: можно делать addAttribute у NSMutableAttributedString

39

Page 40: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Неприятности:

- выделения пишем сами

- анализ текста (html, rtf и чего угодно своего, например, с разбивкой на параграфы) тоже пишем сами

Core Text

40

Page 41: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Приятности:

✓ огромные возможности по кастомизации вывода текста

✓ очень удобно и быстро, когда нужно использовать UILabel, но цветной или с маркированными участками

✓ Достаточно быстр

Core Text

41

Page 42: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Тест на скорость:‣ UITableView, 5000 ячеек

‣ В каждой ячейке label с кастомным шрифтом MetaPro-Normal, цвет текста с прозрачностью

‣ iPhone 4, Xcode Instruments -> CA Instrument

Core Text

42

Page 43: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Тест на скорость:‣ UITableView, 5000 ячеек

‣ В каждой ячейке label с кастомным шрифтом MetaPro-Normal, цвет текста с прозрачностью

‣ iPhone 4, Xcode Instruments -> CA Instrument

Core Text

~ 55–56 fpsUILabel

~ 60 fpsCore Text

43

Page 44: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Тест на скорость:‣ UITableView, 5000 ячеек

‣ В каждой ячейке label с кастомным шрифтом MetaPro-Normal, цвет текста с прозрачностью

‣ iPhone 4, Xcode Instruments -> CA Instrument

Core Text

~ 55–56 fpsUILabel

~ 60 fpsCore TextCore Text точно не

медленнее44

Page 45: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Содержание

• Основы Core Text

๏Маркируем области в тексте

• Два столбца• Обтекание текстом

45

Page 46: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

• Результаты поиска

• Кастомные ссылки в UILabel

➡И все это без UIWebView !

http://anyvoid.ru

46

Page 47: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

47

Page 48: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

• Создаём наследник UIView:

- selectWithPattern:(NSString *)pattern - метод, который будет создавать модель для маркировки указанного текста

- drawRect:(CGRect)rect - здесь будет непосредственная отрисовка текста с маркировкой

48

Page 49: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

[regexp enumerateMatchesInString: ... usingBlock:^(NSTextCheckingResult *result, ...) { // При совпадении куска текста с шаблоном:

// 1. Добавляем участок в список совпадений [ranges addObject: [NSValue valueWithRange: [result range]]];

// 2. Помечаем участок цветом в отдельной атрибутированной строке [attrTextMutable addAttribute: kCTForegroundColorAttributeName value: [UIColor redColor].CGColor range: [result range]]; }];

• Добавляем какой-нибудь атрибут к участкам, которые хотим выделить и сохраняем их в в self.ranges

49

Page 50: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

[regexp enumerateMatchesInString: ... usingBlock:^(NSTextCheckingResult *result, ...) { // При совпадении куска текста с шаблоном:

// 1. Добавляем участок в список совпадений [ranges addObject: [NSValue valueWithRange: [result range]]];

// 2. Помечаем участок цветом в отдельной атрибутированной строке [attrTextMutable addAttribute: kCTForegroundColorAttributeName value: [UIColor redColor].CGColor range: [result range]]; }];

• Добавляем какой-нибудь атрибут к участкам, которые хотим выделить, и сохраняем их в в self.ranges

50

Page 51: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

• В drawRect проходим по всем CTRun каждой строки и получаем их frame, если они входят в сохраненные участки

➡ При проверке подходит ли run обращаем внимание на то, что конец строки может разорвать CTRun => нужно проверять включение, а не совпадение

51

Page 52: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка

CFRange runCFRange = CTRunGetStringRange( run );

NSValue* parentRangeValue = [self parentForRange: runRange];if ( parentRangeValue ) {

// CTRun подходит, можно получить его frame и использовать это...

}

• Получаем frame рана с помощью CTRunGetTypographicBounds

• Осталось только что-нибудь добавить для выделения. . . .

• Маркированным участкам теперь соответствуют отдельные CTRun

52

Page 53: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Маркировка• Добавим кнопку, frame которой будет выглядеть следующим образом:

CGRect buttonFrame = CGRectMake( leftX - leftPadding, topY - leftPadding, runWidth + leftPadding + rightPadding, runHeight + bottomPadding + topPadding );

CGAffineTransform transform = CGAffineTransformMakeTranslation(0, rect.size.height);

transform = CGAffineTransformScale(1, -1);buttonFrame = CGRectApplyAffineTransform(transform, buttonFrame);

• Не забываем, что мы работали в преобразованной системе координат:

53

Page 54: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

МаркировкаМожно использовать нажатие кнопки для чего-нибудь

54

Page 55: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Содержание

• Основы Core Text

• Маркируем области в тексте

๏Два столбца

• Обтекание текстом

55

Page 56: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Два столбца делаются просто - выводим текст в нескольких CTFrame

- задаем CGPath для границ столбца

- чтобы определить, сколько текста вывели в предыдущем столбце, используем:

CFRange prevColTextRange = CTFrameGetVisibleStringRange(colFrames[columnIdx - 1]);

Два столбца

CGRect colRect = CGRectMake(originX, originY, colWidth, colHeight);CGPathAddRect(rectPath, NULL, colRect);

56

Page 57: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Два столбца делаются просто - выводим текст в нескольких CTFrame

- задаем CGPath для границ столбца

- чтобы определить, сколько текста вывели в предыдущем столбце, используем:

CFRange prevColTextRange = CTFrameGetVisibleStringRange(colFrames[columnIdx - 1]);

Два столбца

CGRect colRect = CGRectMake(originX, originY, colWidth, colHeight);CGPathAddRect(rectPath, NULL, colRect);

57

Page 58: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Содержание

• Основы Core Text

• Выделяем области в тексте

• Два столбца๏Обтекание текстом

58

Page 59: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Обтекание• Чтобы текст обтекал shape, нужно вырезать последний из основного фрейма

- Не нужно пытаться делать это через Core Graphics

- В Core Text есть специальные опции, которые задают вырезаемые области

59

Page 60: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Каждый вырезаемый CGPath задается через CFDictionaryRef

Обтекание

- (CFDictionaryRef)createClippingPathWithPath:(CGPathRef)pathRef { NSDictionary* ret = [NSDictionary dictionaryWithObject: (__bridge id)(pathRef) forKey: kCTFramePathClippingPathAttributeName]; return (__bridge CFDictionaryRef)(ret);}

60

Page 61: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

• Затем массив из CDictionaryRef ставится значением опции и передается в CTFrameSetterCreateFrame

frameOptionsDict = [NSDictionary dictionaryWithObject: clippingPaths

forKey: kCTFrameClippingPathsAttributeName];

Обтекание

CTFramesetterCreateFrame(..., (__bridge CFDictionaryRef)frameOptionsDict);

61

Page 62: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Apple Font Tool Suitehttps://developer.apple.com/fonts/

ftxdumperfuser -t hhea -A d Font.otf

ftxdumperfuser -t hhea -A f Font.otf

ascender="716"descender="-212"lineGap="219"

ascender="975"descender="-217"lineGap="29"

Custom font Helvetica Neue

62

Page 64: Core Text - cache-ash03.cdn.yandex.netcache-ash03.cdn.yandex.net/download.yandex.ru/... · Рецепты Юлии Высоцкой При нажатии на ссылку со временем

Кофе-брейк