cocoa nstextfield autolayout

cocoa - ¿Cómo dejar que NSTextField crezca con el texto en el diseño automático?



autolayout (3)

El diseño automático en Lion debería hacer que sea bastante simple dejar que un campo de texto (y, por lo tanto, una etiqueta) crezca con el texto que contiene.

El campo de texto está configurado para envolver el Constructor de interfaz.

¿Cuál es una forma simple y confiable de hacer esto?


Swift 4

Editar Autosizing NSTextField

Basado en la publicación Objective-C de Peter Lapisu

Subclase NSTextField , agregue el código a continuación.

override var intrinsicContentSize: NSSize { // Guard the cell exists and wraps guard let cell = self.cell, cell.wraps else {return super.intrinsicContentSize} // Use intrinsic width to jive with autolayout let width = super.intrinsicContentSize.width // Set the frame height to a reasonable number self.frame.size.height = 750.0 // Calcuate height let height = cell.cellSize(forBounds: self.frame).height return NSMakeSize(width, height); } override func textDidChange(_ notification: Notification) { super.textDidChange(notification) super.invalidateIntrinsicContentSize() }

Al establecer self.frame.size.height en ''un número razonable'' se evitan algunos errores al usar FLT_MAX , CGFloat.greatestFiniteMagnitude o números grandes. Los errores se producen durante la operación cuando el usuario selecciona resalta el texto en el campo, puede arrastrar el desplazamiento hacia arriba y hacia abajo hasta el infinito. Además, cuando el usuario ingresa texto, NSTextField se NSTextField hasta que el usuario finaliza la edición. Finalmente, si el usuario ha seleccionado NSTextField y luego intenta cambiar el tamaño de la ventana, si el valor de self.frame.size.height es demasiado grande, la ventana se bloqueará.


La respuesta aceptada se basa en la manipulación de intrinsicContentSize pero eso puede no ser necesario en todos los casos. El diseño automático aumentará y reducirá la altura del campo de texto si (a) le otorga al campo de texto el valor de MaxLayoutWidth preferredMaxLayoutWidth y (b) no hace que el campo sea 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 esta respuesta y esta respuesta para más detalles.

Aún más oscuramente, 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 .


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

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

Por lo tanto, una subclase personalizada de NSTextField puede anular este método para devolver un mejor valor, como el proporcionado por el método cellSizeForBounds: la celda:

-(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]; }