I've typed some text in uitextview and also I've select some text and make it bold.After that I'm going to save this data into my application.Now,When I'm going to fetch that data then it will not displaying same as I've saved.
Its not save bold font.
Below is the code :
pragma mark - btnActions
-(IBAction)btnActions:(UIButton *)sender
{
[self addOrRemoveFontTraitWithName:#"Bold" andValue:UIFontDescriptorTraitBold];
}
pragma mark - Private method implementation
-(void)addOrRemoveFontTraitWithName:(NSString *)traitName andValue:(uint32_t)traitValue{
NSRange selectedRange = [txtViewNote selectedRange];
NSDictionary *currentAttributesDict = [txtViewNote.textStorage attributesAtIndex:selectedRange.location
effectiveRange:nil];
UIFont *currentFont = [currentAttributesDict objectForKey:NSFontAttributeName];
UIFontDescriptor *fontDescriptor = [currentFont fontDescriptor];
NSString *fontNameAttribute = [[fontDescriptor fontAttributes] objectForKey:UIFontDescriptorNameAttribute];
UIFontDescriptor *changedFontDescriptor;
if ([fontNameAttribute rangeOfString:traitName].location == NSNotFound) {
uint32_t existingTraitsWithNewTrait = [fontDescriptor symbolicTraits] | traitValue;
changedFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:existingTraitsWithNewTrait];
}
else{
uint32_t existingTraitsWithoutTrait = [fontDescriptor symbolicTraits] & ~traitValue;
changedFontDescriptor = [fontDescriptor fontDescriptorWithSymbolicTraits:existingTraitsWithoutTrait];
}
UIFont *updatedFont = [UIFont fontWithDescriptor:changedFontDescriptor size:0.0];
NSDictionary *dict = #{NSFontAttributeName: updatedFont};
[txtViewNote.textStorage beginEditing];
[txtViewNote.textStorage setAttributes:dict range:selectedRange];
[txtViewNote.textStorage endEditing];
}
pragma mark - btnSave
-(IBAction)btnSave:(id)sender
{
NSURL *documentDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
NSURL *documentURL = [documentDirectoryURL URLByAppendingPathComponent:#"test.html"];
NSString *htmlCode = txtViewNote.text;
NSError* error;
if (![htmlCode writeToURL:documentURL atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
NSLog(#"Couldn't save file because: %#", error);
}
NSString* fileToUpload = [NSString stringWithContentsOfURL:documentURL encoding:NSUTF8StringEncoding error:&error];
if (!fileToUpload) {
NSLog(#"Couldn't read file because: %#", error);
}
}
can any one html me?
The problem is you are saving the plain text of the textView instead of the attributedText.
NSString *htmlCode = txtViewNote.text;
Instead you should save the attributed text like this:
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:NSHTMLTextDocumentType,NSDocumentTypeDocumentAttribute, nil];
NSData *htmlData = [[self txtViewNote].attributedText dataFromRange:NSMakeRange(0, [self txtViewNote].attributedText.length) documentAttributes:attributes error:NULL];
NSString *htmlCode = [[NSString alloc]initWithData:htmlData encoding:NSUTF8StringEncoding];
If you want to write the htmlCode to the textView, you should:
NSMutableAttributedString *tmp = [[NSMutableAttributedString alloc] initWithData:htmlData options:#{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: #(NSUTF8StringEncoding)} documentAttributes:nil error:nil];
[txtViewNote setAttributedText:tmp];
Related
I know how to convert the common NSAttributedString (which has no image) into HTML. I set the Images as NSTextAttachment to NSAttributedString. How could I convert the whole attributed string into HTML?
UIImage *image = [UIImage imageNamed:#"Test.png"];
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = image;
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:htmlString];
NSAttributedString *attstringImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributedString appendAttributedString:attstringImage];
NSAttributedString *titleContent = (NSAttributedString *)attributedString;
NSDictionary *documentAttributes = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [titleContent dataFromRange:NSMakeRange(0, titleContent.length) documentAttributes:documentAttributes error:NULL];
NSString *html = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
Please suggest me with quick answer
Recently, I come into a problem in my project. I need convert NSAttributedString to HTML file. The solution Click here doesn't work for me because want to output the HTML file only with TagName and idName and ClassName, at the same time, output the CSS style file to control how the HTML file will display.
Here is my sample code, I wish you can get my intend:
- (NSDictionary *)html
{
NSTextStorage *textStorage = [self contents];
NSArray *arr = [textStorage paragraphs];
// Initialize the CSS dictionay
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
nil];
NSEnumerator *paragraphEnumerator;
paragraphEnumerator = [arr objectEnumerator];
NSAttributedString *paragraph;
NSMutableArray *paragrapHTMLStrings = [[NSMutableArray alloc] initWithCapacity:[arr count]];
NSMutableString *cssString = [[NSMutableString alloc] initWithCapacity:0];
[cssString appendString:#"div{"];
[cssString appendString:[NSString stringWithFormat:#"-webkit-column-count:%ld;", self.columnCount]];
[cssString appendString:[NSString stringWithFormat:#"width:%fpx;", self.bounds.size.width]];
[cssString appendString:[NSString stringWithFormat:#"height:%fpx;", self.bounds.size.height]];
[cssString appendString:#"}"];
[dict setObject:cssString forKey:#"css"];
while (paragraph = [paragraphEnumerator nextObject]) {
// initialize
NSUInteger length;
NSRange effectiveRange = NSMakeRange(0, 0);
id attributeValue;
length = [paragraph length];
// get the font attributes
attributeValue = [paragraph attribute:NSFontAttributeName atIndex:NSMaxRange(effectiveRange) effectiveRange:&effectiveRange];
NSLog(#"font is %#", [attributeValue fontName]);
NSLog(#"font-size is %f", [[[attributeValue fontDescriptor] objectForKey:NSFontSizeAttribute] floatValue]);
NSMutableString *htmlString = [NSMutableString stringWithFormat:#"", [attributeValue fontName],
[[[attributeValue fontDescriptor] objectForKey:NSFontSizeAttribute] floatValue]];
[htmlString appendString:[paragraph string]];
[htmlString appendString:#""];
NSLog(#"htmlString is %#", htmlString);
[paragrapHTMLStrings addObject:htmlString];
htmlString = nil;
}
NSMutableString *htmlStringOfGraphToReturn = [NSMutableString stringWithString:#""];
NSString *stringToAdd;
NSEnumerator *stringEnumerator;
stringEnumerator = [paragrapHTMLStrings objectEnumerator];
while (stringToAdd = [stringEnumerator nextObject])
{
[htmlStringOfGraphToReturn appendString:stringToAdd];
}
[htmlStringOfGraphToReturn appendString:#""];
[dict setObject:htmlStringOfGraphToReturn forKey:#"html"];
// test part
CSSSetGenerator *generater = [[CSSSetGenerator alloc] init];
NSMutableString *string = [generater outputCSSStyleContent:self];
NSLog(#"%#", string);
return dict;
}
I got the solution from Github, There's an open project named DTCoreText. I hope this might be useful for someone.
I am using HTMLParser by Ben Reeves. It works great but the only problem is that I couldn't put the output in UITableView. Anyone can tell me what's wrong with this code? ...................................................................................
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSError *error = nil;
NSURL *url=[[NSURL alloc] initWithString:#"http://website.com/"];
NSString *strin=[[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
HTMLParser *parser = [[HTMLParser alloc] initWithString:strin error:&error];
if (error) {
NSLog(#"Error: %#", error);
return;
}
HTMLNode *bodyNode = [parser body];
NSArray *divNodes = [bodyNode findChildTags:#"div"];
for (HTMLNode *inputNode in divNodes) {
if ([[inputNode getAttributeNamed:#"class"] isEqualToString:#"views-field-title"]) {
NSLog(#"%#", [inputNode allContents]);
listData = [[NSArray alloc] initWithObjects:[inputNode allContents], nil];
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
#end
You're reinitializing your array every time you find a new element. I think you need to move
listData = [[NSArray alloc] initWithObjects:[inputNode allContents], nil];
outside of your loop and change it to
listData = [[NSMutableArray alloc] init];
listData should be an NSMutableArray so you can add data to it. You'll need to change this in your variable definition too.
Then inside your loop, use [listData addObject:[inputNode allContents]];
I have this url: http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false
And this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSMutableDictionary *theDictionary = [responseString JSONValue];
NSLog(#"%#", theDictionary);
[responseString release];
if (theDictionary != nil)
{
NSArray *routesArray = [theDictionary objectForKey:#"routes"];
NSDictionary *firstRoute = [routesArray objectAtIndex:0];
NSArray *legsArray = [firstRoute objectForKey:#"legs"];
NSDictionary *firstLeg = [legsArray objectAtIndex:0];
steps = [firstLeg objectForKey:#"steps"];
}
[tableView reloadData];
}
I want to display every single #"html_instructions" on a uitableview.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.steps count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cachedCell"];
if (cell == nil)
cell = [[[UITableViewCell alloc]
initWithFrame:CGRectZero reuseIdentifier:#"cachedCell"] autorelease];
return cell;
}
What's missing in my code??? Should be some little detail... any help would be GREAT!
I would do it like this:
Create url request with your url
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:#"http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false"]];
then create NSData structure, that holds response to the request and I converted it to string
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; //Or async request
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
After that, you load JSON into Dictionary, then to move one level down, pass it to another dictionary (result 1)
NSError *error=nil;
result = [NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];
result1 = [result objectForKey:#"routes"];
result2 = [result1 objectForKey:#"legs"];
Then move it into NSMutableArray
jsonMutArray= [result2 objectForKey:#"steps"];
From there, you just put label into your custom cell attach it as a IBOutlet, synthetize and do in cellForRowAtIndexPath method
cell.yourLabel.text = [jsonMutArray objectForKey:#"html_instructions"];
However, keep in mind, that I'm just begginer, so this might not be the most effective way of doing it :) Good Luck!
Don't you need to be doing something like this in your CellForRowAtIndexPath ?
NSString *cellValue = **WHATEVER VALUE YOU WANT TO PUT IN**;
cell.textLabel.text = cellValue;
return cell;
I don't see you adding your data to the cell.
As the title tells,now i can simple convert HTML into NSAttributedString with initWithHTML:documentAttributes: , but what i want to do here is reverse.
Is there any 3rd party library to achieve this?
#implementation NSAttributedString(HTML)
-(NSString *)htmlForAttributedString{
NSArray * exclude = [NSArray arrayWithObjects:#"doctype",
#"html",
#"head",
#"body",
#"xml",
nil
];
NSDictionary * htmlAtt = [NSDictionary
dictionaryWithObjectsAndKeys:NSHTMLTextDocumentType,
NSDocumentTypeDocumentAttribute,
exclude,
NSExcludedElementsDocumentAttribute,
nil
];
NSError * error;
NSData * htmlData = [self dataFromRange:NSMakeRange(0, [self length])
documentAttributes:htmlAtt error:&error
];
//NSAttributedString * htmlString = [[NSAttributedString alloc]initWithHTML:htmlData documentAttributes:&htmlAtt];
NSString * htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
return htmlString;
}
#end
Use dataFromRange:documentAttributes: with the document type attribute (NSDocumentTypeDocumentAttribute) set to HTML (NSHTMLTextDocumentType):
NSAttributedString *s = ...;
NSDictionary *documentAttributes = #{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSData *htmlData = [s dataFromRange:NSMakeRange(0, s.length) documentAttributes:documentAttributes error:NULL];
NSString *htmlString = [[NSString alloc] initWithData:htmlData encoding:NSUTF8StringEncoding];
This is a swift 4 conversion of #omz answer, hope is useful to anyone landing here
extension NSAttributedString {
var attributedString2Html: String? {
do {
let htmlData = try self.data(from: NSRange(location: 0, length: self.length), documentAttributes:[.documentType: NSAttributedString.DocumentType.html]);
return String.init(data: htmlData, encoding: String.Encoding.utf8)
} catch {
print("error:", error)
return nil
}
}
}