iOS wrapping text around an image - iphone

I've got a few short paragraphs of text that I'd like to place wrapped around an image in my app's view. Typically, the image will be on the left side of the text and the text would flow as you normally expect. The image has varying height and width and size-wise, 4-30kb png files. The text has varying length and can be anywhere between 2 sentences to a few paragraphs. There's markup with text so different lines can be formatted accordingly.
I've been using UIWebView within my UIView to do this in the quickest manner but what I've noticed is that even though my text and images are local, there's a noticeable delay in when the UIWebView loads and shows the image and text. Basically, you see the view area blank and then a short moment later, you see the image load. Most of the time, the text is shown as loaded before the image.
I'm using UIWebView's 'loadHTMLString' to load the local html text and images.
What I want to achieve would look like:
| [ ] | Some text starts here and is long enough to fil until the end of the line. Then
| [image] | the text continues so it wraps around a few more lines to fit the entire
| [ ] | height of the image.
Eventually, we'll show the text below the image, just like you see in a newspaper.
The content would continue at variable length for the rest of the screen.
Is there a better way to display formatted text with images? If there's something better than UIWebView, I'd love to move to that.

I think your basic strategy should be (1) try to get the performance of UIWebView to an acceptable level and (2) if that fails, and it's really important, roll your own text layout code.
Some ideas:
Try to load content into the UIWebView class as early as possible, before it is displayed on screen.
See if using inline styles (instead of a linked stylesheet) improves load time.
See if using inline images (by using <img src="data:...") improves load time.
If none of that works, and you want to roll your own, you're going to have to write your own text layout code. You could probably do this by using NSString's UIKit additions: split the text into words, compute the size of each word (using sizeWithFont:), and lay out the text line by line. You should probably compute on a word-by-word basis, but actually draw a whole line at a time, that should perform better. Or you might be able to make a new string with newlines inserted at the right places and draw the whole thing in one go.
Good luck!

Try the following .This is without CoreText and Html
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];
UIImageView *imageView= [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image=[UIImage imageNamed:#"defaultImage"];
[self.textView addSubview:imageView];
self.textView.textContainer.exclusionPaths = #[imgRect];

Related

Core Text - select text in iPhone?

I need to render rich text using Core Text in my view (simple formatting, multiple fonts in one line of texts, etc.). I am wondering if text rendered this way can be selected by user using (standard copy / paste function)?
I implemented a text selection in CoreText. It is really a hard work... But it's doable.
Basically you have to save all CTLine rects and origins using CTFrameGetLineOrigins(1), CTLineGetTypographicBounds(2), CTLineGetStringRange(3) and CTLineGetOffsetForStringIndex(4).
The line rect can be calculated using the origin(1), ascent(2), descent(2) and offset(3)(4) as shown bellow.
lineRect = CGRectMake(origin.x + offset,
origin.y - descent,
offset,
ascent + descent);
After doing that, you can test which line has the touched point looping the lines (always remember that CoreText uses inverse Y coordinates).
Knowing the line that has the touched point, you can know the letter that is located at that point (or the nearest letter) using CTLineGetStringIndexForPosition.
Here's one screenshot.
For that loupe, I used the code shown in this post.
Edit:
To draw the blue background selection, you have to paint the rect using CGContextFillRect. Unfortunately, there's no background color in NSAttributedString.

UILabel automatic size and position

I want to draw a text with different colors and the only way that I've found for do it is to split every piece of string-color in differents UILabels, so currently now I have four UILabels one after another, lets say, label1, label2, label3 and label4.
The problem with that is with the size and the position of every labels, I've not found an automatic way for do it.
The only way is:
Set the text inside all the labels
Ask for the width of all the labels with this new text
Resize all the labels with this new width
Move label2 to label1.x + label1.width, and so on
This is really the only way in iPhone for do that?
I came from Android and there is a "wrap_content" property for every view and "relative_layouts" where you can define something like.. put label2 rightOf label1. So I'm looking of something simple and automatic like that, but in iPhone.
Thanks!
Depending on your application, you might want to consider a single UIWebView instead. Then you can style the content of it with HTML and CSS.

UILabel and superscript

I have two strings:
a variable length piece of text
another string with numbers that
point to a reference
In my view, the first piece of text is displayed in a UILabel, I adjust the size of the label to accomodate the size of the text. This means I cannot just place another UILabel on the screen, at least not without repositioning it...somehow.
I need to be able to put the second piece of text so it appears to be at the end of the sentence - and superscripted
I really have no idea how to achieve this!
My rather dodgy solution was to enter unicode characters for the superscripted numbers.
Not a great solution but it worked.
The simplest way would be to use two different UILabels. A better solution might be to draw both strings using -drawInRect:withFont: in a custom view's -drawRect: method.

Spacing between characters on the iPhone

I have a label and I wish to increase the spacing between characters.
I tried adding a space between each character, but this was too much
Perhaps there is a font with large spacing between the letters?
If all else fails, I am considering putting each character (only a size character code), into its own textbox.
Any ideas on how to achieve this?
There is a way to insert a half space, but I don't recall the exact command (option-spacebar?). Wikipedia has a complete list of spaces you can use.
Another approach would be a UIWebView with the letter-spacing CSS attribute set.
You're better off creating a custom view and using your drawRect routine to draw the text manually. You can use CFAttributedString to hold your text along with kerning information.
Update: sounds like you can't actually use CFAttributedString to draw text on the iPhone. You can still use your drawRect to draw the customized text, but it will take some more work to actually get your custom kerning to work.

Multiple UILabels to display decorated XML markup

I have a block of content (stored in XML) that I want to put in a UIScrollView. Certain parts of this text will be formatted with different fonts, sizes, and colors. Altogether, it mostly reads as a paragraph with word wrapping.
I've built my NSXMLParser code, and I have separated all the data. I'm ready to apply my decorations and add these elements as UILabels.
However, I'm looking for a solution to ease the inherent difficulties of string height/width calculations and all of that arithmetic to make these UILabels line up with word wrapping nicely. [keeping track of your last X and Y coordinates, knowing when to insert manual line breaks, how to best vertically display a line that has 2 different sized fonts]
The XML markup can easily be converted to HTML, and thus UIWebView, but I hear that is slower to load.
Is the UIWebView going to be the best class for this? I wish there were one that did all of this with UILabels so that I can use these elements for touch events. (I assume that I cannot use an HTML element to trigger a touch event.)
You should probably a UIWebView. You can use an HTML anchor for touchable elements. The delegate will give you the option of doing something other than loading a web-page when the user touches the element. You can use a made-up URL format to uniquely identify each element.
Aside from that, you may want to use a custom control that draws all the text, rather than a series of UILabels. The UILabels will probably make it difficult to do line wrapping.