ios - teclado - Tamaño de fuente personalizado en clases de tamaño XCode6 que no funciona correctamente con fuentes personalizadas
tamaño de letra en html (14)
Después de probar todo, eventualmente decidí una combinación de las soluciones anteriores. Usando Xcode 7.2, Swift 2.
import UIKit
class LabelDeviceClass : UILabel {
@IBInspectable var iPhoneSize:CGFloat = 0 {
didSet {
if isPhone() {
overrideFontSize(iPhoneSize)
}
}
}
@IBInspectable var iPadSize:CGFloat = 0 {
didSet {
if isPad() {
overrideFontSize(iPadSize)
}
}
}
func isPhone() -> Bool {
// return UIDevice.currentDevice().userInterfaceIdiom == .Phone
return !isPad()
}
func isPad() -> Bool {
// return UIDevice.currentDevice().userInterfaceIdiom == .Pad
switch (UIScreen.mainScreen().traitCollection.horizontalSizeClass, UIScreen.mainScreen().traitCollection.verticalSizeClass) {
case (.Regular, .Regular):
return true
default:
return false
}
}
func overrideFontSize(fontSize:CGFloat){
let currentFontName = self.font.fontName
if let calculatedFont = UIFont(name: currentFontName, size: fontSize) {
self.font = calculatedFont
}
}
}
-
@IBInspectable
permite establecer el tamaño de fuente en el guión gráfico - Utiliza un observador
didSet
para evitar las trampas delayoutSubviews()
(bucle infinito para alturas de fila de la vista de tabla dinámica) yawakeFromNib()
(vea el comentario de @ cocoaNoob) - Utiliza clases de tamaño en lugar del idioma del dispositivo, con la esperanza de usarlo eventualmente con
@IBDesignable
- Lamentablemente,
@IBDesignable
no funciona contraitCollection
acuerdo con este otro artículo de pila - La instrucción de cambio de recopilación de rasgos se realiza en
UIScreen.mainScreen()
lugar deself
por este artículo de pila
Xcode 6 tiene una nueva función donde las fuentes y los tamaños de fuente en UILabel, UITextField y UIButton se pueden establecer automáticamente en función de la clase de tamaño de la configuración actual del dispositivo, directamente en el guión gráfico. Por ejemplo, puede configurar un UILabel para usar el tamaño de letra 12 en configuraciones de "cualquier ancho, altura compacta" (como en iPhones en horizontal) y en el tamaño 18 en configuraciones de "ancho regular, altura normal" (como en iPads). Más información está disponible aquí:
Esta es una característica muy buena en teoría porque podría hacer innecesario establecer programáticamente diferentes fuentes en las características de la interfaz de usuario basadas en la configuración del dispositivo. En este momento, tengo un código condicional que establece las fuentes según el tipo de dispositivo, pero obviamente eso significa que tengo que configurar las fuentes mediante programación en todas partes de la aplicación. Así que al principio estaba realmente entusiasmado con esta función, pero descubrí que tiene un problema grave en mi uso real (tal vez un error). Tenga en cuenta que estoy compilando contra el SDK 8 y estableciendo un objetivo de implementación mínimo para iOS 8, por lo que no tiene nada que ver con la compatibilidad con las versiones anteriores de iOS.
El problema es este: si configuro diferentes tamaños de fuente para diferentes clases de tamaño y uso la fuente "Sistema" proporcionada por iOS, todo funciona como se espera y los tamaños de fuente cambian según la clase de tamaño. Si uso una fuente personalizada proporcionada por mi aplicación (sí, la configuré correctamente en mi paquete de aplicaciones, ya que funciona programáticamente) y configuré la fuente personalizada en una etiqueta en un guión gráfico de XCode 6, eso también funciona como se esperaba. Pero cuando trato de usar diferentes tamaños de la fuente personalizada para diferentes clases de tamaño, en el guión gráfico, de repente no funciona. La única diferencia en la configuración es la fuente que he elegido (una personalizada frente a la fuente del sistema). En cambio, todas las fuentes aparecen en el dispositivo y el simulador como la fuente del sistema predeterminada en el tamaño predeterminado, independientemente de la clase de tamaño (y verifiqué a través del depurador que está sustituyendo la fuente del sistema por la actual especificada en el guión gráfico) . Así que, básicamente, la función de clase de tamaño parece estar rota para las fuentes personalizadas. Además, curiosamente, las fuentes personalizadas muestran y ajustan el tamaño correctamente en el panel "Vista previa" de XCode 6 para el controlador de vista: solo cuando se ejecuta en el sistema iOS real deja de funcionar (lo que me hace pensar que lo estoy configurando) correctamente).
Probé varias fuentes personalizadas diferentes y parece que no funciona para ninguna de ellas, pero siempre funciona si utilizo "Sistema".
De todos modos, ¿alguien más ha visto este problema en Xcode 6? ¿Alguna idea sobre si esto es un error en iOS 8, Xcode o algo que estoy haciendo mal? La única solución que he encontrado, como dije, es continuar configurando programáticamente las fuentes, como he estado haciendo con 3 versiones de iOS, porque eso funciona. Pero me encantaría poder utilizar esta función si pudiera hacerlo funcionar con fuentes personalizadas. Usar la fuente del sistema no es aceptable para nuestro diseño.
INFORMACIÓN ADICIONAL: A partir de Xcode 8.0, el error se corrigió.
El error sigue siendo válido en XCode 7.0 GM.
La solución de Razor28 causa bucles infinitos en algunos casos. Mi experiencia ha sido con usarlo junto con SwipeView .
En cambio, te sugiero que:
1) Subclase UILabel e invalidar setFont:
- (void)setFont:(UIFont *)font
{
font = [UIFont fontWithName:(@"Montserrat") size:font.pointSize];
[super setFont:font];
}
2) Establezca la clase personalizada de sus UILabels y luego configure las clases de tamaño de fuente usando la fuente del sistema
El problema sigue ahí es que no puede usar la función para establecer Fuentes para diferentes clases de tamaño desde el constructor de interfaz.
Simplemente configure la fuente según el dispositivo que desee, tal como se muestra a continuación:
if (Your Device is iPAd) //For iPad
{
[yourLabel setFont:[UIFont fontWithName:@"FontName" size:FontSize]];
}
else //For Other Devices then iPad
{
[yourLabel setFont:[UIFont fontWithName:@"FontName" size:FontSize]];
}
Esto funciona perfectamente en todos los dispositivos.
Este error (y otros relacionados con Xcode - Clases de tamaño) me causó un gran dolor recientemente, ya que tuve que pasar por un gran archivo de guiones gráficos que pirateaba las cosas.
Para cualquier otra persona en este puesto, me gustaría agregar algo sobre la respuesta de @ razor28 para aliviar el dolor.
En el archivo de encabezado de su subclase personalizada, use IBInspectable
para sus atributos de tiempo de ejecución. Esto hará que estos atributos sean accesibles desde el "Inspector de Atributos", visualmente justo arriba de la posición predeterminada para la configuración de fuentes.
Ejemplo de uso:
@interface MyCustomLabel : UILabel
@property (nonatomic) IBInspectable NSString *fontType;
@property (nonatomic) IBInspectable CGFloat iphoneFontSize;
@property (nonatomic) IBInspectable CGFloat ipadFontSize;
@end
Esto producirá muy útilmente esta salida:
Un beneficio adicional es que ahora no tenemos que agregar los atributos de tiempo de ejecución manualmente para cada etiqueta. Esto es lo más cerca que podría estar del comportamiento previsto de XCode. Con suerte, una solución adecuada está en camino con iOS 9 este verano.
Estoy usando Swift, XCode 6.4. Entonces esto es lo que hice
import Foundation
import UIKit
@IBDesignable class ExUILabel: UILabel {
@IBInspectable var fontName: String = "Default-Font" {
didSet {
self.font = UIFont(name: fontName, size:self.font.pointSize)
}
}
override func layoutSubviews() {
super.layoutSubviews()
self.font = UIFont(name: fontName, size:self.font.pointSize)
}
}
Goto Designer -> Identity Inspector -> Establezca la clase en ExUILabel
Luego vaya al inspector de atributos en el diseñador y establezca el nombre de la fuente.
He encontrado una solución aún más rápida (supongo que siempre usas tu fuente personalizada).
Cree una categoría para UILabel e inclúyala en los archivos que usan el guión gráfico erróneo con clases de tamaño y configuración de fuente dedicada para varias clases:
@implementation UILabel (FontFixForSizeClassesAppleBug)
- (void)layoutSubviews
{
[super layoutSubviews];
if([[UIFont systemFontOfSize:10].familyName isEqualToString:self.font.familyName]) {
//workaround for interface builder size classes bug which ignores custom font if various classes defined for label: http://.com/questions/26166737/custom-font-sizing-in-xcode6-size-classes-not-working-properly-w-custom-fonts
self.font = [UIFont fontWithName:@"YOUR_CUSTOM_FONT_NAME" size:self.font.pointSize];
}
}
@end
Simplemente use sus fuentes personalizadas en el guión gráfico. Cuando el intérprete con errores use la fuente del sistema en su lugar, esta categoría la cambiará a su fuente personalizada.
Ninguno de estos funcionó para mí, pero esto fue así. También necesita usar la fuente del sistema en IB
#import <UIKit/UIKit.h>
@interface UILabelEx : UILabel
@end
#import "UILabelEx.h"
#import "Constants.h"
@implementation UILabelEx
- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
[super traitCollectionDidChange: previousTraitCollection];
self.font = [UIFont fontWithName:APP_FONT size:self.font.pointSize];
}
@end
Todavía no hay una respuesta correcta firmada. Este código funciona bien para mí. Primero debe deshabilitar el tamaño de fuente para las clases de tamaño en el constructor de interfaz. En IB puede usar una fuente personalizada.
- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
[super traitCollectionDidChange: previousTraitCollection];
if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
|| self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass) {
self.textField.font = [UIFont fontWithName:textField.font.fontName size:17.f];
}
}
Tuve el mismo problema y encontré una solución no muy clara, ¡pero excelente!
- Primero establece el tamaño de fuente requerido en el guión gráfico con el nombre de la fuente del sistema.
- Luego, a esta etiqueta le asigna una etiqueta de 100 a 110 (o más, pero 10 siempre fue suficiente para mí en un controlador de vista).
- Luego coloque este código en el archivo fuente de su CV y no olvide cambiar el nombre de la fuente. Código en swift.
override func viewDidLayoutSubviews() { for i in 100...110 { if let label = view.viewWithTag(i) as? UILabel { label.font = UIFont(name: "RotondaC-Bold", size: label.font.pointSize) } } }
Una combinación de algunas de las últimas respuestas anteriores fueron útiles. Así es como resolví el error de IB a través de una extensión Swift UILabel:
import UIKit
// This extension is only required as a work-around to an interface builder bug in XCode 7.3.1
// When custom fonts are set per size class, they are reset to a small system font
// In order for this extension to work, you must set the fonts in IB to System
// We are switching any instances of ".SFUIDisplay-Bold" to "MuseoSans-700" and ".SFUIDisplay-Regular" to "MuseoSans-300" and keeping the same point size as specified in IB
extension UILabel {
override public func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if ((traitCollection.verticalSizeClass != previousTraitCollection?.verticalSizeClass) || traitCollection.horizontalSizeClass != previousTraitCollection?.horizontalSizeClass) {
//let oldFontName = "/(font.fontName)-/(font.pointSize)"
if (font.fontName == systemFontRegular) {
font = UIFont(name: customFontRegular, size: (font?.pointSize)!)
//xlog.debug("Old font: /(oldFontName) -> new Font: /(font.fontName) - /(font.pointSize)")
}
else if (font.fontName == systemFontBold) {
font = UIFont(name: customFontBold, size: (font?.pointSize)!)
//xlog.debug("Old font: /(oldFontName) -> new Font: /(font.fontName) - /(font.pointSize)")
}
}
}
}
Una solución similar a la de @ razor28, pero creo que es un poco más universal. Además, funciona bien en versiones anteriores de iOS
Solución rápida:
1) Establecer fuentes como sistema para clases de tamaño
2) Subclase UILabel y anula el método "layoutSubviews" como:
- (void)layoutSubviews
{
[super layoutSubviews];
// Implement font logic depending on screen size
if ([self.font.fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location == NSNotFound) {
NSLog(@"font is not bold");
self.font = [UIFont fontWithName:@"Custom regular Font" size:self.font.pointSize];
} else {
NSLog(@"font is bold");
self.font = [UIFont fontWithName:@"Custom bold Font" size:self.font.pointSize];
}
}
Por cierto, es una técnica muy conveniente para fuentes icónicas
Solución para UILabel
: mantenga el mismo tamaño de fuente en todas las clases de tamaño, pero en su lugar cambie la altura de la etiqueta en consecuencia en cada clase de tamaño. Su etiqueta debe tener autoshrink habilitado. Funcionó muy bien en mi caso.
- agregue las fuentes proporcionadas por la aplicación en su aplicación .plist
- agrega tu archivo .ttf al elemento 0
- Úselo [UIFont fontWithName: "example.ttf" size: 10]