Finding the position of a button. CGRectMake - iphone

I have a button and I'm using CGRectMake to position it like this:
btn5.frame = CGRectMake(211, 280, 109, 60);
I guess 211 and 280 are the coordinates of the button. So how can I modify that code if I want the button to be near the bottom left corner.

Yes, you are correct. The frame of the button defines where it is located on its parent view. So btn5 will be in the position (x = 211, y = 280) and will have the dimensions (width = 109, hight = 60) if you use this code:
btn5.frame = CGRectMake(211, 280, 109, 60);
The general expression is:
btn5.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight);
If you want to change the position of the button to the bottom left corner, you can do like this:
btn5.frame = CGRectMake(0, self.view.frame.size.height - 60, 109, 60);
If you want to add some space between the button and the corner, and also change the size of the button:
CGFloat x = leftPadding;
CGFloat y = self.frame.size.width - desiredHeight - bottomPadding;
btn5.frame = CGRectMake(x, y, desiredWidth, desiredHeight);
For more information, check Apple's View Geometry and Coordinate Systems guide.

In CGRectMake(211, 280, 109, 60) you are defining a frame for your button.
The first two parameters are the x & y coordinates location of the upper-left corner of your button (in the parent view's coordinate system)
The second two parameters are the width and height of your button.
If you want your button in the absolute bottom left corner of the parent's view, then you should set the x coordinate to 0 (i.e. 0 pixels from the left edge of the parent) and the y coordinate to the parent view's height - 60 (where 60 is the height or your button). If you want to leave some margin around your button, then adjust the x and y accordingly.

Related

How to center UIImage and UILabel horizontally together?

I have an image for user's icon and a label for user's name
And I want the image and the label align center horizontally in the screen.
Because the length of the label changes as the length of user's name, (the size of image is fixed)
I can't set the positon as a fixed value.
Now I change the positon of the image and lalel at runtime,
It's not convenient.
Is there any good way to do this?
Thank you:)
Here is the snapshot:
All right.
I know there is no a very convenient way to do this just with IB.
And I learn the function of [label sizetoFit].
It's very helpful.
In android, it's very convenient to do this just with the xml layout.
But in ios I have to write code to control the positon of image and label.
Yes...Not too bad.
Thanks everybody :)
[label sizetoFit];
label.center =imageView.center;
this will make the label center on the image center..and it will appear on top...
now you can just use CGRect manipulation to move the label origin downwards based on your image height.
Edit .. now you can do this ..
CGRect frame = label.frame;
frame.origin.x -= imageview.frame.size.width/2 - 15; // you can change 15 to a more appropriate number based on your preference..
label.frame = frame;
Do the above after you do the 2 lines of code given on top in my answer.
Do some calculation
Width of UIImageView + Offset width (Space b/n UIImageView and UILabel "Keep this as constant value") + UILabel Width = You Will get some 'X' width.
iPhone screen width is 460.
320-X = Remaining width.
Remaining width/2 pass this value to UIImageView's X value. This might help you.
#define MARGIN 10.0f
In your -layoutSubviews method, do this:
[ label sizeToFit ] ;
CGRect r = label.frame ;
r.origin = (CGPoint){ CGRectGetMaxX( imageView.frame ) + MARGIN, CGRectGetMidY( imageView.frame ) - 0.5 * r.size.height } ;
label.frame = CGRectIntegral( r ) ;
update here's how to center the the image view and label unit
bounds should be set to bounds of enclosing view
//
// center an image view + label in parent view, with label to right of image view
//
[ label sizeToFit ] ;
CGSize size = (CGSize){ imageView.image.size.width + MARGIN + label.bounds.size.width,
MAX( imageView.image.size.height, label.bounds.size.height } ;
CGRect r = (CGRect){
{ CGRectGetMidX( bounds ) - 0.5 * size.width,
CGRectGetMidY( bounds ) - 0.5 * size.height },
size }
} ;
CGRect imageFrame, labelFrame ;
CGRectDivide( r, &imageFrame, &labelFrame, imageView.image.size.width, CGRectMinXEdge ) ;
imageView.frame = imageFrame ;
labelView.frame = labelFrame ;

Setting a view's bounds changes the coordinates of the frame, WHY?

Why setting the bounds property of a UIView messes up it's frame's coordinates?
For example:
self.view.frame = CGRectMake(10, 10, 200, 200);
CGRect b = CGRectMake(0, 0, 399, 323);
self.view.bounds = b;
I would expect the view's frame to be (10, 10, 399, 323) but instead the coordinates get some weird values like (-89.5 -51.5; 399 323).
Thanks!
From the UIView class reference:
Changing the bounds size grows or shrinks the view relative to its center point.
So it is keeping the center point in the same place, which means the origin of the frame has to adjust.
If you want to resize the view but keep the origin in the same place, set the frame instead of the bounds.

UIView frame larger than iPhone's screen

I have made a new iPhone View-based project in XCode, and I have a look at the xib generated, with the name myAppViewController.xib. In that xib, the generated view's frame looks like this: { x = 160, y = 230, w = 320, h = 460 } this view is supposed to fill the entire screen, excluding the status bar. I would expect the view's frame to look like this: { x = 0, y = 0, w = 240, y = 300 } for the older iPhones, and { x = 0, y = 0, w = 480, h = 600 } for the retina display. However, I get those weird values above. Can anyone please explain to me what is happening here, it is ruining some of my drawing code in my other project (the area to draw is based off of the frame of the view).
Retina display doesn't actually increase the point size of the view.
When Apple introduced it, it made a difference between points and pixels. Retina display has more pixels, but the same amount of points.
Everything in your code related to UIKit will generally be in points, so no changes are needed there, a view of 100x100 will still be that size.
I don't understand really your question but the frame value can be modified by the bounds property and the center property... so check if you're not modifying those.
Frame rects are as such:
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
the screen width is 320px wide by 480px tall. the status bar is 20px. thus the rect you would want is:
CGRectMake(0,0,320,460)
regardless of retina or not, the device will convert up as needed.
Coordinates are in points, not pixels. The coordinate system is 320 X 480, regardless of the resolution of the screen.

UIView's are not positioning correctly

I have a nib with a 2 UIViews and 2 UILabels with IBOutlet's in my controller.
I am increasing and decreasing the height of these UIViews to look like a bar to indicate when something is 100% or less - like a bar chart almost.
I am using the following method for both bars (reuse) however the first UIView (bar) positions correctly but the second is too low down - the Y axis is wrong. However the height of both is correct.
Anyone have any ideas? I have positioned them in interface builder already all I am actually doing in this method is changing the height (basically)
//Position the point, size and label of a rating bar
- (void)configureRatingBar:(UIView *)vRatingBar
andRatingLabel:(UILabel *)lRatingLabel
usingRating:(NSDecimalNumber *)rating
{
//NSDecimalNumber *foodRating = [self calculateRating:self.currentHotel.foodAndBeverageRating];
NSString *formattedRating = [self formatRating:rating];
lRatingLabel.text = formattedRating;
float newHeight = [rating floatValue]; //The height will be based on the rating 100 max
CGRect currentFrame = vRatingBar.frame; //Current frame of the rating view
//CGPoint currentPoint =
// [vRatingBar convertPoint:vRatingBar.frame.origin toView:vReviews];
CGPoint currentPoint = vRatingBar.frame.origin; //Current point of the rating view
float newYaxis = currentPoint.x + (100 - newHeight); //Y axis must move down with the decreasing rating from 0 (100 %) down
[vRatingBar setFrame:CGRectMake(currentPoint.x, newYaxis, currentFrame.size.width, newHeight)];
[lRatingLabel setFrame:CGRectMake(currentFrame.size.width / 34, newHeight - 20, 34, 21)];
}
I see you have this line:
float newYaxis = currentPoint.x + (100 - newHeight); //Y axis must move down with the decreasing rating from 0 (100 %) down
Where you are using currentPoint.x for the calculation. Should this be currentPoint.y?

Rotate using a transform, then change frame origin, and view expands?

This is quite the iPhone quandry. I am working on a library, but have narrowed down my problem to very simple code. What this code does is create a 50x50 view, applies a rotation transform of a few degrees, then shifts the frame down a few times. The result is the 50x50 view is now much larger looking.
Here's the code:
// a simple 50x50 view
UIView *redThing = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 50, 50)];
redThing.backgroundColor = [UIColor redColor];
[self.view addSubview:redThing];
// rotate a small amount (as long as it's not 90 or 180, etc.)
redThing.transform = CGAffineTransformRotate(redThing.transform, 0.1234);
// move the view down 2 pixels
CGRect newFrame = CGRectMake(redThing.frame.origin.x, redThing.frame.origin.y + 2, redThing.frame.size.width, redThing.frame.size.height);
redThing.frame = newFrame;
// move the view down another 2 pixels
newFrame = CGRectMake(redThing.frame.origin.x, redThing.frame.origin.y + 2, redThing.frame.size.width, redThing.frame.size.height);
redThing.frame = newFrame;
// move the view down another 2 pixels
newFrame = CGRectMake(redThing.frame.origin.x, redThing.frame.origin.y + 2, redThing.frame.size.width, redThing.frame.size.height);
redThing.frame = newFrame;
// move the view down another 2 pixels
newFrame = CGRectMake(redThing.frame.origin.x, redThing.frame.origin.y + 2, redThing.frame.size.width, redThing.frame.size.height);
redThing.frame = newFrame;
So, what the heck is going on? Now, if I move the view by applying a translation transform, it works just fine. But that's not what I want to do and this should work anyway.
Any ideas?
From the UIView documentation:
If the transform property is also set, use the bounds and center properties instead; otherwise, animating changes to the frame property does not correctly reflect the actual location of the view.
Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
In other words, I would be wary of the frame property when a transform is set.