1

I am creating an application that should display a list of strings, the string is returned from the server and can be either an html or not. I am currently setting the text inside a UILabel. to do that i am using the below

    NSMutableAttributedString *attributedTitleString = [[NSMutableAttributedString alloc] initWithData:[title dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];
cell.label.attributedText =attributedTitleString;

When the text is an html, everything work perfectly since the font and alignments are returned inside the html. The issue is occurring when the text is a normal text. The font, text alignment, text size and others are not being respected anymore.

So how can I check if the text is an html string or not? I will be using the following in case of normal text:

cell.label.text =title;

I have tried to search on forums but still didn't get any answer for my issue.

Iphone User
  • 1,930
  • 2
  • 17
  • 26
  • What do you mean that the font pp. is not respected anymore? If it is plain text, there are no such attributes. – Amin Negm-Awad Mar 10 '16 at 10:19
  • I mean when creating the label, i am setting the font to 20 for ex and settextalignment center. However when I set cell.label.attributedText =attributedTitleString (from a plain text) , the font is so small and aligned left – Iphone User Mar 10 '16 at 10:28
  • I think it's not possible. You can only check if your html string contain html tag. (With regex for example) – Pipiks Mar 10 '16 at 10:29
  • What happens if you (re-)set the attributes after assigning the plain text? – Amin Negm-Awad Mar 10 '16 at 10:38
  • @AminNegm-Awad I don't want to always set the font after setting the attribute text in case of html text because this will override the font returned from the html – Iphone User Mar 10 '16 at 10:48
  • Oh, I assumed that the html settings will be respected, if there are attributes. – Amin Negm-Awad Mar 10 '16 at 10:50
  • Could to the trick: `if([[title dataUsingEncoding:NSUnicodeStringEncoding] length] == [[attributedTitleString string] length]){//normal text}else{//html}`? – Larme Mar 10 '16 at 10:54
  • @Larme still not working (( i also tried if([title length] == ...) but not working in all cases – Iphone User Mar 10 '16 at 11:07
  • `[title length]` is better, since we want a `NSString` length, not a `NSData` one. Sorry for my mistake. Do you have an example case where it's not working? – Larme Mar 10 '16 at 11:08
  • I am receiving a text where the text is displaying "Your will. Stay" and the attribute is displaying "Your will. Stay" . The difference of length is 3 and i can't know why the text is adding some tabs and space.(or maybe why the attribute is removing them) – Iphone User Mar 10 '16 at 11:25
  • With `NSString *title = @"Your will. Stay";` I got 15 at length for `attributedTitleString` and `title`. – Larme Mar 10 '16 at 13:40
  • @Larme, the string contains a tab and 2 spaces after the point, these does not exist in the attributedTitleString. I can't figure how they disappear in the attributedTitleString. – Iphone User Mar 10 '16 at 14:08
  • @Pipiks can you please help me how could I do that using regex? – Iphone User Mar 10 '16 at 21:51

3 Answers3

2

This is working fine, you need to put:

cell.label. attributedText = title; incase of normal text too.

As It is working fine. Run the below code.

//If HTML Text

NSString *htmlstr = `@"This is <font color='red'>simple</font>"`;

NSMutableAttributedString *attributedTitleString = [[NSMutableAttributedString alloc] initWithData:[htmlstr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

textField.attributedText =attributedTitleString;

textField.font = [UIFont fontWithName:@"vardana" size:20.0];

//If Normal text.

NSString *normalStr = @"This is Renuka";

NSMutableAttributedString *NorAttributedTitleString = [[NSMutableAttributedString alloc] initWithData:[normalStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType } documentAttributes:nil error:nil];

textField.attributedText = NorAttributedTitleString;

textField.font = [UIFont fontWithName:@"vardana" size:20.0];
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
Renuka Pandey
  • 1,730
  • 2
  • 15
  • 27
1

You can check if your string contains html tag :

// iOS8 +

NSString *string = @"<TAG>bla bla bla html</TAG>";

if ([string containsString:@"<TAG"]) {
    NSLog(@"html string");
} else {
    NSLog(@"no html string");
}

// iOS7 +

NSString *string = @"<TAG>bla bla bla html</TAG>";

if ([string rangeOfString:@"<TAG"].location != NSNotFound) {
    NSLog(@"html string");
} else {
    NSLog(@"no html string");
}
Pipiks
  • 2,018
  • 12
  • 27
1

Since the syntax and structure of HTML and XML is quite similar, you can utilize XMLDocument to check whether a given data object is HTML or plain text.

So data is from the type Data and is returned by an URLSession dataTask.

// Default to plain text
var options : [NSAttributedString.DocumentReadingOptionKey: Any] = [.documentType: NSAttributedString.DocumentType.plain]

// This will succeed for HTML, but not for plain text                
if let _ = try? XMLDocument(data: data, options: []) {
     options[.documentType] = NSAttributedString.DocumentType.html
}

guard let string = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else { return }

Update

The above method works sort of. I had trouble with some HTML not creating an XML document. For the moment I have a different solution, that I don't really like. As the symptom is that we get only one line back in the attributed string, simply check for that and create a new attributed string if there is only one line.

var options : [NSAttributedString.DocumentReadingOptionKey: Any] = [.documentType: NSAttributedString.DocumentType.html]

guard var string = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else { return }

if string.string.split(separator: "\n").count == 1 {
    options[.documentType] = NSAttributedString.DocumentType.plain
    guard let tempString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) else { return }
    string = tempString
} 
mangerlahn
  • 4,746
  • 2
  • 26
  • 50