tipos - tamaño de letra html
Analizando HTML en NSAttributedText-¿cómo configurar la fuente? (13)
Estoy tratando de obtener un fragmento de texto que está formateado en html para mostrar bien en un iPhone en una UITableViewCell.
Hasta ahora tengo esto:
NSError* error;
NSString* source = @"<strong>Nice</strong> try, Phil";
NSMutableAttributedString* str = [[NSMutableAttributedString alloc] initWithData:[source dataUsingEncoding:NSUTF8StringEncoding]
options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]}
documentAttributes:nil error:&error];
Este tipo de obras ¡Recibo un texto que tiene ''Agradable'' en negrita! Pero ... ¡también establece que la fuente sea Times Roman! Esta no es la cara tipográfica que quiero. Estoy pensando que necesito establecer algo en el documento Atributo, pero no puedo encontrar ningún ejemplo en ninguna parte.
De hecho, encontré una solución funcional a este problema:
Cambiar la fuente en su cadena de respuesta HTML antes de que se analice.
NSString *aux = [NSString stringWithFormat:@"<span style=/"font-family: YOUR_FONT_NAME; font-size: SIZE/">%@</span>", htmlResponse];
Ejemplo:
NSString *aux = [NSString stringWithFormat:@"<span style=/"font-family: HelveticaNeue-Thin; font-size: 17/">%@</span>", [response objectForKey:@"content"]];
Versión Swift:
let aux = "<span style=/"font-family: YOUR_FONT_NAME; font-size: SIZE/">/(htmlResponse)</span>"
El uso de NSHTMLTextDocumentType es lento y difícil de controlar los estilos. Te sugiero que pruebes mi biblioteca, que se llama Atributika. Tiene su propio analizador muy rápido. También puede tener cualquier nombre de etiqueta y definir cualquier estilo para ellos.
Ejemplo:
let str = "<strong>Nice</strong> try, Phil".style(tags:
Style("strong").font(.boldSystemFont(ofSize: 15))).attributedString
label.attributedText = str
Puede encontrarlo aquí https://github.com/psharanda/Atributika
En realidad, existe una forma aún más fácil y más limpia. Simplemente configure la fuente después de analizar el HTML:
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]
options:@{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
documentAttributes:nil error:nil];
[text addAttributes:@{NSFontAttributeName: [UIFont fontWithName:@"Lato-Regular" size:20]} range:NSMakeRange(0, text.length)];
Gracias por las respuestas, realmente me gustó la extensión, pero aún no me he convertido. Para aquellos estudiantes de escuela vieja que todavía están en Objective-C esto debería ayudar un poco: D
-(void) setBaseFont:(UIFont*)font preserveSize:(BOOL) bPreserve {
UIFontDescriptor *baseDescriptor = font.fontDescriptor;
[self enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, [self length]) options:0 usingBlock:^(id _Nullable value, NSRange range, BOOL * _Nonnull stop) {
UIFont *font = (UIFont*)value;
UIFontDescriptorSymbolicTraits traits = font.fontDescriptor.symbolicTraits;
UIFontDescriptor *descriptor = [baseDescriptor fontDescriptorWithSymbolicTraits:traits];
UIFont *newFont = [UIFont fontWithDescriptor:descriptor size:bPreserve?baseDescriptor.pointSize:descriptor.pointSize];
[self removeAttribute:NSFontAttributeName range:range];
[self addAttribute:NSFontAttributeName value:newFont range:range];
}]; }
Feliz Codificación! - Marco Greg
Las respuestas sobre todo funcionan bien si está haciendo la conversión al mismo tiempo que crea NSAttributedString
. Pero creo que una mejor solución, que funciona en la cadena misma y, por lo tanto, no necesita acceder a la entrada, es la siguiente categoría:
extension NSMutableAttributedString
{
func convertFontTo(font: UIFont)
{
var range = NSMakeRange(0, 0)
while (NSMaxRange(range) < length)
{
let attributes = attributesAtIndex(NSMaxRange(range), effectiveRange: &range)
if let oldFont = attributes[NSFontAttributeName]
{
let newFont = UIFont(descriptor: font.fontDescriptor().fontDescriptorWithSymbolicTraits(oldFont.fontDescriptor().symbolicTraits), size: font.pointSize)
addAttribute(NSFontAttributeName, value: newFont, range: range)
}
}
}
}
Usar como:
let desc = NSMutableAttributedString(attributedString: *someNSAttributedString*)
desc.convertFontTo(UIFont.systemFontOfSize(16))
Funciona en iOS 7+
Lo averigué. Como un oso, y tal vez no sea la mejor respuesta.
Este código pasará por todos los cambios de fuente. Sé que está usando "Times New Roman" y "Times New Roman BoldMT" para las fuentes. Pero independientemente, esto encontrará las fuentes en negrita y me permitirá restablecerlas. También puedo restablecer el tamaño mientras estoy en ello.
Honestamente espero / creo que hay una manera de configurar esto en tiempo de análisis, pero no puedo encontrarlo si lo hay.
NSRange range = (NSRange){0,[str length]};
[str enumerateAttribute:NSFontAttributeName inRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(id value, NSRange range, BOOL *stop) {
UIFont* currentFont = value;
UIFont *replacementFont = nil;
if ([currentFont.fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location != NSNotFound) {
replacementFont = [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:25.0f];
} else {
replacementFont = [UIFont fontWithName:@"HelveticaNeue-Thin" size:25.0f];
}
[str addAttribute:NSFontAttributeName value:replacementFont range:range];
}];
Mejorando la solución de Victor, incluido el color:
extension UILabel {
func setHTMLFromString(text: String) {
let modifiedFont = NSString(format:"<span style=/"color:/(self.textColor.toHexString());font-family: /(self.font!.fontName); font-size: /(self.font!.pointSize)/">%@</span>", text) as String
let attrStr = try! NSAttributedString(
data: modifiedFont.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding],
documentAttributes: nil)
self.attributedText = attrStr
}
}
Para que esto funcione también necesitarás YLColor.swift de la conversión de uicolor a hexadecimal gist.github.com/yannickl/16f0ed38f0698d9a8ae7
Sí, hay una solución más fácil. ¡Establezca la fuente en la fuente html!
NSError* error;
NSString* source = @"<strong>Nice</strong> try, Phil";
source = [source stringByAppendingString:@"<style>strong{font-family: ''Avenir-Roman'';font-size: 14px;}</style>"];
NSMutableAttributedString* str = [[NSMutableAttributedString alloc] initWithData:[source dataUsingEncoding:NSUTF8StringEncoding]
options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]}
documentAttributes:nil error:&error];
Espero que esto ayude.
Un enfoque más genérico es observar los rasgos de la fuente al enumerar y crear una fuente con los mismos rasgos (negrita, cursiva, etc.):
extension NSMutableAttributedString {
/// Replaces the base font (typically Times) with the given font, while preserving traits like bold and italic
func setBaseFont(baseFont: UIFont, preserveFontSizes: Bool = false) {
let baseDescriptor = baseFont.fontDescriptor
let wholeRange = NSRange(location: 0, length: length)
beginEditing()
enumerateAttribute(.font, in: wholeRange, options: []) { object, range, _ in
guard let font = object as? UIFont else { return }
// Instantiate a font with our base font''s family, but with the current range''s traits
let traits = font.fontDescriptor.symbolicTraits
guard let descriptor = baseDescriptor.withSymbolicTraits(traits) else { return }
let newSize = preserveFontSizes ? descriptor.pointSize : baseDescriptor.pointSize
let newFont = UIFont(descriptor: descriptor, size: newSize)
self.removeAttribute(.font, range: range)
self.addAttribute(.font, value: newFont, range: range)
}
endEditing()
}
}
Versión Swift, basada en la respuesta dada por Javier Querol
extension UILabel {
func setHTMLFromString(text: String) {
let modifiedFont = NSString(format:"<span style=/"font-family: /(self.font!.fontName); font-size: /(self.font!.pointSize)/">%@</span>", text) as String
let attrStr = try! NSAttributedString(
data: modifiedFont.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding],
documentAttributes: nil)
self.attributedText = attrStr
}
}
Swift 3.0 e iOS 9+
extension UILabel {
func setHTMLFromString(htmlText: String) {
let modifiedFont = String(format:"<span style=/"font-family: ''-apple-system'', ''HelveticaNeue''; font-size: /(self.font!.pointSize)/">%@</span>", htmlText)
//process collection values
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
}
}
Swift 3 String extension incluye una fuente nula. La propiedad sin fuente se toma de otra pregunta SO, no recuerdo cuál :(
extension String {
var html2AttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else {
return nil
}
do {
return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
}
catch {
print(error.localizedDescription)
return nil
}
}
public func getHtml2AttributedString(font: UIFont?) -> NSAttributedString? {
guard let font = font else {
return html2AttributedString
}
let modifiedString = "<style>body{font-family: ''/(font.fontName)''; font-size:/(font.pointSize)px;}</style>/(self)";
guard let data = modifiedString.data(using: .utf8) else {
return nil
}
do {
return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
}
catch {
print(error)
return nil
}
}
}
Swift 4+ actualización de la extensión UILabel
extension UILabel {
func setHTMLFromString(text: String) {
let modifiedFont = NSString(format:"<span style=/"font-family: /(self.font!.fontName); font-size: /(self.font!.pointSize)/">%@</span>" as NSString, text)
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: String.Encoding.unicode.rawValue, allowLossyConversion: true)!,
options: [NSAttributedString.DocumentReadingOptionKey.documentType:NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
}
}
iOS 9+
extension UILabel {
func setHTMLFromString(htmlText: String) {
let modifiedFont = NSString(format:"<span style=/"font-family: ''-apple-system'', ''HelveticaNeue''; font-size: /(self.font!.pointSize)/">%@</span>" as NSString, htmlText) as String
//process collection values
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options: [NSAttributedString.DocumentReadingOptionKey.documentType:NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
}
}
#import "UILabel+HTML.h"
@implementation UILabel (HTML)
- (void)jaq_setHTMLFromString:(NSString *)string {
string = [string stringByAppendingString:[NSString stringWithFormat:@"<style>body{font-family: ''%@''; font-size:%fpx;}</style>",
self.font.fontName,
self.font.pointSize]];
self.attributedText = [[NSAttributedString alloc] initWithData:[string dataUsingEncoding:NSUnicodeStringEncoding]
options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
documentAttributes:nil
error:nil];
}
@end
De esta forma, no necesita especificar qué fuente quiere, tomará la fuente y el tamaño de la etiqueta.