HTML text to NSString conversion for content using Nastaleeq Urdu font - html

Font for one of our Urdu based app is "Jameel Noori Nastaleeq Kasheeda". We are supposed to show content (on UILabel) after converting its HTML text to NSString.
For converting HTML to NSString, we have implemented following functions,
-(NSString *)styledHTMLwithHTML:(NSString *)HTML{
NSString *style = #"<meta charset=\"UTF-8\"><style> body { font-family: 'Jameel-Noori-Nastaleeq'; font-size: 20px; } b {font-family: 'Jameel-Noori-Nastaleeq'; }</style>";
return [NSString stringWithFormat:#"%#%#", style, HTML];
}
- (NSAttributedString *)attributedStringWithHTML:(NSString *)HTML {
NSDictionary *options = #{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType };
return [[NSAttributedString alloc] initWithData:[HTML dataUsingEncoding:NSUTF16StringEncoding] options:options documentAttributes:NULL error:NULL];
}
Then we are setting UILabel's attributedTextproperty to get properly formatted NSString based on HTML text.
NSString *styledHtml = [self.novel.article styledHTMLwithHTML:self.novel.article];
NSAttributedString *attributedText = [self.novel.article attributedStringWithHTML:styledHtml];
self.articleView.articleContent.attributedText = attributedText;
This implementation is working as per expectation of default iOS fonts like Arial or Helvetica but text is overlapping when we applied custom Urdu font i.e. Nastaleeq. Any help in this regard would be highly appreciated.

You can implement webview to load your html string like,
NSString* htmlString = #"your html string here";
[webView loadHTMLString:htmlString baseURL: nil]; //webView is `UIWebView` object

Related

Makes all html links clickable when displaying a NSAttributedString in UITextView

I want to display some HTML that contains links (<a> tag) in a UITextView, and makes those links clickable.
For that I use a NSAttributedString initialized with the HTML data and the appropriate options for HTML.
NSString* html = #""
"<html>"
"<head>"
"<base href='http://en.wikipedia.com' target='_self'>"
"</head>"
"<body>"
"<a href='#id'>link</a>"
"<a href='http://stackoverflow.com'>link</a>"
"</body>"
"</html>";
NSAttributedString* attStr = [[NSAttributedString alloc] initWithData:[html dataUsingEncoding:NSUnicodeStringEncoding]
options:#{
NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)
}
documentAttributes:nil
error:nil];
In the html string, you can see two <a> links with href attributes referring to:
The stack overflow URL for the first one.
A URL with only the fragment part for the second one. (https://developer.apple.com/reference/foundation/nsurl)
Next, I set the attributed text in the UITextView
_textView.attributedText = attStr;
When executing, all is well displayed in the view, but only the stackoverflow link is clickable. I want to be able to make the other one clickable too. It seems that NSAttributedString does not make all html links clickable, but only those with valid URLs.
Any ideas how I could do that using NSAttributedString?
Thanks!

CoreTextView & UIScrollview : Calculating window size

I am using CoreTextView on iOS to render an html file in a UIScrollview that is set up programmatically. As soon as the html file exceeds a certain length, the text no longer renders. It does not seem to be a problem with:
Memory. NSLog displays the entire NSAttributedString no matter how long it is.
A formatting error in the html file. I was able to render the entire file in pieces.
If I put in a very large height for the frame, same thing: empty screen and no errors to troubleshoot. I suspect that the issue has something to do with calculating file size and maybe... font line size? Stumped. Incidentally, if I enter a custom font, it is ignored and only the default Helvetica is displayed. Font SIZES, however, render correctly. Any help on getting the entire file to display would be much appreciated!
My code:
m_coreText = [[CoreTextView alloc] initWithFrame:CGRectZero];
m_coreText.backgroundColor = [UIColor clearColor];
m_coreText.contentInset = UIEdgeInsetsMake(10, 10, 10, 10);
NSString* html = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"terms" ofType:#"html"] encoding:NSUTF8StringEncoding error:NULL];
m_coreText.attributedString = [NSAttributedString attributedStringWithHTML:html renderer:^id<HTMLRenderer>(NSMutableDictionary* attributes) {
CustomRenderer* renderer=[[CustomRenderer alloc] init];
renderer.type=attributes[#"type"];
renderer.size=CGSizeMake(16, 16);
return renderer;
}];
m_coreText.frame = CGRectMake(0, 0, self.view.bounds.size.width, [m_coreText sizeThatFits:CGSizeMake(self.view.bounds.size.width, MAXFLOAT)].height);
UIScrollView* scroll = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scroll.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
scroll.contentSize=m_coreText.frame.size;
[scroll addSubview:m_coreText];
[self.view addSubview:scroll];

Populate a hyperlink attributed string for UIActivityViewController activities

There are lots of answers on SO that show devs how to make a string from HTML content or place a URL in a string, but my question is how to make an HTML string.
I'm trying to create a string that will return in HTML format or at least not show the URL.
So for example web devs would do this to hide the URL:
Visit Us at Google.com!
I can easily translate that to a string by doing so:
NSString *urlLink = #"www.google.com";
NSString *string = [NSString stringWithFormat:#"Visit Us at %#", urlLink];
But that doesn't replace the link with a hyperlink word of my choosing.
I'm aware that the device dictates if its a hyperlink depending on how you display it. i.e., text fields, text views, or you can force open it etc.
What i'm trying to do is:
#define APPSTORELINK #"www.appstorelink.com"
#implementation Config
+(NSString *)appstorelink {
return APPSTORELINK;
}
+(NSString *)mmsmetadata {
NSString *string = [NSString stringWithFormat:#"I shared this publication with the [Name of my iPhone App] iPhone App", APPSTORELINK];
return string;
}
So I can easily call it here or app wide:
NSArray *shareItems;
UIImage *snapshot = [self imageFromView:self.view];
shareItems = #[[Config mmsmetadata], snapshot];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:shareItems applicationActivities:nil];
activityController.excludedActivityTypes = #[UIActivityTypePostToFlickr, UIActivityTypeAssignToContact, UIActivityTypeMail, UIActivityTypePostToVimeo];
[activityController setCompletionWithItemsHandler:(UIActivityViewControllerCompletionWithItemsHandler)^(NSString *string, BOOL completed) {
So in short, how can I make the string HTML format out of the box? My main concern is I want to hide the URL and replace it with an HTML tag, or otherwise if you have a better solution. Can't find anything on SO.
Any thoughts? I'm probably overthinking this. I'm sure theres an easier way
EDIT
Before even posting I have been aware of NSAttributedString and that was the first thing I attempted. However, the issue isn't setting an attribute, thats the easy part, the part that is defining my question is how to set it so it will DISPLAY as attributed when using activities in the UIActivityViewController
Here is how I set it, but the outcome was the same as above so I figured it would be easier to use an HTML tag:
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:#"I shared this publication with the Army Pubs iPhone App!"];
NSRange selectedRange = NSMakeRange(0, [string length]);
NSURL *linkURL = [NSURL URLWithString:APPSTORELINK];
[string beginEditing];
[string addAttribute:NSLinkAttributeName
value:linkURL
range:selectedRange];
[string addAttribute:NSForegroundColorAttributeName
value:[UIColor blueColor]
range:selectedRange];
[string addAttribute:NSUnderlineStyleAttributeName
value:[NSNumber numberWithInt:NSUnderlineStyleSingle]
range:selectedRange];
[string endEditing];
return string;
However, it still displays as plain text in the Message or Mail composers. So think MFMailComposeViewControllerDelegate how there is a setting for isHTML. If it's set to yes it strips all the HTML tags and displays the text as a hyperlink. For example:
MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init];
mc.mailComposeDelegate = self;
[mc setSubject:emailTitle];
[mc setMessageBody:messageBody isHTML:YES];
I want to emulate that when the activities are called from within a UIActivityViewController
This is the output currently even if I do it with the attributed string I tried first it just displays as plain text by stripping the HTML tag but doesn't make it a link
See link option in attributed strings.
The link attribute specifies an arbitrary object that is passed to the NSTextView method
clickedOnLink:atIndex: when the user clicks in the text range
associated with the NSLinkAttributeName attribute. The text view’s
delegate object can implement textView:clickedOnLink:atIndex: or
textView:clickedOnLink: to process the link object. Otherwise, the
default implementation checks whether the link object is an NSURL
object and, if so, opens it in the URL’s default application.

Reading text from HTML iOS SDK

I have a Label in my View. The Label's text must be the text on http://sample.com/file.html.
How to do this?
You can 'load' the contents of the URL directly into an NSString:
NSString *text = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://sample.com/file.html"] encoding:NSUTF8StringEncoding error:&error];
And then set the label's text accordingly!
Try using NSData's
+ (id)dataWithContentsOfURL:(NSURL *)aURL
Then convert to a string with NSString's
- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding

How to calculate height of html string?

I want to display html text on a label(TTStyleLabel). I am receieving text in form of html. How do I calculate height of html string?
To get height of html text you need to put that html info uiwebview. After loading the html in uiwebview you can get its height in its delegate methods like this -
- (void)viewDidLoad
{
[super viewDidLoad];
webview.delegate = self;
[webview loadHTMLString:#"<div id='foo' style='background: red'>The quick brown fox jumped over the lazy dog.</div>" baseURL:nil];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *output = [webview stringByEvaluatingJavaScriptFromString:#"document.getElementById(\"foo\").offsetHeight;"];
NSLog(#"height: %#", output);
}
But if you are not displaying the text on the screen using the webview (as you are using a TTStyleLabel) you can hide the webview and load the html in it. You need to perform some tricks.