For Example:
I can get the height of UIImageView(identifier:ImgView) by the top and bottom constraints and I want to let its width be (4/3 x height).
How can I do it?
I have ever tried doing it by this sentence:
ImgView.frame.width = ImgView.frame.height * 4.0 / 3.0
But it didn't work with an error said:
it can't assign to ImgView.frame.width
So, how can I achieve this?
Use a ratio constraint. Easy peasy.
Try this:
CGRect frame = ImgView.frame;
frame.size.width = frame.size.height * 4/3;
ImgView.frame = frame;
Or a one-liner:
ImgView.frame = CGRectMake(ImgView.frame.origin.x,
ImgView.frame.origin.y,
ImgView.frame.size.height * 4/3,
ImgView.frame.size.height);
I am somewhat new to iOS and to change the width or height of a view I am using the following code:
view.frame = CGRectMake(view.frame.origin.x,
view.frame.origin.y,
view.frame.size.width,
newHeight);
This feels wrong because I am copying all of the old values into a new rect just to change a single value, but I can't just do:
view.frame.size.height = newHeight;
Is there a better way to do this?
You can't assign the values directly. You have to create a variable for it:
CGRect frame = view.frame;
frame.size.height = newHeight;
view.frame = frame; // or [view setFrame:frame];
Another way which helps you keep the frame variable in a different scope:
view.frame = ({
CGRect frame = view.frame;
frame.size.height = newHeight;
frame;
});
I have a UIlabel that when a user clicks a button its text changes, this label is then resized using:
CGRect frame = label.frame;
[label sizeToFit];
frame.size.height = label.frame.size.height;
label.frame = frame;
So that the width is kept the same but the height of the label is changed so all text fits in this.
I then however need the uiview below this label to be moved down so that it starts at the bottom of the label, how do I do this?
Worked it out in the end by doing:
CGRect contentframe = _lbl_content.frame; //the uilabel
CGRect keyframe = _view_keystuff.frame; //the uiview
float startlocation = contentframe.origin.y;
startlocation += contentframe.size.height;
keyframe.origin.y = startlocation;
_view_keystuff.frame = keyframe;
You just want to put the UIView below the label?
Try this:
UIView *viewBelowLabel = [[UIView alloc] init];
viewBelowLabel.frame = CGRectMake( "your view origin x", label.frame.origin.y + label.frame.size.height, "your view size width", "your view size height");
You should adjust UIView frame after the resizing of the label
I am calling a custom picker in my application when i hit a button.
The picker looks like a bubble so i am pointing it to the button like this :
thePicker.presentFromRect = button.frame;
I need the picker to show 300 pixels down from this button. How can i do that?
How can i add 300 pixels height on the above statement ?
You need to use :
CGRect frame = self.window.frame;
frame.size.height += 30;
thePicker.presentFromRect = frame;
You should create a new frame and edit its height property like so:
CGRect frame = button.frame;
frame.size.height += 30;
thePicker.presentFromRect = frame;
First get the frame of the button so to be able to work on it.
Then change his height as you like, accessing the size attribute.
Finally, reassign the frame to the picker
CGRect buttonFrame = button.frame;
buttonFrame.size.height += 300;
thePicker.presentFromRect = buttonFrame;
When would an UIView's bounds.origin not be (0, 0)?
This paragraph was helpful to me:
IMPORTANT!! Bounds X and Y, the origin, are for moving inside the
View. For eample X+5, moving 5pix to the left of the frame's origin
meaning draw all content within this View to the left 5pix of frame's
origin. It doesn't do anything to itself, it is what being drew on it
that get affected.
But it describes only the case when I had set the value of bounds.origin myself.
In what other cases the value of bounds.origin != (0, 0)?
View's frame determines its location in superview. View's bounds determines its subviews locations. That means, if you change view's bounds, its location won't be changed, but all of its subviews location will be changed.
Positive width and height is like you draw a view from upper-left to bottom-right, while negative value is from bottom-right to upper-left. So
frame1 = CGRectMake(100, 100, -50, -50)
is totally identical with
frame2 = CGRectMake(50, 50, 50, 50).
And in fact, if you init a view with frame1, it will AUTOMATICALLY CHANGED to frame2.
But the bounds.origin of the views are not identical. Bounds.origin indicates the point that you "draw" the view, so all subviews frames will originate at this point.
For example, in Landscape iPhone 6, we have:
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 275, 275)];
leftView.backgroundColor = [UIColor greenColor];
[self.view addSubview:leftView];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(667-50, 375-50, -275, -275)];
rightView.backgroundColor = [UIColor blueColor];
[self.view addSubview:rightView];
And we got:
We will find that rightView's frame is automatically changed to positive value, which is (342, 50, 275, 275), but its bounts.origin = (-275,-275).
And we add subviews:
UIView *leftSubview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
leftSubview.backgroundColor = [UIColor grayColor];
[leftView addSubview:leftSubview];
UIView *rightSubview= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
rightSubview.backgroundColor = [UIColor grayColor];
[rightView addSubview:rightSubview];
So the bounds makes rightView's subview follows the origin which we init rightView.
If we change the bounds of rightView equals to leftView:
rightView.bounds = leftView.bounds;
Then the two subViews location is the same, we lost the information that rightView's width and height are negative.
And we change the bounds of leftView instead of rightView:
CGRect bounds = leftView.bounds;
bounds.origin = CGPointMake(50, 50);
leftView.bounds = bounds;
We can see, its subview's frame.origin is offset by bounds.origin(using minus, not plus).
To conclude:
view.bounds determines all its subview's location(offset by bounds.origin), while bounds will not affect its own location in its superview.
If you init a view with negative width and height, it will automatically changed to positive(which won't change the location), but its bounds.origin indicates the point that you start to "draw" the view.
A UIScrollView's bounds.origin will not be (0, 0) when its contentOffset is not (0, 0).
The bounds.origin will be negative if you initialize a view with negative width/height.
For example, if you did
UIView* v = [[UIView alloc] initWithFrame:CGRectMake(5, 5, -10, -20)];
the frame would be:
origin = {
x = -5,
y = -15
},
size = {
width = 10,
height = 20
}
bounds:
origin = {
x = -10,
y = -20
},
size = {
width = 10,
height = 20
}
center:
x = 0,
y = -5
try it for yourself!
(edited again because I can’t delete my original answer after it was accepted—credit for this goes to ian, who posted a more thorough answer below:)
In most cases this won’t happen. If you initialize your view with a negative width and/or height, you’ll get an origin with a negative X of the width and/or negative Y of the height.