Estoy tratando de colocar texto en una etiqueta de ancho fijo (en realidad, el ancho depende del tamaño de la pantalla, pero no puede cambiar dentro de la aplicación), y espero que UIKit use hábilmente una combinación de cambio de tamaño de fuente y ajuste de palabras para obtener el resultado adecuado. Sin embargo, no parece funcionar de esa manera. Considerando una UILabel con las siguientes restricciones:
y el siguiente código:
label.font = label.font.withSize(100) label.adjustsFontSizeToFitWidth = true label.lineBreakMode = .byClipping label.numberOfLines = 0 label.text = "Shooter team"
Esperaría que cambiara el tamaño del texto y lo hiciera encajar en dos líneas: "Tirador" y "equipo" (o, dado que el texto podría ser cualquier cosa, dividirlo correctamente en palabras). Sin embargo, cuando configuro label.lineBreakMode
en .byWordWrapping
, no cambia el tamaño del texto en absoluto, por lo que solo se muestra una letra grande (nota: estoy usando un tamaño de fuente grande para cambiar el tamaño porque no puedo saber de antemano el tamaño que va a tener el texto, ya que el tamaño depende del tamaño de la pantalla). Cualquier otro valor para .lineBreakMode
da como resultado que el texto cambie de tamaño pero se divida en "Shoote" y "r team", lo que parece tonto. Cambiar autoshrink
a, por ejemplo Minimum font size = 8
no parece tener ningún efecto. Vea la captura de pantalla a continuación.
¿Alguna sugerencia de cómo puedo obtener la división/cambio de tamaño adecuado? Puede que haya usado los términos incorrectos para mis búsquedas pero no he encontrado ninguna respuesta :-|
(Nota: habrá una pregunta diferente sobre cómo puedo hacer que el borde de la vista envolvente sea un círculo agradable antes de que se muestre la vista :-| )
En primer lugar, para aprovechar las ventajas de adjustsFontSizeToFitWidth
, también debe asignarle un factor de escala (el tamaño más pequeño al que está dispuesto a reducir la etiqueta). Entonces, si, por ejemplo, la fuente de su etiqueta tiene un tamaño de 30, puede dejar que se reduzca a 24:
someLabel.font = UIFont(name: "someFont", size: 30) someLabel.adjustsFontSizeToFitWidth = true someLabel.minimumScaleFactor = (24/30)
En segundo lugar, es posible que desee considerar el uso de un título con atributos para su etiqueta para aprovechar el estilo de párrafo. El estilo de párrafo te permite jugar con las reglas de separación silábica:
let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.hyphenationFactor = 1.0 let attributedTitle = NSAttributedString(string: "Shooter team", attributes: [NSAttributedString.Key.foregroundColor: UIColor.red, NSAttributedString.Key.paragraphStyle: paragraphStyle]) someLabel.attributedText = attributedTitle
A falta de una solución mejor, he escrito la siguiente función que intenta empíricamente encontrar un tamaño de fuente que no divida una palabra en el medio. Es un truco, pero al menos funciona... Comentarios, sugerencias o cualquier solución mejor, ¡bienvenidos!
func findFittingFont(for label: String) -> UIFont { // note: the 'split' function is a personal addition that splits a string on a regex // in this case, split between a non-word char and a word char let words = label.split(pattern: "(?<=\\W)(?=\\w)") var font = myLabel.font! // the width we don't want to overflow let maxWidth = myLabel.frame.width var fontSize = myLabel.frame.height var tooBig: Bool repeat { tooBig = false font = font.withSize(fontSize) // check for each word whether the rendered width is larger than the max width for word in words { // calculate the rendered width with the current font let width = (word as NSString).size(withAttributes: [.font: font]).width if width > maxWidth { tooBig = true // decrease the size by a factor fontSize *= 0.9 break } } // go on as long as there's an overflowing word } while tooBig return font }