CGRectIntegral what is the usage of it? - iphone

How does one use the CGRectIntegral function? I understand it's purpose.
The documentation isn't clear on it's exact use.

CGRectIntegral to convert any decimal values to their integer equivalents
see image may be you can understand
How do I fix it?
frame = CGRectIntegral(frame);
-OR-
myTextView.frame = CGRectIntegral(myTextView.frame);
 
see this for more information of CGRectIntegral

CGRectIntegral Method is used to create integer rect . I mean to say suppose if you calculate frame in app you may get frames value in float.
Setting float value as frame to some UIElement like UILabel would make the text looks blur. To avoid that, we use CGRectIntegral.Please look at the example below,
NSLog(#"%#",NSStringFromCGRect( CGRectIntegral(CGRectMake(0, 15.6, 16.1, 20.2))));
This will print, {0,15},{17,21}.
This explanation is found in the header file.
/* Expand `rect' to the smallest rect containing it with integral origin and
size. */

One particular usage is to fix frames that do not align perfectly with on-screen pixels.
See this question: UITextField blurred text
If a label or textfield has a frame that isn't pixel-aligned when rendered to the screen, the text will appear blurred. This can happen if you calculate the frame using division (for example to center it in a parent view).
CGRectIntegral will remove the fractional part of the frame, fixing this problem. Note however that with retina displays a .5 frame value is pixel aligned, but CGRectIntgral will still remove the fractional part.

Related

UILabel: Get actual font size with adjustFontSizeToFit

I have two labels in my layout.
I want the font size to adjust to fit the label bounds.
I set to true the UILabel adjustFontSizeToFit.
Moreover a need the two labels to have the same font size. So I added an auto-layout constraint to make the labels have the same size.
The issue with it is the labels do not contain the same string. Sometimes the first is longer and vice-versa. The font I use doesn't have the same width for every character which will not allow me to use a space to fill to shorter string. (This solution looks a bit ugly to me).
I tried to get the label.font.size.pointSize after the label has been displayed but the value returned is always the one I set at the beginning (before being reduced to fit).
Does anyone have an idea on how I could achieve it ?

find the frame or position from the content drawn on the screen [duplicate]

Here's a screenshot of the twitter app for reference: http://screencast.com/t/YmFmYmI4M
What I want to do is place a floating pop-over on top of a substring in an NSAttributedString that could span multiple lines. NSAttributedString is a requirement for the project.
In the screenshot supplied, you can see that links are background-highlighted, so it leads me to believe that they're using CoreText and NSAttributedStrings. I also found something called CTRunRef ( http://developer.apple.com/library/ios/#documentation/Carbon/Reference/CTRunRef/Reference/reference.html ) which looks promising, but I'm having trouble fitting it all together conceptually.
In short, if I have a paragraph in core text and when I tap on a word, how do I find the bounding box for that word?
Set some attribute in the attributed string that won't effect display, but will cause it to be laid out as a seperate glyph run, then use CoreText to layout the string
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(attrString);
CTFrameRef ctframe = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
Now you will have to hunt through the frame to find the relevant chunk of text. Get the array of CTLineRefs with CTFrameGetLines().
Iterate through the array, testing if the touch was on that line, by checking it is within the rect returned by CTLineGetImageBounds(). If it is, now look through the glyph runs in the line.
Again, you can get an array of CTRunRefs with CTLineGetGlyphRuns(). Check whether the tap was within the glyph run with CTRunGetImageBounds(), and if it was you can find the the range of indices in the original attributed string that the glyph run corresponds to with CTRunGetStringIndices().
you need to find Y by CTLine and X by CTRun width and height you can get by word and font itself. ill attache my project link, its really simple code but you can reedit in order to meet your needs. hope it helps cheers if you improve general logic please let me know thx.
textViewProject
The link given by George was very helpful and got me what I wanted. But strange thing happened. It was working in iOS SDK 4.0 but in the iOS SDK 5 the position of the link appeared in wrong position on the view.
So I had to tweak the code a little bit. For the x coordinates of the touchable button, I had to use CTRunGetTypographicBounds instead of the CTRunGetImageBounds function.
So over all, in the tweaked code:
The y Coordinate , width and height was calculated using CTRunGetImageBounds.
And x coordinate was calculated using CTRunGetTypographicBounds.
I've been working on a small library that does exactly that. You can find it here: https://github.com/pothibo/CMFramework
However, this library is in its alpha stage, there's optimization needed and some feature are lacking (line height is one of the urgent feature I want to add)
If you decide to use it and find issue, don't hesitate to post issues on github!

CTLine or NSAttributedString -- get image bounds without a graphics context?

Is this possible? Basically, I have a bunch of NSAttributedString objects and corresponding CTLine objects. I want to get the image bounds before the drawRect stage. So at this point, there is nothing to draw into. I will then use these image bounds to decide exactly what I need to create for drawing.
EDIT: Another measurement of the size would probably work just fine. But calling the deceptively named CTLineGetTypographicBounds function only returns the width. If I pass in addresses of ascent and descent floats, they come back as zero.
EDIT: The given answer works great in MacOS. Can anyone do it in iOS?
If you are developing for iOS6+. You can use the following method:
CTLineRef line;
// Create the line...
CGRect bounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsUseGlyphPathBounds);
// use bounds...
This is gives the same bounds as CTLineGetImageBounds() assuming you have no transforms applied in your context, but does not require the context. For iOS 5 and below, you would need to use the method described by Иван.
CTLineGetTypographicBounds() gives me a different width than this function or image bounds. I am not sure why. And the ascent and descent returned are those of the font and not the characters displayed in the CTLineRef.
Yes, you can, but not so easy.
You should, generally use CTLineGetTypographicBounds() which, for me, does return ascent, descent and leading, but a bit messed up - 'ascent' equals the total height (i.e. what should be ascent + descent) and 'descent' is always the maximum descent of the font - no matter if you have descending characters or not.
Other way is to retrieve the CTRun(s) from the line (CTLineGetGlyphRuns), then get the glyphs array (CTRunGetGlyphs or CTRunGetGlyphsPtr) and then using CTFontGetBoundingRectsForGlyphs and CTFontGetAdvancesForGlyphs build up the information you need.
EDIT:
I've just found this method: "- (NSRect) boundingRectWithSize:(NSSize)size options:(NSStringDrawingOptions)options" of NSAttributedString which seems to do exactly what is needed.
Hope, this is helpful...
Bounds returned by CTLineGetTypographicBounds() are not the same as image bounds. As the name, (and Иван's answer) suggests, ascent etc. are defined for the font and won't change based on the string. For example, you would use it if you want to find the correct line height if you have a multiline text, as line height normally should not depend on the exact characters you use.
CTLineGetImageBounds() on the other hand, returns the bounds that exactly fit the image. For example, if you want to draw a box around a single line, this is what you need.
CTLineGetImageBounds() needs a context because there may be text transforms and things like that. If you don't want to worry about that, just use a dummy context. For example:
CTLineRef line;
// create the line...
UIGraphicsBeginImageContext(CGSizeMake(1, 1));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetTextPosition(context, 0, 0);
CGRect bounds = CTLineGetImageBounds(line, context);
UIGraphicsEndImageContext();
// use bounds...
Another method is to convert the string to glyphs usingCTFontGetGlyphsForCharacters() and then calling CTFontGetBoundingRectsForGlyphs() with the glyph array you get from the first function. The latter function returns "the overall bounding rectangle for the glyph run" so don't worry about having to do processing on the individual bounding rects. If used both these functions successfully in iOS.
If you do this remember the mapping between glyphs and characters is not always one to one, especially when the string has non-English characters.

Size of TTStyledText with floating image is being computed wrong

I have a TTStyledText with a floating image. The problem that I am facing is that the height of the text incase there is a floating image larger than text, is being computed wrong. Instead of incorporating the size of the image + text accompanying the image, The implementation just returns size of text. This causes the image to be clipped.
Any one else has faced this issue?
I finally solved this by defining a TTBoxStyle with minimum size. This way even if the image is clipped the minimum size ensures that some part of the image is displayed properly.

StretchableImageWithLeftCapWidth stretching wrong portions

I am trying to use a UIImage with stretchableImageWithLeftCapWidth to set the image in my UIImageView but am encountering a strange scaling bug. Basically picture my image as an oval that is 31 pixels wide. The left and right 15 pixels are the caps and the middle single pixel is the scaled portion.
This works fine if I set the left cap to 15. However, if I set it to, say, 4. I would expect to get a 'center' portion that is a bit curved as it spans the center while the ends are a little pinched.
What I get is the left cap seemingly correct, followed by a long middle portion that is as if I scaled the single pixel at pixel 5, then a portion at the right of the image where it expands and closes over a width about twice the width of the original image. The resulting image is like a thermometer bulb.
Has anyone seen odd behavior like this and might know what's going on?
Your observation is correct, Joey. StretchableImageWithLeftCapWidth does NOT expand the whole center of the image as you would expect. It only expands the pixel column just right of the left cap and the pixel row just below the top cap!
Use UIView's contentStretch property instead, and your problem will be solved. Another advantage to this is that contentStretch can also shrink a graphic properly, whereas stretchableImageWithLeftCapWidth only works when making the graphic larger.
Not sure if I got you right, but LeftCapWidth etc is made for rounded corners, with everything in the rectangle within the rounding radius is stretched to fit the space between the 'caps' on the destination button or such.
So if your oval is taller or wider than 4 x 2 = 8, whatever is in the middle rectangle will be stretched. And yours is, so it would at least look at bit ugly! But if it's not even symmetrical, something has affected the stretch. Maybe something to do with origin or frame, or when it's set, or maybe it's set twice, or you have two different stretched images on top of each other giving the thermometer look.
I once created two identical buttons in the same place, using the same retained object - of course throwing away the previous button. Then I wondered why the heck the button didn't disappear when I set alpha to 0... But it did, it's just that there was a 'dead' identical button beneath it :)