Подтвердить что ты не робот

iOS: как вы измеряете ширину и высоту строки, используя Quartz?

Прежде чем я задам свои вопросы, это из документации Apple: как определить ширину строки с помощью Quartz:

Если измерения текста важны для вашего приложения, их можно рассчитать с помощью функций Quartz 2D. Тем не менее, вы могли бы сначала рассмотреть возможность использования ATSUI, сила которого заключается в разметке и измерении текста. ATSUI имеет несколько функций, которые получают текстовые метрики. Вы можете не только получить текстовые метрики после макета, но и в тех редких случаях, когда они вам нужны, вы можете получить текстовые метрики до макета. В отличие от кварца, для которого вы должны выполнить вычисления самостоятельно, ATSUI вычисляет измерения для вас. Например, вы можете получить ограничивающий прямоугольник изображения для текста, вызвав функцию ATSUI ATSUMeasureTextImage.

Если вы решите, что текст Quartz больше соответствует вашим потребностям, чем текст ATSUI (или Cocoa), вы можете выполнить следующие шаги, чтобы измерить ширину текста, прежде чем Quartz его прорисует:

  1. Вызовите функцию CGContextGetTextPosition, чтобы получить текущую позицию текста.
  2. Установите режим рисования текста на kCGTextInvisible, используя функцию CGContextSetTextDrawingMode.
  3. Нарисуйте текст, вызвав функцию CGContextShowText, чтобы нарисовать текст в текущей позиции текста.
  4. Определите окончательную позицию текста, вызвав функцию CGContextGetTextPosition.
  5. Вычтите начальную позицию из конечной позиции, чтобы определить ширину текста.

Вот мои вопросы:

  1. Это действительно лучший способ определить ширину строки с помощью Core Graphics? Это кажется неубедительным, и поскольку мой текст сосуществует с двухмерными графическими элементами, я хотел бы использовать один и тот же контекст для всего рендеринга. Я надеялся, что будет какой-то компактный метод, например:

    CGContextGetTextWidthAndHeight(context, text);
    
  2. Я читал, что ATSUI устарел и будет заменен Core Text. Это правда, и если да, то в iOS?

4b9b3361

Ответ 1

В iPhone SDK существует семейство методов на NSString, которые обеспечивают то, что вы хотите.

Начиная с iOS 7.0, эти методы::

- boundingRectWithSize:options:attributes:context:
- sizeWithAttributes:

В старых версиях iOS у нас были эти, теперь устарели:

– sizeWithFont:  
– sizeWithFont:forWidth:lineBreakMode:  
– sizeWithFont:constrainedToSize:  
– sizeWithFont:constrainedToSize:lineBreakMode:  
– sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:

Ответ 2

При выполнении операций рисования в потоках, отличных от потока пользовательского интерфейса, вы должны использовать описанную вами технику. Это особенно важно отметить при использовании таких вещей, как CATiledLayer, который выполняет его рендеринг асинхронно по фоновым потокам или при рисовании пользовательской графики в фоновом режиме по любой другой причине.

Я согласен с PGB, когда вы делаете "простую" графику, и вы гарантированно работаете в основном потоке. Тем не менее, sizeWithFont делает то же самое, что и описанный вами метод - он просто делает это для вас, используя UIGraphicsGetCurrentContext().