I have an UITextview inside a iOS app, where I want to display a HTML document. I found solutions to transform the HTML document to an NSAttributedString.
extension String {
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return nil }
do {
return try NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue],
documentAttributes: nil)
} catch {
return nil
}
}
var htmlToString: String {
return htmlToAttributedString?.string ?? ""
}
}
Now I am struggling with the fact, that the HTML document is not displayed as it should be.
For example I want to display this HTML-example inside my UITextView: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_css_example_website
It should look like this:
HTML document in browser
But it looks like this:
HTML document on iPad emulator inside UITextView
What am I doing wrong?
I think it better to display it in WKWebView WKWebKit Offical Documentation
Related
I am working on iOS (Swift) application. I am getting some server response like below.
"description":"This is sample text to show in UI. When doing everyday activities.\u003cbr /\u003eclass is a strong predictor of life, and again sample text here.\u003cbr /\u003eSample text can show here also."
So, Above text has 3 paragraphs, I am trying to displaying them in Textview, But it is showing in plain with new line instead of New Paragraph.
override func viewDidLoad() {
super.viewDidLoad()
let description = jsonResponse["description"] as! String
self.textView.attributedText = description.htmlAttributedString()
}
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: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil) else { return nil }
return html
}
}
The issue is it is showing text, But like new line showing instead of new paragraph. How to fix this?
I have fixed this issue by following, And after conversion server response into json serialization, the special characters code showing as
So, I have fixed like below
let description = jsonResponse["description"] as! String
let formattedString = description.replacingOccurrences(of: "<br />", with: " \n\n")
self.textView.text = formattedString
From my response, I am getting the HTML tags with some strings. I am displaying the dynamic contents in my table view. I've converted HTML tags and displaying in the table view. But the problem is, facing the table view flickering issue heavily and it affects the performance also.
Can you please suggest me, if there is any other way to improve the performance.
I am thinking to add the HTML tags manually and replace the tags based on the response. Bcoz I don't want to affect my performance. please advice.
Eg: How to get the Customer Support ?.
The below code is for converting the html code,
var encryptData : String = inputString
if inputString.contains("<") {
encryptData = inputString.htmlToString // Converting HTML to text
}
else { return encryptData } // Normal string
extension String {
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return NSAttributedString() }
do {
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
return NSAttributedString()
}
}
var htmlToString: String {
return htmlToAttributedString?.string ?? ""
}
}
Try this Approach
Cell with NSAttributedString makes the scrolling of UITableView slow
It will help you out for table view flickering. Thanks
Background: When I retrieve a string from a web service, it includes HTML tags. What I get is:
"Most children who have chronic ear infections outgrow them over time.<div><br></div><div><br></div><div>test</div><div><br></div><div><br></div><div><br></div><div>test1</div>").
Now, I am displaying this to a UITextView by converting it to an attributedString so the user wouldn't see all the HTML tags. I am converting this string to attributedString like this with two extensions:
extension: String {
var data: Data {
return Data(utf8)
}
extension Data {
var attributedString: NSAttributedString? {
do {
return try NSAttributedString(data: self, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
} catch {
print(error)
}
return nil
}
self.textView.attributedText = htmlTagString.data.attributedString
Now, the user will be able to view the textview's attributed text without the HTML Tags. But then when they save it, I am only saving the textView.attributedText.string but by doing that, the string's HTML Tags are all gone but I need to save them as well such as etc.
Question: How do I keep the HTML Tags of a textview's string/text? Please and thank you.
Swift 4:
extension NSAttributedString {
var attributedStringToHtml: String? {
do {
let htmlData = try self.data(from:NSMakeRange(0, self.length), documentAttributes:[.documentType: NSAttributedString.DocumentType.html]);
return String.init(data: htmlData, encoding: String.Encoding.utf8)
} catch {
print("error:", error)
return nil
}
}
}
Previous swift versions:
extension NSAttributedString {
var attributedStringToHtml: String? {
do {
let htmlData = try self.data(from: NSMakeRange(0, self.length), documentAttributes: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType])
return String(data:htmlData, encoding:String.Encoding.utf8)
} catch {
print("error:", error)
return nil
}
}
}
Work for me
Next all code in Controller file, but first in it
self.contact.attributedText = contact.html2Attributed
Second in end file
extension String {
var html2Attributed: NSAttributedString? {
do {
guard let data = data(using: String.Encoding.utf8) else {
return nil
}
return try NSAttributedString(data: data, options: [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
], documentAttributes: nil)
} catch {
print("error: ", error)
return nil
}
}
}
Swift 5:
extension String{
func convertHtml() -> NSAttributedString{
guard let data = data(using: .utf8) else { return NSAttributedString() }
do{
return try NSAttributedString(data: data, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html, NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
}catch{
return NSAttributedString()
}
}
}
How to Use?
descLbl.attributedText = "<!DOCTYPE html><html><body><h1>This is heading 1</h1><h2>This is heading 2</h2><h3>This is heading 3</h3><h4>This is heading 4</h4><h5>This is heading 5</h5><h6>This is heading 6</h6></body></html>".convertHtml()
I am attempting to render a large HTML string, that contains hyperlinks, into a UITextView using NSAttributedString. Everything is working fine except the hyperlinks, they don't actually open the link.
For an example, here is a dummy version of my html string:
let htmlString = "<html><p>If you would like to contact someone, you can email
them at <a class=rvts10 href=\"mailto:some#one.com\">some#one.com</a></p></html>"
I have a function called convertHTML() that converts strings to NSAttributedString with html document type options, that I use to assign to the UITextView's attributed text:
textView.attributedText = htmlString.convertHTML()
The TextField is selectable but not editable. When the page is loaded, you can see the hyperlink styling (blue text) and everything, but you can't tap on the link and open the mail app.
I assume this I need to change "mailto:..." to something else that iOS will recognize, but I just have no idea what needs to be done to allow this link to be linkable.
This is my html method:
func convertHtml() -> NSAttributedString{
guard let data = data(using: .utf8) else { return NSAttributedString() }
do{
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
}catch{
return NSAttributedString()
}
}
I think you have error with your convertHTML() Method check this
let htmlString = "<html><p>If you would like to contact someone, you can email them at <a class=rvts10 href=\"mailto:some#one.com\">some#one.com</a></p></html>"
// you have to convert string to data
let data = Data(htmlString.utf8)
// then convert data to NSAttributedString with NSAttributedString.DocumentType.htm
if let attributedString = try? NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html], documentAttributes: nil) {
self.textView.attributedText = attributedString
}
I use this extension :
import Foundation
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)
}
}
After implementing you can use it like this:
contentTextField.attributedText = try? NSAttributedString(htmlString: aHTMLString)
In my app, i want to display a text in a UILabel. I use HTML to store the text in my data base to dynamically from my text in my app. I actually use this (Swift 3.2, iOS 8+) :
if let data = text.data(using: .utf8) {
let htmlString = try? NSMutableAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
self.textLabel.attributedText = htmlString
}
It's work great for the HTML stuff i used like
<b>Text</b>
<i>Test</i>
And more...
Now, i want to display a table in my label. This is the HTML code for the table :
<table border="2px solid black">
<tr><th>Symbole</th><th>Å</th><th>↓</th><th>■</th><th>╩</th><th>¬</th><th>▓</th><th>Ø</th><th>±</th><th> º </th><th>¶</th><th>░</th></tr>
<tr><td>Utilisation</td><td>1</td><td>11</td><td>11</td><td>5</td><td>1</td><td>4</td><td>12</td><td>4</td><td>1</td><td>5</td><td>1</td></tr>
</table>
This code displays a table form but there is no border in the table. I want to display the table border like the reel HTML render. It's possible or not ?
Weird issue, I didn't understand why this simple thing didn't work, however I managed to make the border appear by adding a random attribute to the NSAttributedString, which makes me believe it's a NSAttributedString rendering bug.
Here's the function that I used (this is Swift 4 but can be converted to earlier versions):
extension String {
func attributedString() -> NSAttributedString? {
guard let data = self.data(using: String.Encoding.utf8,
allowLossyConversion: false) else { return nil }
let options: [NSAttributedString.DocumentReadingOptionKey : Any] = [
NSAttributedString.DocumentReadingOptionKey.characterEncoding : String.Encoding.utf8.rawValue,
NSAttributedString.DocumentReadingOptionKey.documentType : NSAttributedString.DocumentType.html
]
let htmlString = try? NSMutableAttributedString(data: data, options: options, documentAttributes: nil)
// Removing this line makes the bug reappear
htmlString?.addAttribute(NSAttributedStringKey.backgroundColor, value: UIColor.clear, range: NSMakeRange(0, 1))
return htmlString
}
}