HTML을 NSA 속성으로 구문 분석텍스트 - 글꼴을 설정하는 방법?
UITableViewCell의 iPhone에 잘 표시되도록 html 형식의 텍스트 조각을 가져오려고 합니다.
지금까지 저는 다음과 같습니다.
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];
이런 종류의 일이 있습니다.'Nice'가 굵은 글씨로 표시된 텍스트를 받았습니다!하지만... 또한 글꼴을 Times Roman으로 설정합니다!이것은 제가 원하는 글꼴이 아닙니다.Attributes 문서에서 뭔가 설정해야 할 것 같은데, 어디에서도 예제를 찾을 수 없습니다.
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 및 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)
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 5 및 iOS 11+
extension UILabel {
func setHTMLFromString(htmlText: String) {
let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>", htmlText)
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html, .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
이렇게 하면 원하는 글꼴을 지정할 필요가 없으며 레이블 글꼴과 크기가 사용됩니다.
저는 실제로 이 문제에 대한 효과적인 해결책을 찾았습니다.
구문 분석하기 전에 HTML 응답 문자열의 글꼴을 변경합니다.
NSString *aux = [NSString stringWithFormat:@"<span style=\"font-family: YOUR_FONT_NAME; font-size: SIZE\">%@</span>", htmlResponse];
예:
NSString *aux = [NSString stringWithFormat:@"<span style=\"font-family: HelveticaNeue-Thin; font-size: 17\">%@</span>", [response objectForKey:@"content"]];
빠른 버전:
let aux = "<span style=\"font-family: YOUR_FONT_NAME; font-size: SIZE\">\(htmlResponse)</span>"
보다 일반적인 접근 방식은 열거하는 동안 글꼴 특성을 살펴보고 동일한 특성(굵은 글씨, 기울임꼴 등)을 가진 글꼴을 만드는 것입니다.
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()
}
}
알았어요.약간 곰 같기도 하고, 아마도 최선의 답은 아닐 것입니다.
이 코드는 모든 글꼴 변경을 거칩니다.글꼴에 "Times New Roman"과 "Times New Roman BoldMT"를 사용하는 것으로 알고 있습니다.그러나 이와 상관없이 굵은 글꼴을 찾아서 다시 설정할 수 있습니다.제가 있는 동안 크기를 재설정할 수도 있습니다.
저는 솔직히 이것을 구문 분석 시간에 설정할 방법이 있기를 희망합니다/생각합니다만 있다면 찾을 수 없습니다.
- (void)changeFont:(NSMutableAttributedString*)string
{
NSRange range = (NSRange){0,[string length]};
[string 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];
}
[string addAttribute:NSFontAttributeName value:replacementFont range:range];
}];
}
UILabel 확장의 신속한 4개 이상 업데이트
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
}
}
네, 더 쉬운 해결책이 있습니다.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];
이게 도움이 되길 바랍니다.
위의 답변은 변환을 동시에 수행하는 경우 정상적으로 작동합니다.NSAttributedString
그러나 문자열 자체에서 작동하므로 입력에 액세스할 필요가 없는 더 나은 솔루션은 다음과 같은 범주라고 생각합니다.
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)
}
}
}
}
다음으로 사용:
let desc = NSMutableAttributedString(attributedString: *someNSAttributedString*)
desc.convertFontTo(UIFont.systemFontOfSize(16))
iOS 7+에서 작동합니다.
색상을 포함한 Victor 솔루션 개선:
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
}
}
이것이 작동하기 위해서는 uicolor to hex 변환 https://gist.github.com/yannickl/16f0ed38f0698d9a8ae7 의 YLcolor.swift도 필요합니다.
NSHTML 텍스트 문서 사용유형은 느리고 스타일을 제어하기 어렵습니다.저는 당신이 아트리부티카라고 불리는 제 도서관에 가보는 것을 제안합니다.그것은 매우 빠른 파서를 가지고 있습니다.또한 태그 이름을 지정하고 원하는 스타일을 정의할 수 있습니다.
예:
let str = "<strong>Nice</strong> try, Phil".style(tags:
Style("strong").font(.boldSystemFont(ofSize: 15))).attributedString
label.attributedText = str
https://github.com/psharanda/Atributika 에서 찾을 수 있습니다.
모두의 답변을 종합하여 HTML 텍스트로 레이블을 설정할 수 있는 두 가지 확장을 만들었습니다.위의 일부 답변은 속성 문자열의 글꼴 패밀리를 올바르게 해석하지 못했습니다.다른 것들은 제가 필요로 하는 것에 대해 불완전하거나 다른 방법으로 실패했습니다.제가 개선했으면 하는 점이 있으면 말씀해 주세요.
이것이 누군가에게 도움이 되길 바랍니다.
extension UILabel {
/// Sets the label using the supplied html, using the label's font and font size as a basis.
/// For predictable results, using only simple html without style sheets.
/// See https://stackoverflow.com/questions/19921972/parsing-html-into-nsattributedtext-how-to-set-font
///
/// - Returns: Whether the text could be converted.
@discardableResult func setAttributedText(fromHtml html: String) -> Bool {
guard let data = html.data(using: .utf8, allowLossyConversion: true) else {
print(">>> Could not create UTF8 formatted data from \(html)")
return false
}
do {
let mutableText = try NSMutableAttributedString(
data: data,
options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
mutableText.replaceFonts(with: font)
self.attributedText = mutableText
return true
} catch (let error) {
print(">>> Could not create attributed text from \(html)\nError: \(error)")
return false
}
}
}
extension NSMutableAttributedString {
/// Replace any font with the specified font (including its pointSize) while still keeping
/// all other attributes like bold, italics, spacing, etc.
/// See https://stackoverflow.com/questions/19921972/parsing-html-into-nsattributedtext-how-to-set-font
func replaceFonts(with font: UIFont) {
let baseFontDescriptor = font.fontDescriptor
var changes = [NSRange: UIFont]()
enumerateAttribute(.font, in: NSMakeRange(0, length), options: []) { foundFont, range, _ in
if let htmlTraits = (foundFont as? UIFont)?.fontDescriptor.symbolicTraits,
let adjustedDescriptor = baseFontDescriptor.withSymbolicTraits(htmlTraits) {
let newFont = UIFont(descriptor: adjustedDescriptor, size: font.pointSize)
changes[range] = newFont
}
}
changes.forEach { range, newFont in
removeAttribute(.font, range: range)
addAttribute(.font, value: newFont, range: range)
}
}
}
답변 감사합니다, 연장은 정말 마음에 들었지만 아직 swift로 전환하지 못했습니다.아직 목표 C에 있는 나이든 학생들에게 이것은 약간 도움이 될 것입니다.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];
}]; }
해피 코딩! -- 그렉 프레임
다음은 Objective-C를 사용하여 NSA 속성 문자열을 반환하는 NSString의 확장입니다.
HTML 태그가 있는 문자열을 올바르게 처리하고 원하는 글꼴 및 글꼴 색을 설정하는 동시에 BOLD, Italics 등의 HTML 태그를 유지합니다.
가장 좋은 점은 글꼴 속성을 설정하는 HTML 마커에 의존하지 않는다는 것입니다.
@implementation NSString (AUIViewFactory)
- (NSAttributedString*)attributedStringFromHtmlUsingFont:(UIFont*)font fontColor:(UIColor*)fontColor
{
NSMutableAttributedString* mutableAttributedString = [[[NSAttributedString alloc] initWithData:[self dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute : @(NSUTF8StringEncoding)} documentAttributes:nil error:nil] mutableCopy]; // parse text with html tags into a mutable attributed string
[mutableAttributedString beginEditing];
// html tags cause font ranges to be created, for example "This text is <b>bold</b> now." creates three font ranges: "This text is " , "bold" , " now."
[mutableAttributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, mutableAttributedString.length) options:0 usingBlock:^(id value, NSRange range, BOOL* stop)
{ // iterate every font range, change every font to new font but preserve symbolic traits such as bold and italic (underline and strikethorugh are preserved automatically), set font color
if (value)
{
UIFont* oldFont = (UIFont*)value;
UIFontDescriptor* fontDescriptor = [font.fontDescriptor fontDescriptorWithSymbolicTraits:oldFont.fontDescriptor.symbolicTraits];
UIFont* newFont = [UIFont fontWithDescriptor:fontDescriptor size:font.pointSize];
[mutableAttributedString removeAttribute:NSFontAttributeName range:range]; // remove the old font attribute from this range
[mutableAttributedString addAttribute:NSFontAttributeName value:newFont range:range]; // add the new font attribute to this range
[mutableAttributedString addAttribute:NSForegroundColorAttributeName value:fontColor range:range]; // set the font color for this range
}
}];
[mutableAttributedString endEditing];
return mutableAttributedString;
}
@end
UILabel 및 UITextView용 Swift 5 솔루션
extension UITextView {
func setHTMLFromString(htmlText: String) {
let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>", htmlText)
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
}
}
extension UILabel {
func setHTMLFromString(htmlText: String) {
let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', 'HelveticaNeue'; font-size: \(self.font!.pointSize)\">%@</span>", htmlText)
let attrStr = try! NSAttributedString(
data: modifiedFont.data(using: .unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue],
documentAttributes: nil)
self.attributedText = attrStr
}
}
UILabel에 대한 사용
self.label.setHTMLFromString(htmlText: htmlString)
IMT-2000 3GPP-UE textView
self.textView.setHTMLFromString(htmlText: htmlString)
산출량
0 글꼴을 포함한 Swift 3 String 확장자입니다.글꼴이 없는 속성은 다른 SO 질문에서 가져온 것입니다. 어떤 질문인지 기억하지 마십시오.
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
}
}
}
- 스위프트 솔루션
아래의 접근 방식이 효과가 있습니다.이 방법에서는 글꼴 패밀리, 글꼴 크기 및 색상을 매우 잘 제공할 수 있습니다.변경 사항이나 더 나은 방법을 자유롭게 제안하십시오.
extension UILabel {
func setHTMLFromString(htmlText: String,fontFamily:String,fontColor:String) {
let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', \(fontFamily); font-size: \(self.font!.pointSize); color: \(fontColor) ; \">%@</span>", htmlText)
do{
if let valData = modifiedFont.data(using: .utf8){
let attrStr = try NSAttributedString(data: valData, options: [NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html.rawValue], documentAttributes: nil)
self.attributedText = attrStr
}
}catch{
print("Conversion failed with \(error)")
self.attributedText = nil
}
}
사실, 훨씬 더 쉽고 깨끗한 방법이 존재합니다.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)];
언급URL : https://stackoverflow.com/questions/19921972/parsing-html-into-nsattributedtext-how-to-set-font
'sourcecode' 카테고리의 다른 글
.NET 버전을 어떻게 찾습니까? (0) | 2023.06.07 |
---|---|
find_spec_for_exe': 보석 번들러를 찾을 수 없습니다(>= 0.a) (Gem::GemNotFound예외) (0) | 2023.06.07 |
Android의 Firebase에서 알림을 보낼 때 알림음이 들리지 않음 (0) | 2023.06.07 |
안드로이드 에뮬레이터는 왜 그렇게 느립니까?안드로이드 에뮬레이터의 속도를 높이려면 어떻게 해야 합니까? (0) | 2023.06.07 |
RMagick 2.13.1을 설치할 수 없습니다. MagickWand.h를 찾을 수 없습니다. (0) | 2023.06.02 |