iOS에서 HTML을 NSA 속성 문자열로 변환
의 인스턴스를 사용하고 있습니다.UIWebView
을 지정하기 하지만, 부텍스를로정색위해칠기하일게, 은결를과대 에 표시하는 로 제공합니다.UIWebView
을 다을사용표다니합시여음하를 사용하여 표시하고 싶습니다.Core Text
NSAttributedString
.
나는 창조하고 그릴 수 있습니다.NSAttributedString
HTML을 어떻게 변환하고 속성 문자열에 매핑할 수 있는지 잘 모르겠습니다.
X Mac OS X 아래에 있습니다.NSAttributedString
을 가지고 있습니다.initWithHTML:
할 수 없습니다. method는 Mac에서 사용할 수 없습니다. method는 iOS에서 사용할 수 있습니다.
저도 이것과 비슷한 질문이 있다는 것을 알고 있지만 답이 없었습니다. 저는 누군가가 이것을 할 수 있는 방법을 만들었는지, 만약 그렇다면 공유할 수 있는지 다시 한번 시도해보고 싶다고 생각했습니다.
iOS 7에서 UIKit은 초기화할 수 있는 방법을 추가했습니다.NSAttributedString
HTML 사용(예:
[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]
options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
documentAttributes:nil error:nil];
Swift에서:
let htmlData = NSString(string: details).data(using: String.Encoding.unicode.rawValue)
let options = [NSAttributedString.DocumentReadingOptionKey.documentType:
NSAttributedString.DocumentType.html]
let attributedString = try? NSMutableAttributedString(data: htmlData ?? Data(),
options: options,
documentAttributes: nil)
Github의 Oliver Drobnik이 NSA에서 제공하는 문자열에 대한 오픈 소스 추가 작업이 진행 중입니다.HTML 구문 분석에 NS 스캐너를 사용합니다.
HTML에서 NSA 속성 문자열을 생성하려면 메인 스레드에서 수행해야 합니다!
업데이트: NSA 속성 String HTML 렌더링은 후드 아래의 WebKit에 의존하며 메인 스레드에서 실행되어야 하며 그렇지 않으면 SIGTRAP로 앱이 충돌하는 경우가 있습니다.
새 유물 충돌 로그:
다음은 스레드 세이프 Swift 2 String 확장 버전 업데이트입니다.
extension String {
func attributedStringFromHTML(completionBlock:NSAttributedString? ->()) {
guard let data = dataUsingEncoding(NSUTF8StringEncoding) else {
print("Unable to decode data from html string: \(self)")
return completionBlock(nil)
}
let options = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: NSNumber(unsignedInteger:NSUTF8StringEncoding)]
dispatch_async(dispatch_get_main_queue()) {
if let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) {
completionBlock(attributedString)
} else {
print("Unable to create attributed string from html string: \(self)")
completionBlock(nil)
}
}
}
}
용도:
let html = "<center>Here is some <b>HTML</b></center>"
html.attributedStringFromHTML { attString in
self.bodyLabel.attributedText = attString
}
출력:
NSA 속성 문자열의 빠른 초기화자 확장
제 성향은 이것을 확장으로 추가하는 것이었습니다.NSAttributedString
String
정적 확장과 이니셜라이저로 사용해 보았습니다.저는 아래에 포함된 이니셜라이저를 선호합니다.
스위프트 4
internal convenience init?(html: String) {
guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
return nil
}
guard let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else {
return nil
}
self.init(attributedString: attributedString)
}
스위프트 3
extension NSAttributedString {
internal convenience init?(html: String) {
guard let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else {
return nil
}
guard let attributedString = try? NSMutableAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) else {
return nil
}
self.init(attributedString: attributedString)
}
}
예
let html = "<b>Hello World!</b>"
let attributedString = NSAttributedString(html: html)
은 이은입니다.String
을 HTML로 입니다.NSAttributedString
.
extension String {
func htmlAttributedString() -> NSAttributedString? {
guard let data = self.dataUsingEncoding(NSUTF16StringEncoding, allowLossyConversion: false) else { return nil }
guard let html = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil }
return html
}
}
사용할 항목,
label.attributedText = "<b>Hello</b> \u{2022} babe".htmlAttributedString()
위에서 유니코드를 올바르게 렌더링한다는 것을 보여주기 위해 일부러 유니코드 \u22022를 추가했습니다.
기본 : 기본 인코딩으로 되는 인코딩입니다.NSAttributedString
은 도는용입니다.NSUTF16StringEncoding
(UTF8 사용!).
Swift 3.0 Xcode 8 버전
func htmlAttributedString() -> NSAttributedString? {
guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
guard let html = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) else { return nil }
return html
}
Andrew의 솔루션을 수정하고 코드를 Swift 3으로 업데이트했습니다.
를 UITextView로 사용합니다.self
및 색상을 수 .
참고:toHexString()
여기서부터 내선 번호입니다.
extension UITextView {
func setAttributedStringFromHTML(_ htmlCode: String, completionBlock: @escaping (NSAttributedString?) ->()) {
let inputText = "\(htmlCode)<style>body { font-family: '\((self.font?.fontName)!)'; font-size:\((self.font?.pointSize)!)px; color: \((self.textColor)!.toHexString()); }</style>"
guard let data = inputText.data(using: String.Encoding.utf16) else {
print("Unable to decode data from html string: \(self)")
return completionBlock(nil)
}
DispatchQueue.main.async {
if let attributedString = try? NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) {
self.attributedText = attributedString
completionBlock(attributedString)
} else {
print("Unable to create attributed string from html string: \(self)")
completionBlock(nil)
}
}
}
}
사용 예:
mainTextView.setAttributedStringFromHTML("<i>Hello world!</i>") { _ in }
스위프트 4
- NSA 속성 문자열 편의성 초기화자
- 추가 경비 없이
- 오류 발생
extension NSAttributedString {
convenience init(htmlString html: String) throws {
try self.init(data: Data(html.utf8), options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
], documentAttributes: nil)
}
}
사용.
UILabel.attributedText = try? NSAttributedString(htmlString: "<strong>Hello</strong> World!")
NSHTML 텍스트 문서 사용유형은 느리고 스타일을 제어하기 어렵습니다.저는 당신이 아트리부티카라고 불리는 제 도서관에 가보는 것을 제안합니다.그것은 매우 빠른 HTML 파서를 가지고 있습니다.또한 태그 이름을 지정하고 원하는 스타일을 정의할 수 있습니다.
예:
let str = "<strong>Hello</strong> World!".style(tags:
Style("strong").font(.boldSystemFont(ofSize: 15))).attributedString
label.attributedText = str
https://github.com/psharanda/Atributika 에서 찾을 수 있습니다.
현재 유일한 해결책은 HTML을 구문 분석하고 지정된 point/font/etc 속성을 가진 노드를 구축한 다음 이들 노드를 NSA 속성 문자열로 결합하는 것입니다.많은 작업이 필요하지만 올바르게 수행되면 미래에 재사용할 수 있습니다.
스위프트 3:
사용해 보십시오.
extension String {
func htmlAttributedString() -> NSAttributedString? {
guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
guard let html = try? NSMutableAttributedString(
data: data,
options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
documentAttributes: nil) else { return nil }
return html
}
}
사용 용도:
let str = "<h1>Hello bro</h1><h2>Come On</h2><h3>Go sis</h3><ul><li>ME 1</li><li>ME 2</li></ul> <p>It is me bro , remember please</p>"
self.contentLabel.attributedText = str.htmlAttributedString()
위의 해결책이 맞습니다.
[[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]
options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)}
documentAttributes:nil error:nil];
그러나 ios 8.1, 2 또는 3에서 실행하면 앱이 충돌합니다.
충돌을 방지하기 위해 대기열에서 실행할 수 있습니다.그래서 항상 메인 스레드에 있습니다.
.forgroundColor가 설정된 속성 사전을 다른 항목으로 전달하는 경우에도 내장 변환은 항상 텍스트 색상을 UIColor.black으로 설정합니다.iOS 13에서 DARK 모드를 지원하려면 NSA 속성 문자열에서 이 확장 버전을 사용해 보십시오.
extension NSAttributedString {
internal convenience init?(html: String) {
guard
let data = html.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
let options : [DocumentReadingOptionKey : Any] = [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
]
guard
let string = try? NSMutableAttributedString(data: data, options: options,
documentAttributes: nil) else { return nil }
if #available(iOS 13, *) {
let colour = [NSAttributedString.Key.foregroundColor: UIColor.label]
string.addAttributes(colour, range: NSRange(location: 0, length: string.length))
}
self.init(attributedString: string)
}
}
여기 있습니다.Swift 5
Mobile Dan의 답변 버전:
public extension NSAttributedString {
convenience init?(_ html: String) {
guard let data = html.data(using: .unicode) else {
return nil
}
try? self.init(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil)
}
}
유용한 확장 기능
iOS Gourmet Cookbook p.80에 있는 이 실과 포드, 그리고 Erica Sadun의 ObjC 예시에서 영감을 받아, 저는 확장을 썼습니다.String
등등NSAttributedString
HTML 플레인 스트링과 NSA 속성 스트링 사이를 왔다 갔다 하거나 그 반대로 GitHub에서 사용할 수 있습니다.
서명은 다음과 같습니다(게스트의 전체 코드, 위 링크).
extension NSAttributedString {
func encodedString(ext: DocEXT) -> String?
static func fromEncodedString(_ eString: String, ext: DocEXT) -> NSAttributedString?
static func fromHTML(_ html: String) -> NSAttributedString? // same as above, where ext = .html
}
extension String {
func attributedString(ext: DocEXT) -> NSAttributedString?
}
enum DocEXT: String { case rtfd, rtf, htm, html, txt }
폰트 계열, 동적 폰트에 경의를 표합니다. 제가 이 혐오감을 만들어냈습니다.
extension NSAttributedString
{
convenience fileprivate init?(html: String, font: UIFont? = Font.dynamic(style: .subheadline))
{
guard let data = html.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
var totalString = html
/*
https://stackoverflow.com/questions/32660748/how-to-use-apples-new-san-francisco-font-on-a-webpage
.AppleSystemUIFont I get in font.familyName does not work
while -apple-system does:
*/
var ffamily = "-apple-system"
if let font = font {
let lLDBsucks = font.familyName
if !lLDBsucks.hasPrefix(".appleSystem") {
ffamily = font.familyName
}
totalString = "<style>\nhtml * {font-family: \(ffamily) !important;}\n </style>\n" + html
}
guard let data = totalString.data(using: String.Encoding.utf8, allowLossyConversion: true) else {
return nil
}
assert(Thread.isMainThread)
guard let attributedText = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) else {
return nil
}
let mutable = NSMutableAttributedString(attributedString: attributedText)
if let font = font {
do {
var found = false
mutable.beginEditing()
mutable.enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, attributedText.length), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (value, range, stop) in
if let oldFont = value as? UIFont {
let newsize = oldFont.pointSize * 15 * Font.scaleHeruistic / 12
let newFont = oldFont.withSize(newsize)
mutable.addAttribute(NSAttributedString.Key.font, value: newFont, range: range)
found = true
}
}
if !found {
// No font was found - do something else?
}
mutable.endEditing()
// mutable.addAttribute(.font, value: font, range: NSRange(location: 0, length: mutable.length))
}
self.init(attributedString: mutable)
}
}
또는 이것이 파생된 버전을 사용하고 attributedString을 설정한 후 UILabel에 글꼴을 설정할 수 있습니다.
이것은 속성 문자열에 캡슐화된 크기와 대담성을 포함합니다.
여기까지 모든 답을 읽어주셔서 감사합니다.당신은 매우 인내심이 많은 남자 여자나 아이입니다.
html을 Attributed NSAttributedString으로 변환하여 동적 크기 + 텍스트에 대한 접근성을 조정하는 함수입니다.
static func convertHtml(string: String?) -> NSAttributedString? {
guard let string = string else {return nil}
guard let data = string.data(using: .utf8) else {
return nil
}
do {
let attrStr = try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
let range = NSRange(location: 0, length: attrStr.length)
let str = NSMutableAttributedString(attributedString: attrStr)
str.enumerateAttribute(NSAttributedString.Key.font, in: NSMakeRange(0, str.length), options: .longestEffectiveRangeNotRequired) {
(value, range, stop) in
if let font = value as? UIFont {
let userFont = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .title2)
let pointSize = userFont.withSize(font.pointSize)
let customFont = UIFont.systemFont(ofSize: pointSize.pointSize)
let dynamicText = UIFontMetrics.default.scaledFont(for: customFont)
str.addAttribute(NSAttributedString.Key.font,
value: dynamicText,
range: range)
}
}
str.addAttribute(NSAttributedString.Key.underlineStyle, value: 0, range: range)
return NSAttributedString(attributedString: str.attributedSubstring(from: range))
} catch {}
return nil
}
사용 방법:
let htmToStringText = convertHtml(string: html)
self.bodyTextView.isEditable = false
self.bodyTextView.isAccessibilityElement = true
self.bodyTextView.adjustsFontForContentSizeCategory = true
self.bodyTextView.attributedText = htmToStringText
self.bodyTextView.accessibilityAttributedLabel = htmToStringText
이 확장자를 추가한 다음 텍스트를 사용합니다. 이 코드를 사용한 후 텍스트의 사용자 정의 크기를 사용할 수 있습니다.
extension Text {
init(html htmlString: String,
raw: Bool = false,
size: CGFloat? = nil,
fontFamily: String = "-apple-system") {
let fullHTML: String
if raw {
fullHTML = htmlString
} else {
var sizeCss = ""
if let size = size {
sizeCss = "font-size: \(size)px;"
}
fullHTML = """
<!doctype html>
<html>
<head>
<style>
body {
font-family: \(fontFamily);
\(sizeCss)
}
</style>
</head>
<body>
\(htmlString)
</body>
</html>
"""
}
let attributedString: NSAttributedString
if let data = fullHTML.data(using: .unicode),
let attrString = try? NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil) {
attributedString = attrString
} else {
attributedString = NSAttributedString()
}
self.init(attributedString)
}
init(_ attributedString: NSAttributedString) {
self.init("")
attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length), options: []) { (attrs, range, _) in
let string = attributedString.attributedSubstring(from: range).string
var text = Text(string)
if let font = attrs[.font] as? UIFont {
text = text.font(.init(font))
}
if let color = attrs[.foregroundColor] as? UIColor {
text = text.foregroundColor(Color(color))
}
if let kern = attrs[.kern] as? CGFloat {
text = text.kerning(kern)
}
if #available(iOS 14.0, *) {
if let tracking = attrs[.tracking] as? CGFloat {
text = text.tracking(tracking)
}
}
if let strikethroughStyle = attrs[.strikethroughStyle] as? NSNumber, strikethroughStyle != 0 {
if let strikethroughColor = (attrs[.strikethroughColor] as? UIColor) {
text = text.strikethrough(true, color: Color(strikethroughColor))
} else {
text = text.strikethrough(true)
}
}
if let underlineStyle = attrs[.underlineStyle] as? NSNumber,
underlineStyle != 0 {
if let underlineColor = (attrs[.underlineColor] as? UIColor) {
text = text.underline(true, color: Color(underlineColor))
} else {
text = text.underline(true)
}
}
if let baselineOffset = attrs[.baselineOffset] as? NSNumber {
text = text.baselineOffset(CGFloat(baselineOffset.floatValue))
}
self = self + text
}
}
}
언급URL : https://stackoverflow.com/questions/4217820/convert-html-to-nsattributedstring-in-ios
'programing' 카테고리의 다른 글
WPF에서 현재 마우스 화면 좌표를 가져오려면 어떻게 해야 합니까? (0) | 2023.04.29 |
---|---|
특정 셀 아파치 poi 3.9의 글꼴 색 변경 방법 (0) | 2023.04.29 |
Microsoft Azure 웹 사이트 - 사용자 정의 도메인 메일 (0) | 2023.04.29 |
각도 2 ngIf 및 CSS 전환/애니메이션 (0) | 2023.04.29 |
gulp 명령을 찾을 수 없음 - gulp 설치 후 오류 (0) | 2023.04.29 |