ios - para - que es link en html
Etiqueta multilĂnea en UIStackView (17)
Al colocar la etiqueta de varias líneas (con el salto de línea establecido en Word Wrap) en una vista de pila, la etiqueta pierde inmediatamente el salto de línea y muestra el texto de la etiqueta en una línea.
¿Por qué sucede esto y cómo se conserva la etiqueta multilínea dentro de una vista de pila?
Aquí hay un ejemplo completo de un
UIStackView
vertical compuesto por
UILabel
s
UILabel
con altura automática.
Las etiquetas se ajustan según el ancho de la vista de pila y la altura de la vista de pila se basa en la altura de la etiqueta.
(Con este enfoque, no necesita incrustar las etiquetas en una
UIView
.)
(Swift 5, iOS 12.2)
// A vertical stackview with multiline labels and automatic height.
class ThreeLabelStackView: UIStackView {
let label1 = UILabel()
let label2 = UILabel()
let label3 = UILabel()
init() {
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
self.axis = .vertical
self.distribution = .fill
self.alignment = .fill
label1.numberOfLines = 0
label2.numberOfLines = 0
label3.numberOfLines = 0
label1.lineBreakMode = .byWordWrapping
label2.lineBreakMode = .byWordWrapping
label3.lineBreakMode = .byWordWrapping
self.addArrangedSubview(label1)
self.addArrangedSubview(label2)
self.addArrangedSubview(label3)
// (Add some test data, a little spacing, and the background color
// make the labels easier to see visually.)
self.spacing = 1
label1.backgroundColor = .orange
label2.backgroundColor = .orange
label3.backgroundColor = .orange
label1.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi."
label2.text = "Hello darkness my old friend..."
label3.text = "When I wrote the following pages, or rather the bulk of them, I lived alone, in the woods, a mile from any neighbor, in a house which I had built myself, on the shore of Walden Pond, in Concord, Massachusetts, and earned my living by the labor of my hands only."
}
required init(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
}
Aquí hay un ejemplo de
ViewController
que lo usa.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let myLabelStackView = ThreeLabelStackView()
self.view.addSubview(myLabelStackView)
// Set stackview width to its superview.
let widthConstraint = NSLayoutConstraint(item: myLabelStackView, attribute: NSLayoutConstraint.Attribute.width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: self.view, attribute: NSLayoutConstraint.Attribute.width, multiplier: 1, constant: 0)
self.view.addConstraints([widthConstraint])
}
}
¡Lo que funcionó para mí!
stackview: alineación: relleno, distribución: relleno, restricción del ancho proporcional a la supervista ej. 0.8,
etiqueta: centro y líneas = 0
Agregar propiedades
UIStackView
,
stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.axis = .horizontal
En lugar de agregar una etiqueta dentro de
UIView
cual no es necesario. Si está usando
UITableViewCell
, vuelva a cargar los datos en la rotación.
Después de probar todas las sugerencias anteriores, no encontré ningún cambio de propiedades para UIStackView. Solo cambio las propiedades de UILabels de la siguiente manera (las etiquetas ya se han agregado a una vista de pila vertical):
Swift 4 ejemplo:
[titleLabel, subtitleLabel].forEach(){
$0.numberOfLines = 0
$0.lineBreakMode = .byWordWrapping
$0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
}
El diseño del sistema debe determinar el origen, el ancho y la altura para dibujar sus subvistas, en este caso todas sus subvistas tienen la misma prioridad, ese punto genera conflicto, el sistema de diseño no conoce las dependencias entre las vistas, cuál dibuja primero, segundo, etc.
Establecer compresión de subvistas de pila resolverá el problema con varias líneas, dependiendo de que su vista de pila sea horizontal o vertical y cuál desea que se convierta en varias líneas.
stackOtherSubviews .setContentCompressionResistancePriority(.defaultHight, for: .horizontal)
lblTitle.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
El truco de magia para mí fue establecer un
widthAnchor
de
widthAnchor
al
UIStackView
.
La configuración de
leadingAnchor
y
trailingAnchor
no funcionará, pero la configuración de
centerXAnchor
y
widthAnchor
hizo que UILabel se visualizara correctamente.
En mi caso, seguí las sugerencias anteriores, pero mi texto seguía truncado en una sola línea, aunque solo en horizontal.
Resulta que encontré un carácter nulo
/0
invisible en el texto de la etiqueta que era el culpable.
Debe haberse introducido junto con el símbolo del guión que había insertado.
Para ver si esto también está sucediendo en su caso, use Ver depurador para seleccionar su etiqueta e inspeccionar su texto.
Es casi como la Respuesta de @ Andy, pero puede agregar su
UILabel
en
UIStackview
adicional, vertical funcionó para mí.
La configuración del PreferredMaxLayoutWidth a UILabel me funcionó
self.myLabel.preferredMaxLayoutWidth = self.bounds.size.width;
La respuesta correcta está aquí: https://.com/a/43110590/566360
-
Incrustar el
UILabel
dentro de unaUIView
(Editor -> Incrustar en -> Ver)-
Use restricciones para ajustar
UILabel
aUIView
(por ejemplo, espacio final, espacio superior y espacio inicial para supervisar restricciones)
-
Use restricciones para ajustar
El
UIStackView
estirará el
UIView
para que se ajuste correctamente, y el
UIView
restringirá el
UILabel
a varias líneas.
La siguiente es una implementación de Playground de una etiqueta de varias líneas con un salto de línea dentro de un
UIStackView
.
No requiere incrustar el
UILabel
dentro de nada y ha sido probado con Xcode 9.2 y Swift 4. Espero que sea útil.
import UIKit
import PlaygroundSupport
let containerView = UIView()
containerView.frame = CGRect.init(x: 0, y: 0, width: 400, height: 500)
containerView.backgroundColor = UIColor.white
var label = UILabel.init()
label.textColor = .black
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "This is an example of sample text that goes on for a long time. This is an example of sample text that goes on for a long time."
let stackView = UIStackView.init(arrangedSubviews: [label])
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
containerView.addSubview(stackView)
stackView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalTo: containerView.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true
PlaygroundPage.current.liveView = containerView
Para cualquiera que todavía no pueda hacer que funcione. Intente configurar Autoshrink con una Escala de fuente mínima en ese UILabel.
Captura de pantalla de la configuración de UILabel Autoshrink
Para una vista de pila horizontal que tiene una
UILabel
como una de sus vistas, en Interface Builder primero configure
label.numberOfLines = 0
.
Esto debería permitir que la etiqueta tenga más de 1 línea.
Inicialmente, esto no funcionó para mí cuando la vista de la pila tenía
stackView.alignment = .fill
.
Para que funcione, simplemente configure
stackView.alignment = .center
.
La etiqueta ahora puede expandirse a varias líneas dentro de
UIStackView
.
La documentación de Apple dice
Para todas las alineaciones, excepto la alineación de relleno, la vista de pila utiliza la propiedad de Tamaño de contenido intrínseco de cada vista organizada al calcular su tamaño perpendicular al eje de la pila
Tenga en cuenta la palabra,
excepto
aquí.
Cuando se utiliza
UIStackView
, el
UIStackView
horizontal NO
UIStackView
tamaño verticalmente usando los tamaños de subvistas organizados.
Xcode 9.2:
Simplemente establezca el número de líneas en 0. Storyboard se verá extraño después de configurar esto. No te preocupes, ejecuta el proyecto. Mientras se ejecuta, todo cambiará de tamaño de acuerdo con la configuración de su guión gráfico. Creo que es un tipo de error en el guión gráfico.
Consejos: establezca "número de revestimiento en 0" en el último. reinícielo cuando desee editar alguna otra vista y configúrelo en 0 después de la edición.
iOS 9+
Llame a
[textLabel sizeToFit]
después de configurar el texto de UILabel.
sizeToFit rediseñará la etiqueta multilínea con el ancho máximo preferido. La etiqueta redimensionará el stackView, que redimensionará la celda. No se requieren restricciones adicionales además de fijar la vista de pila a la vista de contenido.
- Primero establezca el número de etiqueta de líneas en 0
-
La vista de pila aún no crecerá a
multiLine
menos que le des un ancho fijo. Cuando arreglamos su ancho, se rompe a multilínea cuando se alcanza ese ancho como se muestra:
Si no le damos un ancho fijo a la vista de la pila, las cosas se vuelven ambiguas. ¿Cuánto tiempo crecerá la vista de pila con la etiqueta (si el valor de la etiqueta es dinámico)?
Espero que esto pueda solucionar tu problema.