2012-05-05 10 views

Odpowiedz

42

Metoda intrinsicContentSize w NSView zwraca, co sam widok uważa za swój wewnętrzny rozmiar zawartości.

NSTextField oblicza to bez uwzględnienia właściwości komórki wraps, więc zgłasza wymiary tekstu, jeśli jest ułożone w jednej linii.

Stąd zwyczaj podklasa NSTextField może zastąpić tę metodę, aby powrócić do lepszej jakości, jak to dostarczane przez komórki cellSizeForBounds: metody:

-(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

To dokładnie pasuje do tego, co widzę. Dla wyjaśnienia, ignorowanie własności "okładów" w komórce wydaje się być błędem w Lionie, który został naprawiony w Mountain Lion. Tak więc, jeśli celujesz w Lwa i powyżej, zobaczysz różne wyniki w 2 systemach operacyjnych, dopóki nie zastosujesz poprawki błędów, aby przyspieszyć działanie Lwa. –

+0

Tak, to błąd w Lion. Naprawdę chciałbym, aby Apple naprawił te problemy zarówno w OS X 10.7 i 10.8. W mojej implementacji robię jeszcze więcej kontroli dla przypadków specjalnych (np. Jeśli to Lion || Jeśli językiem nie jest angielski) i ustawiam swój wzrost trochę inaczej. Niemniej jednak to, co napisał Monolo, to dobry początek. – Arvin

+2

Metoda intrinsicContentSize: nie jest wywoływana, gdy zmienia się w niej tekst za pomocą metody setStringValue :. – ideawu

1

Zaakceptowanych odpowiedź opiera się na manipulacji intrinsicContentSize ale może nie jest konieczne we wszystkich przypadkach. Autolayout będzie się powiększał i zmniejszał wysokość pola tekstowego, jeśli (a) nadałeś polu tekstowemu preferredMaxLayoutWidth i (b) uczynisz pole nie editable. Te kroki umożliwiają polu tekstowemu określenie jego wewnętrznej szerokości i obliczenie wysokości wymaganej dla autolayout. Aby uzyskać więcej informacji, zobacz this answer i this answer.

Jeszcze bardziej niejasne, wynika z zależności od atrybutu pola tekstowego o numerze editable, że autolayout ulegnie zniszczeniu, jeśli używasz powiązań na tym polu i nie wyczyścisz opcji Conditionally Sets Editable.

Powiązane problemy