2012-05-05 11 views

Respuesta

42

El método intrinsicContentSize en NSView devuelve lo que la vista misma considera como su tamaño de contenido intrínseco.

NSTextField calcula esto sin tener en cuenta la propiedad wraps de su celda, por lo que informará las dimensiones del texto si se establece en una sola línea.

Por lo tanto, una subclase personalizada de NSTextField puede reemplazar este método para volver un mejor valor, como el proporcionado por el método de la célula 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

Esto coincide exactamente con lo que estoy viendo. Solo para aclarar, este hecho de ignorar la propiedad 'wraps' en la celda parece ser un error en Lion que se ha solucionado en Mountain Lion. Entonces, si estás apuntando a Lion y más arriba, verás diferentes resultados en los 2 sistemas operativos hasta que apliques la corrección de errores para poner a Lion al tanto. –

+0

Sí, esto es un error en Lion. Realmente me gustaría que Apple solucione estos problemas tanto en OS X 10.7 como en 10.8. En mi implementación, realizo más comprobaciones para casos especiales (por ejemplo, si es Lion || Si el idioma no es inglés) y configuro mi altura un poco diferente. Sin embargo, lo que Monolo publicó es un buen comienzo. – Arvin

+2

El método intrinsicContentSize: no se invoca cuando se cambia el texto en él por setStringValue :. – ideawu

1

La respuesta aceptada se basa en la manipulación de intrinsicContentSize pero que pueden no será necesario en todos los casos. El diseño automático aumentará y reducirá la altura del campo de texto si (a) le asigna al campo de texto un preferredMaxLayoutWidth y (b) establece el campo no editable. Estos pasos permiten que el campo de texto determine su ancho intrínseco y calcule la altura necesaria para el diseño automático. Vea this answer y this answer para más detalles.

Aún más oscura, se deduce de la dependencia en el atributo editable del campo de texto que el autolayout se romperá si está utilizando enlaces en el campo y no borra la opción Conditionally Sets Editable.

Cuestiones relacionadas