Я пытаюсь получить прямоугольник для приписанной строки, но вызов boundingRectWithSize не учитывает размер, который я передаю, и возвращает прямоугольник с высотой в одну строку в отличие от большой высоты (это длинная строка). Я экспериментировал, передавая очень большое значение для высоты, а также 0, как в коде ниже, но возвращаемое прямоугольное значение всегда одинаково.
CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(300,0.0)
options:NSStringDrawingUsesDeviceMetrics
context:nil];
Это сломано, или мне нужно сделать что-то еще, чтобы вернуть прямоугольник для обернутого текста?
objective-c
nsattributedstring
RunLoop
источник
источник
lineBreakMode
?Ответы:
Похоже, вы не указали правильные параметры. Для упаковки этикеток предоставьте как минимум:
Примечание: если исходная ширина текста меньше 300.f, переноса строк не будет, поэтому убедитесь, что размер границы правильный, иначе вы все равно получите неправильные результаты.
источник
ceilf(paragraphRect.size.height)
так, чтобы он округлился. Я постоянно об этом забываю и удивляюсь, почему мои лейблы все еще обрезаются.boundingRectWithSize:
вычисления в CGRectIntegral (), которыйCGRectIntegral rounds the rectangle’s origin downward and its size upward to the nearest whole integers
в данном случае округляет высоту и ширину, чтобы исключить ограничение, если высота или ширина являются дробным значением.По какой-то причине boundingRectWithSize всегда возвращает неправильный размер. Я нашел решение. Для UItextView -sizeThatFits существует метод, который возвращает правильный размер для текстового набора. Поэтому вместо использования boundingRectWithSize создайте UITextView со случайным кадром и вызовите его sizeThatFits с соответствующей шириной и высотой CGFLOAT_MAX. Возвращает размер, который будет иметь правильную высоту.
Если вы вычисляете размер в цикле while, не забудьте добавить, что в пуле автоматического выпуска, так как будет создано n номеров UITextView, оперативная память приложения увеличится, если мы не используем autoreleasepool.
источник
UITextView
столько раз, сколько вызываетсяheightForRowAtIndexPath
метод, излишне? это занимает времяЭд МакМанус, безусловно, дал ключ к тому, чтобы заставить это работать. Я нашел случай, который не работает
прямоугольник не будет иметь правильную высоту. Обратите внимание, что anotherString (который добавляется к строке ) был инициализирован без словаря атрибутов. Это допустимый инициализатор для anotherString, но boundingRectWithSize: не дает точного размера в этом случае.
источник
NSMutableAttributedString
без атрибутов и получал неправильный размер.Мое окончательное решение после долгого исследования:
- boundingRectWithSize
функция возвращает правильный размер только для непрерывной последовательности символов! Если строка содержит пробелы или что-то еще (называемое Apple «Некоторые из глифов») - невозможно получить фактический размер прямоугольника, необходимый для отображения текста!Я заменил пробелы в моих строках буквами и сразу получил правильный результат.
Apple говорит здесь: https://developer.apple.com/documentation/foundation/nsstring/1524729-boundingrectwithsize
«Этот метод возвращает фактические границы глифов в строке. Некоторые глифы (например, пробелы) могут перекрывать ограничения макета, заданные передаваемым размером, поэтому в некоторых случаях значение ширины компонента размера возвращаемое значение
CGRect
может превышать значение ширины параметра размера. "Так что нужно найти какой-то другой способ вычислить реальный прямоугольник ...
После долгого процесса расследования решение наконец-то найдено !!! Я не уверен, что это будет работать хорошо во всех случаях, связанных с
UITextView
, но главное и главное было обнаружено!boundingRectWithSize
Функция, а такжеCTFramesetterSuggestFrameSizeWithConstraints
(и многие другие методы) будут правильно вычислять размер и часть текста при использовании правильного прямоугольника. Например -UITextView
имеетtextView.bounds.size.width
- и это значение не фактический прямоугольник, используемый системой при рисовании текстаUITextView
.Я нашел очень интересный параметр и выполнил простой расчет в коде:
И магия работает - все мои тексты рассчитаны правильно сейчас! Наслаждайтесь!
источник
Swift четыре версии
Измерение текста с помощью CTFramesetter работает лучше всего, поскольку обеспечивает целочисленные размеры и хорошо обрабатывает символы эмодзи и другие символы Юникода.
источник
Мне не повезло ни с одним из этих предложений. Моя строка содержала точки пули Unicode, и я подозреваю, что они приводят к горе в вычислениях. Я заметил, что UITextView отлично справлялся с рисованием, поэтому я обратился к нему, чтобы использовать его вычисления. Я сделал следующее, что, вероятно, не так оптимально, как методы рисования NSString, но, по крайней мере, это точно. Это также немного более оптимально, чем инициализация UITextView просто для вызова
-sizeThatFits:
.источник
В случае, если вы хотите получить ограничивающую рамку, обрезая хвост, этот вопрос может помочь вам.
источник
Оказывается, что КАЖДАЯ часть NSAttributedString должна иметь набор словаря, по крайней мере, с NSFontAttributeName и NSForegroundColorAttributeName, если вы хотите, чтобы boundingRectWithSize действительно работал!
Я не вижу этого нигде.
источник
@warrenm Извините, что метод фреймсеттера у меня не работает.
Я получил это. Эта функция может помочь нам определить размер кадра, необходимый для диапазона строк NSAttributedString в iphone / Ipad SDK для заданной ширины:
Может использоваться для динамической высоты ячеек UITableView.
Благодаря HADDAD ISSA >>> http://haddadissa.blogspot.in/2010/09/compute-needed-heigh-for-fixed-width-of.html
источник
#import <CoreText/CoreText.h>
Я обнаружил, что предпочтительное решение не обрабатывает разрывы строк.
Я обнаружил, что этот подход работает во всех случаях:
источник
У меня была та же проблема с не получением точного размера с использованием этих методов, и я изменил свой подход, чтобы заставить его работать.
У меня есть длинная атрибутивная строка, которую я пытался вписать в представление прокрутки, чтобы оно отображалось правильно, не обрезаясь. То, что я сделал, чтобы текст работал надежно, заключался в том, чтобы вообще не устанавливать высоту в качестве ограничения, а вместо этого позволял принимать внутренний размер. Теперь текст отображается правильно, без усечения, и мне не нужно рассчитывать высоту.
Я полагаю, что если бы мне нужно было надежно получить высоту, я бы создал вид, который скрыт, и эти ограничения и получу высоту кадра, как только ограничения будут применены.
источник
Я немного опаздываю к игре - но я пытался найти способ, который поможет найти ограничивающий прямоугольник, который поместится вокруг приписанной строки, чтобы создать фокусировочное кольцо, как при редактировании файла в Finder. все, что я пробовал, терпело неудачу, когда в конце строки есть пробелы или несколько строк внутри строки.
boundingRectWithSize
терпит неудачу для этого, а такжеCTFramesetterCreateWithAttributedString
.Использование
NSLayoutManager
следующего кода, похоже, помогает во всех обнаруженных мною случаях и возвращает прямоугольник, который идеально ограничивает строку. Бонус: если вы выделите текст, края выделенной области будут доходить до границ возвращаемого прямоугольника. Код ниже использует layoutManager изNSTextView
.источник
Работает на всех шрифтах отлично!
источник
У меня была та же проблема, но я понял, что ограниченная высота была установлена правильно. Итак, я сделал следующее:
источник
Я попробовал все на этой странице и все еще имел один случай для UILabel, который неправильно форматировал. На самом деле установка атрибутов на тексте, наконец, исправила проблему.
источник
Одна вещь, которую я заметил, состоит в том, что прямоугольник, который должен был вернуться
(CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(NSDictionary *)attributes context:(NSStringDrawingContext *)context
, имел бы большую ширину, чем то, что я передал. Когда это произошло, моя строка была бы обрезана. Я решил это так:Для некоторого большего контекста; У меня был многострочный текст, и я пытался найти правильную высоту, чтобы отобразить его. BoundRectWithSize иногда возвращал ширину, большую, чем я бы указал, таким образом, когда я использовал мое прошлое в ширину и вычисленную высоту, чтобы отобразить мой текст, он будет усекать. Из тестирования, когда boundingRectWithSize использовал неправильную ширину, величина, на которую она бы уменьшилась, составляла 1 строку. Поэтому я бы проверил, была ли ширина больше, и если да, то добавил бы lineHeight шрифта, чтобы обеспечить достаточно места, чтобы избежать усечения.
источник
если метка не добавит 10, этот метод никогда не сработает! надеюсь, это поможет вам! удачи
источник
}
источник
Я хотел бы добавить свои мысли, так как у меня была точно такая же проблема.
Я использовал,
UITextView
так как у него было более хорошее выравнивание текста (выровнять, чего в то время не было в наличииUILabel
), но для того, чтобы «симулировать» неинтерактивную и не прокручиваемуюUILabel
, я бы полностью отключил прокрутку, отскок и взаимодействие с пользователем ,Конечно, проблема заключалась в том, что текст был динамическим, и хотя ширина будет фиксированной, высоту следует пересчитывать каждый раз, когда я устанавливаю новое текстовое значение.
boundingRectWithSize
у меня ничего не получалось, насколько я вижу,UITextView
добавление некоторого поля сверху, котороеboundingRectWithSize
не попадало в счетчик, следовательно, полученная высотаboundingRectWithSize
была меньше, чем должна быть.Поскольку текст не должен был быстро обновляться, он просто используется для некоторой информации, которая может обновляться чаще всего каждые 2-3 секунды, поэтому я решил использовать следующий подход:
* Выше код не скопирован напрямую из моего источника, я должен был настроить его / очистить его от других вещей, которые не нужны для этой статьи. Не принимайте это за код "вставь и вставь".
Очевидным недостатком является то, что он имеет выделение и освобождение для каждого вызова.
Но, преимущество заключается в том, что вы избежите в зависимости от совместимости между тем, как boundingRectWithSize рисует текст и вычислил его размер и реализация текста чертежа в
UITextView
(илиUILabel
которые также можно использовать просто заменитьUITextView
сUILabel
). Таким образом можно избежать любых «ошибок», которые может иметь Apple.PS Может показаться, что вам не нужен этот «темп»,
UITextView
и вы можете просто спроситьsizeThatFits
непосредственно у цели, однако это не сработало для меня. Хотя логика сказала бы, что она должна работать, а выделение / выпуск временныхUITextView
не нужны, это не так. Но это решение работало безупречно для любого текста, который я бы включил.источник
Итак, я потратил много времени на отладку этого. Я обнаружил, что максимальная высота текста, определяемая параметром «
boundingRectWithSize
позволено отображать текст»,UITextView
была меньше, чем размер кадра.В моем случае размер кадра не более 140pt, но UITextView переносит текст не более 131pt.
Я должен был понять это вручную и жестко закодировать «реальную» максимальную высоту.
Вот мое решение:
источник