Rotate around the center of a CCLabelTTF as achnor point - objective-c

I want to rotate a CCLabelTTF around it's center.
But it doesn't look like it. It does look more like a rotation at the bottom of the CCLabelTTF.
Code:
CCLabelTTF *aLabel ... init/addChild and so on
CCRotateBy *rotateLabelA = [[CCRotateBy alloc] initWithDuration:0.5f angle:-60.0f];
aLabel.string = #"0";
aLabel.anchorPoint = ccp(0.5f, 0.5f);
[aLabel runAction:rotateLabelA];
How to rotate a letter around its visible center, if it is a CCLabelTTF?
I was able to make the boundary box of a CCLabelTTF visible:
As seen in the image, the bounding box is much bigger. But there isn't a formula to determine the middle of the letter.

If you set anchorPoint = cpp(0.5f,0.5f) to some ccNode object, it will rotate around its center, which is calculated using boundingBox property.
The problem is the label's boundingBox.size.height differs with it's actual height. That is why it rotates not around the center.
I am not sure in such a manual solution, but it worked for me someday.
CCLabelTTF *label = [CCLabelTTF labelWithString:#"0" fontName:#"Marker Felt"fontSize:24];
label.position = ccp(winSize.width /2.0f, winSize.height / 2.0f);
float fontSize = label.fontSize; // actual Font size
float labelHeight = label.contentSize.height; // actual label height ( the same as boundingBox.size.height
float offset = (labelHeight - fontSize - (labelHeight - fontSize) / 2.0f) / labelHeight / 2.0f;
label.anchorPoint = ccp(0.5f, 0.5f + offset);
[layer addChild:label];
[label runAction:[CCRotateBy actionWithDuration:10.0f angle:-360]];

I found out how to find the middle point of an CCLabelTTF:
float fontSize = bLabel.fontSize; // actual Font size in pixels
float labelHeight = bLabel.contentSize.height; // actual label height ( the same as boundingBox.size.height )
float offset = labelHeight - fontSize; // the free room under the font
float halfFontSize = fontSize / 2;
float percentMiddleOfFont = (halfFontSize + offset) / labelHeight;
bLabel.anchorPoint = ccp(0.5f, percentMiddleOfFont);

Related

How to change screen size from user input value

I have one requirement to display image into imageview with aspect ratio from user input dimension. If the user enter the width = 2000, height =500, but my image size is 350x199. How can i fit the aspect ratio of the image into user input. If user enters the 2000 then i need to keep the iPad screen width is 2000 then only i can keep aspect ratio. How can i do this?
imgView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 10, 350, 199)];
This code should help you:
//input data
CGSize screenSize;
CGSize enteredRoomSize;
CGSize originalImageSize;
//ratio calculation
CGFloat widthRatio = screenSize.width / enteredRoomSize.width;
CGFloat heightRatio = screenSize.height / enteredRoomSize.height;
CGFloat minRatio = MIN(widthRatio, heightRatio);
//results calculation
CGSize roomViewSize = CGSizeMake(enteredRoomSize.width * minRatio, enteredRoomSize.height * minRatio);
CGSize imageSize = CGSizeMake(originalImageSize.width * minRatio, originalImageSize.height * minRatio);
If you want to use different ratios for width and height use the following code:
//input data
CGSize screenSize;
CGSize enteredRoomSize;
CGSize originalImageSize;
//ratio calculation
CGFloat widthRatio = screenSize.width / enteredRoomSize.width;
CGFloat heightRatio = screenSize.height / enteredRoomSize.height;
//results calculation
CGSize imageSize = CGSizeMake(originalImageSize.width * widthRatio, originalImageSize.height * heightRatio);

Attach UILabel to image thumbnail bottom (varying heights)

I have a view with image view and Label. Image view displays images of varying sizes and it is fixed to the top(see image) I want to dynamically glue text label to the bottom of every image without any space between image thumbnail and UILabel.
You can do that programically. I assume that you have UILabel attached to "label" and the image to "imageView" variables.
CGRect labelFrame = label.frame;
labelFrame.origin.y = imageView.frame.origin.y + imageView.frame.size.height + any_space_you_want_between_image_and_label;
label.frame = labelFrame;
That will change the position of label just bellow the imageView. I hope this helps.
Because as you mentioned you use UIViewContentModeScaleAspectFit for the content mode the solution is a bit harder.
You have to actually calculate the final height of the image (the actual size of the image inside the UIImageView):
//UIImage *img = ...; UIImageView *imgView = ....
CGFloat imageWidth = img.size.width;
CGFloat imageHeight = img.size.height;
CGFloat viewWidth = imgView.frame.size.width;
CGFloat viewHeight = imgView.frame.size.height;
float actualHeight = imageHeight * viewWidth / imageWidth;
// this is the actual height of the UIImage inside the UIImageView
CGRect labelFrame = label.frame;
labelFrame.origin.y = imageView.frame.origin.y + actualHeight + any_space_you_want_between_image_and_label;
label.frame = labelFrame;

CGRect changes width when device rotated

I want to draw a XoY coordinate axis... The axis are CGRects .. the thing is they change width when the device is rotated ... I would want them to maintain their with in all rotations. Does width 5.0 mean different things when the device is in portrait rather than landscape?
Here is the code:
CGContextSaveGState(ctx);
CGContextSetFillColorWithColor(ctx, [[UIColor whiteColor] CGColor]);
// the axis is a rect ...
//axis start point
CGFloat axisStartX = viewBounds.size.width * LEFT_EXCLUSION_LENGTH_PERCENT;
CGFloat axisStartY = viewBounds.size.height * UNDER_EXCLUSION_LENGTH_PERCENT;
CGFloat axisLength = viewBounds .size.height - (viewBounds.size.height * OVER_EXCLUSION_LENGTH_PERCENT) - viewBounds.size.height * UNDER_EXCLUSION_LENGTH_PERCENT;
CGContextAddRect(ctx, CGRectMake(axisStartX, axisStartY, AXIS_LINE_WIDTH, axisLength));
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
I would not know what you are up to with this calculation, but viewBounds.size.height may change on rotation, depending on what it represents. But if its height varies for different orientations then the axisLength will vary too. And axisLength is the height of your rect.
If you want you rect to be of same size in every orientation than do this!
CGContextSaveGState(ctx);
CGContextSetFillColorWithColor(ctx, [[UIColor whiteColor] CGColor]);
// the axis is a rect ...
//axis start point
CGFloat boxSize = MIN(viewBounds.size.width, viewBounds.size.height);
CGFloat axisStartX = boxSize * LEFT_EXCLUSION_LENGTH_PERCENT;
CGFloat axisStartY = boxSize * UNDER_EXCLUSION_LENGTH_PERCENT;
CGFloat axisLength = boxSize - (boxSize * OVER_EXCLUSION_LENGTH_PERCENT) - boxSize * UNDER_EXCLUSION_LENGTH_PERCENT;
CGContextAddRect(ctx, CGRectMake(axisStartX, axisStartY, AXIS_LINE_WIDTH, axisLength));
CGContextFillPath(ctx);
CGContextRestoreGState(ctx);
The idea here is that whatever the orientation is, the size remains same and visible on screen.
hope that helps!

How to set size of UIScrollView frame programmatically?

I am newbie so my question can be really obvious, but I didn't find any solution so far.
I did in IB UIScrollView and connected it with File's Owner.
I would like to set now the frame size of my UIScrollView (named ScrollView).
const CGFloat BoardWidth = 320;
const CGFloat BoardHeight = 400;
//I tried this way but 'Expression is assignable' - said Xcode
ScrollView.frame.size.width = BoardWidth;
ScrollView.frame.size.height = BoardWidth;
So how can I the easiest set own sizes of ScrollView frame?
CGRect scrollFrame = CGRrectMake(x, y, w, h);
ScrollView.frame = scrollFrame;
Or if you need only to change the width and height;
CGRect scrollFrame;
scrollFrame.origin = ScrollView.frame.origin;
scrollFrame.size = CGSizeMake(w, h);
ScrollView.frame = scrollFrame;
Edit keeping the center unchanged:
CGRect scrollFrame;
CGFloat newX = scrollView.frame.origin.x + (scrollView.frame.size.width - w) / 2;
CGFloat newY = scrollView.frame.origin.y + (scrollView.frame.size.height - y) / 2;
scrollFrame.origin = CGPointMake(newX, newY);
scrollFrame.size = CGSizeMake(w, h);
scrollView.frame = scrollFrame;
you need to do this, for example.
ScrollView.frame = CGRectMake(0, 0, BoardWidth, BoardHeight);
Once done you need also to set contentSize property. It's the area that 'extends' behind the frame of your UIScrollView.
If you want to scroll only horizontally:
ScrollView.contentSize = CGSizeMake(w * BoardWidth, BoardHeight);
If you want to scroll only vertically:
ScrollView.contentSize = CGSizeMake(BoardWidth, h * BoardHeight);
If you want to scroll both horizontally and vertically:
ScrollView.contentSize = CGSizeMake(w * BoardWidth, h * BoardHeight);
where w and h are generic values to increment your width and/or your height.
If you want have an horizontal (for example) discrete scroll (e.g. you have some pages with the same dimension of your screen).
ScrollView.pagingEnabled = YES;
ScrollView.contentSize = CGSizeMake(p * BoardWidth, BoardHeight);
where p is the number of pages you want to display.
Hope it helps.
You can do it as below,
scrollView.frame = CGRectMake(xOrigin,yOrigin,width,height);
If you are looking for content size of scrollview then it as below,
scrollView.contentSize = CGSizeMake(width,height);
CGRect Frame = ScrollView.frame
Frame.frame.size.width = BoardWidth;
Frame.frame.size.width = BoardWidth;
ScrollView.frame = Frame;
Since frame is a structure..you can't set the frame of an object directly.. You will have to make a Cgrect and then manipulate it.
using contentSize property
ScrollView.contentSize = CGSizeMake(320, 520);
it needs to be bigger than the frame so it actually scrolls.

Need help to make own coordinate system (classic, center of UIView is 0,0)

I need to create my own coordinate system in UIView, where 0,0 is center of UIView. But I don't know ho to do this. Please help.
UIView *view = /*...*/;
CGContextRef ctx = /*...*/;
/* Shift center from UL corner to mid-x, mid-y. */
CGRect bounds = [view bounds];
CGFloat hx = bounds.size.width / 2.0;
CGFloat hy = bounds.size.height / 2.0;
CGContextTranslateCTM(ctx, hx, hy);
/* y still increases down, and x to the right. */
/* if you want y to increase up, then flip y: */
CGContextScaleCTM(ctx, 1.0/*sx*/, -1.0/*sy*/);
By default, (0,0) is in the upper left corner of the view. To move this point to the view's center, modify its bounds:
CGFloat width = self.bounds.size.width;
CGFloat height = self.bounds.size.height;
self.bounds = CGRectMake(-width/2.0, -height/2.0, width, height);
Make sure to repeat this calculation whenever the size of the view changes.