Вы не указали код, который вызывает вашу функцию heightForStringDrawing()
. Какую ширину вы предоставляете? Если это ширина текстового поля, это неправильно, потому что текст в текстовом поле не разрешается полностью переходить к краям текстового поля. Также есть горизонтальная прокладка.
В любом случае, есть более простой подход. Создайте текстовое поле, соответствующее свойствам той, которую вы пытаетесь измерить. Установите его stringValue
и font
. Установите его preferredMaxLayoutWidth
на доступную ширину. (Обратите внимание, что это касается выравнивания rect, а не прямоугольника. Используйте -alignmentRectForFrame:
, если вам нужно преобразовать.) Теперь спросите его о его intrinsicSize
. Затем вам необходимо преобразовать это из выравнивания rect в frame rect, используя -frameForAlignmentRect:
.
В зависимости от вашей ситуации вы можете дублировать существующее текстовое поле, архивируя и разгружая его, или вы можете загрузить NIB, который содержит его, чтобы получить его.
Один из способов получения текстового поля с необходимыми характеристиками, чтобы клонировать существующий:
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:_label];
NSTextField* clone = [NSKeyedUnarchiver unarchiveObjectWithData:data];
Чтобы рассчитать необходимую высоту кадра, чтобы поместиться в заданной ширины:
NSRect rect = { NSZeroPoint, NSMakeSize(desiredWidth, 100 /* arbitrary */) };
rect = [clone alignmentRectForFrame:rect];
clone.preferredMaxLayoutWidth = NSWidth(rect);
rect.size = clone.intrinsicContentSize;
rect = [clone frameForAlignmentRect:rect];
CGFloat resultingHeight = NSHeight(rect);
Теперь, в вашем скриншоте, высота строки должна быть выше высоты текстового поля, потому что там есть запас. Насколько высока зависимость от вашего макета. Поскольку вы упоминаете ограничения в своем комментарии, вы, вероятно, используете автоматическую компоновку. В этом случае поля (ограничения) будут фактически применены к выравниванию прямоугольника текстового поля. Итак, вы пропустили бы вторую в последнюю строку кода. То есть высота строки будет неотъемлемой высотой текстового поля (не скорректирована) плюс полями, налагаемыми вашими ограничениями.
Чтобы избежать большого количества этого материала при игре с полями, вы должны работать над полной иерархией представлений, соответствующей виду ячейки таблицы. Таким образом, вы напрямую загрузите представление таблицы NIB таблицы. Вы должны установить содержимое текстового поля, если это необходимо (и любое другое содержимое, которое требуется для просмотра в вашем представлении ячеек). Вы должны применить ограничение ширины к самому ядру ячейки, чтобы имитировать ширину столбца. Затем вы спросите вид ячейки для своего fittingSize
. Пусть система автоматического компоновки вычисляет общую высоту, включая поля и все, что подразумевается под вашими ограничениями, из содержимого.
Конечно, это работает только в том случае, если текстовое поле использует preferredMaxLayoutWidth
. В противном случае он не увеличит свою внутреннюю высоту в ответ на упаковку. Поскольку вы не хотите жестко кодировать предпочтительную ширину или размер полей, вы можете сделать два прохода.После установки содержимого элементов управления в виде ячеек и добавления ограничения ширины вызовите -layoutSubtreeIfNeeded
. Затем запросите рамку текстового поля, преобразуйте ее в прямоугольник выравнивания, установите preferredMaxLayoutWidth
в ширину выравнивания и только затем выполните запрос в виде ячейки fittingSize
.
'NSString * с = @ "слишком длинное строковое значение, чтобы положить его в комментарии";' 'NSFont * шрифт = [NSFont fontWithName: @ "Helvetica Neue" size: 13]; ' ' h = heightForStringDrawing (s, font, 100-4); ' Вот как я вызываю этот метод. 100 - ширина закругленного зеленого цвета. -4 из-за ограничений customView - текстовое поле (2 стороны). Я уже пробовал ваш подход, но он тоже не работает. Он возвращает еще более низкую высоту, чем требуется. – PawelPawel
Я обновил свой ответ. Я забыл отметить, что вам нужно преобразовать внутреннюю высоту из выравнивания rect в прямоугольник. –
@ Ąowski, я снова обновил свой ответ с примером кода. Я также описываю подход, использующий представление целой ячейки, поскольку он подвержен ошибкам воспроизводить ваши границы ограничений в коде. –