La cadena atribuida con fuentes personalizadas en el guión gráfico no se carga correctamente


100

Estamos utilizando fuentes personalizadas en nuestro proyecto. Funciona bien en Xcode 5. En Xcode 6, funciona en texto plano, cadena atribuida en código. Pero todas las cadenas atribuidas establecidas en el guión gráfico vuelven a Helvetica cuando se ejecutan en un simulador o dispositivo, aunque se ven bien en el guión gráfico.

No estoy seguro de si es un error de Xcode 6 o iOS 8 SDK, o la forma de usar fuentes personalizadas ha cambiado en Xcode 6 / iOS 8.


El mismo problema aqui. Me encantaría saber qué pasa.
obeattie

1
Por ahora, creamos un UILabel personalizado, llamado GLMarkdownLabel, y exportamos algunas propiedades con IBInspectable, luego establecimos cadenas de rebajas en el guión gráfico y traducimos las cadenas de rebajas a cadenas atribuidas cuando estamos despiertos desde la plumilla.
Allen Hsu

Ahora es una solución a largo plazo, espero que Apple solucione este error en la próxima versión de Xcode.
Allen Hsu

Vaya, qué tontería. Sin embargo, gracias por informarnos que no es un problema aislado. ¿Existe un radar?
obeattie

1
Nuestra solución fue eventualmente volver a usar IBCustomFonts para nuestras etiquetas atribuidas.
yonix

Respuestas:


30

La solución para mí fue usar una IBDesignableclase:

import UIKit

@IBDesignable class TIFAttributedLabel: UILabel {

    @IBInspectable var fontSize: CGFloat = 13.0

    @IBInspectable var fontFamily: String = "DIN Light"

    override func awakeFromNib() {
        var attrString = NSMutableAttributedString(attributedString: self.attributedText)
        attrString.addAttribute(NSFontAttributeName, value: UIFont(name: self.fontFamily, size: self.fontSize)!, range: NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

Dándote esto en el Interface Builder:

Fuente personalizada de Interface Builder con cadena atribuida

Puede configurar su cadena de atributos como lo hace normalmente, pero tendrá que configurar su tamaño de fuente y su familia de fuentes una vez más en las nuevas propiedades disponibles.

Como el Interface Builder está trabajando con la fuente personalizada de forma predeterminada, esto da como resultado que lo que ves es lo que obtienes , lo que prefiero al crear aplicaciones.

Nota

La razón por la que estoy usando esto en lugar de solo la versión simple es que estoy configurando propiedades en la etiqueta atribuida como el espacio entre líneas, que no están disponibles cuando se usa el estilo simple.


1
Su solución solo admite una familia de fuentes y un tamaño para una etiqueta, entonces, ¿por qué no usar simplemente texto sin formato?
Allen Hsu

De manera similar, usamos @IBInspectableatributos temporalmente, en lugar de fuente y tamaño. Tenemos una markdownTextpropiedad, porque la mayoría de las veces usamos cadenas atribuidas para texto en negrita o subrayado. Luego, analice el texto de la rebaja en una cadena atribuida con la información de fuente y tamaño configurada para texto sin formato.
Allen Hsu

@AllenHsu, tienes razón. No mencioné eso, pero estoy usando el espacio entre líneas atribuido para mi etiqueta. Por supuesto, de lo contrario, usaría el estilo simple :)
Antoine

Buen punto, también exportamos lineSpacing: p Creo que aceptaría su respuesta ya que en realidad es un error en Xcode, y no hay mejor solución por ahora. Esperemos la próxima versión de Xcode.
Allen Hsu

2
Esto no funcionará si quiero poner en negrita una parte del texto
xtrinch

28

La respuesta más simple que funcionó es arrastrar las fuentes a FontBook. Si las fuentes están en su proyecto pero no en el FontBook de su computadora, IB a veces tiene problemas para encontrarlas. Extraño, pero me ha funcionado en varias ocasiones.


17
Si bien esto permitirá que Xcode seleccione la fuente personalizada, en realidad no funciona. En tiempo de ejecución, la fuente no se utilizará como cabría esperar.
Daniel

Desafortunadamente, no pude encontrar una solución. Lo mejor que pude hacer fue registrar un error con Apple.
Daniel

Sí, esta es la solución. Otro desarrollador diseñó mi guión gráfico, svn update ok, pero nunca obtuve la fuente en la interfaz de usuario. La fuente estaba en los recursos pero no se mostraba en la interfaz de usuario del dispositivo / simulador. Como usa cadena atribuida, debo tenerla en Font Book. Eso resuelve el problema.
karim

Si. esto me ayuda a resolver el mismo problema. Cuando agrego una fuente personalizada en el libro de fuentes, las cosas funcionan a la perfección.
Sushant Jagtap

1
Si bien esta solución funciona en algunos casos, también me he enfrentado al mismo problema que @Daniel en el mismo proyecto con la misma familia de fuentes. XCode necesita solucionar este problema.
dey.shin

16

Puede agregar fuentes personalizadas al libro de fuentes.

Paso 1 : haga clic en administrar fuentes. Abre el libro de fuentes.

ingrese la descripción de la imagen aquí

Paso 2 : haga clic en más y agregue sus fuentes.

ingrese la descripción de la imagen aquí

La próxima vez que haga clic en la fuente con texto atribuido, la fuente recién agregada también se mostrará en la lista. Pero asegúrese de que su fuente personalizada se agregue en info.plist y agrupe los recursos.


Esto funciona en el guión gráfico, pero después de ejecutarlo no muestra el formato
Van

1
@Van formateo? ¿Puedes contarme más? ¿Cuándo no funciona?
Mahbaleshwar hegde

Tengo que configurar el texto que es una combinación de rgualr y fuente en negrita. Usé la solución anterior, por lo que funcionó en el guión gráfico, pero cuando ejecuto la aplicación, la etiqueta no muestra la fuente aplicada, sino la fuente del sistema
Van

¿Agregó sus fuentes personalizadas en info.plist? Después de eso, solo imprima todas las familias de fuentes
mahbaleshwar hegde

2
si. Puedo configurar la fuente personalizada en toda la aplicación en caso de texto sin formato, necesito configurar el texto atribuido
Van

5

Gracias a este hilo, he llegado a esta solución:

private let fontMapping = [
    "HelveticaNeue-Medium": "ITCAvantGardePro-Md",
    "HelveticaNeue": "ITCAvantGardePro-Bk",
    "HelveticaNeue-Bold": "ITCAvantGardePro-Demi",
]

func switchFontFamily(string: NSAttributedString) -> NSAttributedString {
    var result = NSMutableAttributedString(attributedString: string)
    string.enumerateAttribute(NSFontAttributeName, inRange: NSRange(location: 0, length: string.length), options: nil) { (font, range, _) in
        if let font = font as? UIFont {
            result.removeAttribute(NSFontAttributeName, range: range)
            result.addAttribute(NSFontAttributeName, value: UIFont(name: fontMapping[font.fontName]!, size: font.pointSize)!, range: range)
        }
    }
    return result
}

1
Buena idea. Es realmente increíble que esto esté roto en Apple. Asombroso.
Fattie

4

Mi solución es un poco complicada. La verdadera solución es que Apple arregle Interface Builder.

Con él, puede marcar todo el texto en negrita y cursiva en el generador de interfaces usando una fuente del sistema, luego, en tiempo de ejecución, renderizar su fuente personalizada. Puede que no sea óptimo en todos los casos.

 NSMutableAttributedString* ApplyCustomFont(NSAttributedString *attributedText,
                     UIFont* boldFont,
                     UIFont* italicFont,
                     UIFont* boldItalicFont,
                     UIFont* regularFont)
{

    NSMutableAttributedString *attrib = [[NSMutableAttributedString alloc] initWithAttributedString:attributedText];
    [attrib beginEditing];
    [attrib enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, attrib.length) options:0
                    usingBlock:^(id value, NSRange range, BOOL *stop)
    {
        if (value)
        {
            UIFont *oldFont = (UIFont *)value;
            NSLog(@"%@",oldFont.fontName);

            [attrib removeAttribute:NSFontAttributeName range:range];

            if([oldFont.fontName rangeOfString:@"BoldItalic"].location != NSNotFound && boldItalicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldItalicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Italic"].location != NSNotFound && italicFont != nil)
                [attrib addAttribute:NSFontAttributeName value:italicFont range:range];
            else if([oldFont.fontName rangeOfString:@"Bold"].location != NSNotFound && boldFont != nil)
                [attrib addAttribute:NSFontAttributeName value:boldFont range:range];
            else if(regularFont != nil)
                [attrib addAttribute:NSFontAttributeName value:regularFont range:range];
        }
    }];
    [attrib endEditing];

    return attrib;
}

Inspirado por esta publicación


4

He tenido problemas con este error: UILabel se muestra correctamente en IB con una fuente personalizada pero no se muestra correctamente en el dispositivo o simulador (la fuente está incluida en el proyecto y se usa en UILabels simples).

Finalmente encontré Attributed String Creator en (Mac) App Store. Genera código para colocarlo en su aplicación en el lugar apropiado. Fantástico. No soy el creador, solo un usuario feliz.


3

Resolvió el mismo problema: la fuente de atributo establecida para TextView en el guión gráfico no funcionó en tiempo de ejecución con XCode 6.1 y iOS 8 SDK.

Así es como resolví este problema, podría ser una solución para usted:

  1. abra el inspector de atributos de su vista de texto, cambie el texto a "Sin formato"

  2. haga clic en la cruz para eliminar el "wC hR" (rojo a continuación)

    ingrese la descripción de la imagen aquí

  3. cambie el texto a "Atribuido", y luego podrá establecer la fuente y el tamaño de su texto.

  4. corre para comprobar si funciona

Parece que por defecto no hay ninguna wC hRpropiedad establecida, ni UILabeltampoco UITextView.
Allen Hsu

por xcode 6, ¿estableciste otro tipo de alto-ancho, como "Ancho regular | Cualquier alto", "Ancho compacto | Alto regular"? Debido a que tengo un proyecto desarrollado en Xcode 5 y su vista de texto atribuida funciona incluso con iOS 8 SDK, verifiqué la configuración y encontré que la única diferencia es que Xcode 6 permite a los usuarios configurar la fuente para diferentes tamaños de dispositivos si configura el texto en "Llanura". Esta nueva configuración podría ser la razón por la que configurar el texto en "atribuido" pero la fuente no funciona.
Zhihao Yang

1
¿estás usando fuentes personalizadas? Me refiero a las autoincrustadas, no a las fuentes del sistema.
Allen Hsu

Ajá, pensé que las fuentes "personalizadas" que mencionaste son las que ofrece Xcode siempre que tenga la fuente "Sistema".
Zhihao Yang

No me funciona. Funciona para cadenas normales pero no para cadenas atribuidas.
Pratik Somaiya


2

Prueba esto, funcionará

En mi caso, cuando intento establecer "Tecnología Silversky" como texto atribuido para la etiqueta del generador de interfaz, no se muestra cuando ejecuto el simulador, pero se muestra en el generador de interfaz. Así que utilicé un truco: hice la fuente Silversky con 1 píxel más grande que el texto de Tecnología.

El texto de atributo tiene un problema con el mismo tamaño de fuente, así que cambie el tamaño de 1 palabra, esto funciona conmigo.

Puede ser que este sea un error de xcode, pero este truco funciona para mí.


1

El mismo problema.

Resuelto: simplemente marque Seleccionable en TextView. Sin esto, tengo la fuente estándar del sistema.



1

La solución @Hamidptb funciona, asegúrese de obtener el nombre correcto de la fuente (una vez que la haya agregado al Libro de fuentes)

  • Abra la aplicación Libro de fuentes, navegue hasta su fuente y luego presione Comando + I. El nombre de PostScript es el nombre de la fuente que desea utilizar aquí:

    UILabel.appearance (). Font = UIFont (nombre: " PostScriptName ", tamaño: 17)


0

Estaba tratando de obtener celdas tableView con texto que tiene varios párrafos. Las cadenas atribuidas parecían ser una forma de obtener espacio adicional entre los párrafos (algo un poco más atractivo que hacer dos avances de línea en la cadena). Encontré esta y otras publicaciones cuando descubrí que la configuración de IB no se aplicaba en el tiempo de ejecución cuando deseaba poner texto diferente en la celda.

Lo principal que se me ocurrió fue agregar una extensión a String (usando Swift) para crear una cadena atribuida con ciertas características. El ejemplo aquí usa la fuente Marker Felt, ya que se distingue fácilmente de Helvetica. El ejemplo también muestra un poco más de espacio entre párrafos para hacerlos más distintos entre sí.

extension String {
func toMarkerFelt() -> NSAttributedString {
    var style = NSMutableParagraphStyle()
    style.paragraphSpacing = 5.0
    let markerFontAttributes : [NSObject : AnyObject]? = [
        NSFontAttributeName : UIFont(name: "Marker Felt", size: 14.0)!,
        NSParagraphStyleAttributeName: style,
        NSForegroundColorAttributeName : UIColor.blackColor()
    ]
    let s = NSAttributedString(string: self, attributes: markerFontAttributes)
    return s
    }
}

Luego, en mi tableViewCell personalizado, le envía el texto que desea y lo convierte en una cadena atribuida en UILabel.

//  MarkerFeltCell.swift
class MarkerFeltCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
func configureCellWithString(inputString : String) {
    myLabel.attributedText = inputString.toMarkerFelt()
}}

En el controlador de vista con tableView, debe registrar su celda en viewDidLoad (); utilicé una plumilla, así que algo como:

let cellName = "MarkerFeltCell"
tableView.registerNib(UINib(nibName: cellName, bundle: nil), forCellReuseIdentifier: cellName)

Para que la celda determine qué tan alta debe ser, cree una celda prototipo que se use para obtener información sobre el tamaño y que nunca se agregue a tableView. Entonces, en las variables de su controlador de vista:

var prototypeSummaryCell : MarkerFeltCell? = nil

Luego, en (probablemente anular, dependiendo de su controlador de vista) heightForRowAtIndexPath:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        // ...
    if xib == "MarkerFeltCell" {
            if prototypeCell == nil {
                prototypeCell = tableView.dequeueReusableCellWithIdentifier(xib) as? MarkerFeltCell
            }
            let width : CGFloat = tableView.bounds.width
            let height : CGFloat = prototypeCell!.bounds.height
            prototypeCell?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
            configureCell(prototypeCell!, atIndexPath: indexPath)
            prototypeSummaryCell?.layoutIfNeeded()
            let size = prototypeSummaryCell!.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
            let nextHeight : CGFloat = ceil(size.height + 1.0)
            return nextHeight
    } else {  // ...

En el código anterior, prototypeCell se completará la primera vez que se necesite. El prototypeCell se usa para calcular la altura de la celda después de pasar por el proceso de tamaño automático. Deberá redondear la altura con la función ceil (). También agregué un factor extra de dulce de azúcar.

El bit de código final es cómo configura el texto para la celda. Para este ejemplo, simplemente:

func configureCell(cell :UITableViewCell, atIndexPath indexPath: NSIndexPath) {
    if let realCell = cell as? MarkerFeltCell  {
        realCell.configureCellWithString("Multi-line string.\nLine 2.\nLine 3.")    // Use \n to separate lines
    }
}

Además, aquí hay una foto de la punta. Fijó la etiqueta a los bordes de la celda (con el margen deseado), pero usó una restricción "Mayor o igual que", con una prioridad menor que "Requerida" para la restricción inferior.

Restricciones de celda

Establezca la fuente de la etiqueta en Atribuida. La fuente IB real no importaba.

LabelFont

El resultado en este caso:

CellResults


0

En el caso de una cadena atribuida, puede agregar una fuente personalizada en la lista de fuentes como: haga clic en el icono de fuente, esto mostrará el siguiente cuadro de diálogo. En el siguiente cuadro de diálogo, puede agregar su propia categoría o una existente para la fuente personalizada. diálogo de fuente atribuida

Después de hacer clic en Administrar fuentes, se abre el siguiente cuadro de diálogo para seleccionar la categoría en la que creó o en la existente. Haga clic en el signo + para agregar una fuente en la categoría. Administrar cuadro de diálogo de fuente


0

eso tiene una solución simple y rápida y eso funciona en mi caso. esa solución es agregar una línea de código en didFinishLaunchingWithOptions func en el archivo AppDelegate.swift:

para textViews :

UITextView.appearance().font = UIFont(name: "IranSans", size: 17)

para etiquetas :

UILabel.appearance().font = UIFont(name: "IranSans", size: 17)

y para el resto de UiView como este dos ☝️


0

Para cualquiera que aplique fuentes personalizadas a una cadena atribuida en el código: intente configurarlo viewDidLayoutSubviews. Mi error fue hacerlo viewDidLoad, no se aplicará allí.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.