iOS: как вы измеряете ширину и высоту строки, используя Quartz? - PullRequest
19 голосов
/ 27 мая 2009

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

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

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

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

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

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

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

Ответы [ 2 ]

22 голосов
/ 27 мая 2009

На 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:
0 голосов
/ 19 октября 2010

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

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

...