2012-05-05 6 views
33

Автомакет в Lion должен сделать его довольно простым, чтобы текстовое поле (и, следовательно, ярлык) расти с текстом, который он держит.Как разрешить NSTextField расти с текстом в автоматическом макете?

Текстовое поле настроено на обертку в Interface Builder.

Что такое простой и надежный способ сделать это?

ответ

42

Метод intrinsicContentSize в NSView возвращает то, что сам взгляд рассматривает как его собственный размер содержимого.

NSTextField рассчитывает это без учета свойства wraps его ячейки, поэтому он будет сообщать размеры текста, если он выложен на одной строке.

Следовательно, пользовательский подкласс NSTextField может переопределить этот метод, чтобы вернуть лучшее значение, например, от предусмотренного методом клетки cellSizeForBounds::

-(NSSize)intrinsicContentSize 
{ 
    if (![self.cell wraps]) { 
     return [super intrinsicContentSize]; 
    } 

    NSRect frame = [self frame]; 

    CGFloat width = frame.size.width; 

    // Make the frame very high, while keeping the width 
    frame.size.height = CGFLOAT_MAX; 

    // Calculate new height within the frame 
    // with practically infinite height. 
    CGFloat height = [self.cell cellSizeForBounds: frame].height; 

    return NSMakeSize(width, height); 
} 

// you need to invalidate the layout on text change, else it wouldn't grow by changing the text 
- (void)textDidChange:(NSNotification *)notification 
{ 
    [super textDidChange:notification]; 
    [self invalidateIntrinsicContentSize]; 
} 
+2

Это точно соответствует тому, что я вижу. Чтобы прояснить, это игнорирование свойства «обертывания» в ячейке кажется ошибкой в ​​Lion, которая была зафиксирована в Mountain Lion. Итак, если вы ориентируетесь на Lion и выше, вы увидите разные результаты в двух операционных системах, пока не примените исправление, чтобы привести Lion к скорости. –

+0

Да, это ошибка во Льве. Я действительно хочу, чтобы Apple исправила эти проблемы как в OS X 10.7 && 10.8. В моей реализации я делаю еще несколько проверок для особых случаев (например, если это Lion || Если язык не является английским), и я устанавливаю свою высоту немного иначе. Тем не менее, то, что опубликовал Моноло, - хорошее начало. – Arvin

+2

Метод intrinsicContentSize: не вызывается при изменении текста в нем с помощью setStringValue :. – ideawu

1

Принятый ответ основан на манипулировании intrinsicContentSize, но это может не обязательно во всех случаях. Autolayout будет расти и уменьшать высоту текстового поля, если (a) вы даете текстовое поле preferredMaxLayoutWidth и (b) сделайте поле не editable. Эти шаги позволяют текстовому полю определять его внутреннюю ширину и вычислять высоту, необходимую для автоматического отключения. См. this answer и this answer для более подробной информации.

Еще более неясно, из-за зависимости от атрибута текстового поля editable атрибут автоопределения будет нарушен, если вы используете привязки в поле и не можете очистить опцию Conditionally Sets Editable.

Смежные вопросы