Reputation: 29094
I am trying to set the origin of the frame programmatically.
Method1:
button.frame.origin.y = 100;
Method 2:
CGRect frame = button.frame;
frame.origin.y = 100;
I tried method 1 but it is not working(showing an error saying Expression is not assignable). Method 2 is working. Why is this so?
Need guidance on what I am doing right.
Upvotes: 15
Views: 19495
Reputation: 4208
button.frame.origin.y = 100;
equals to the following call:
[button getFrame].origin.y = 100;
in which [button getFrame]
gives you the copied CGRect
.
You are trying to set a variable of a structure of a structure. There is no pointer from the UIView
to the structure (as it is a basic C struct
so can't be pointed). hence, copied instead.
So basically, you are copying the structure and setting it. But, that just doesn't work like that.
Upvotes: 0
Reputation: 12224
The reason you can't do method #1 is because a frame's individual properties are read-only. However, the entire frame itself is writable/assignable, thus you can do method #2.
You can even do tricks like this:
CGRect newFrame = button.frame;
newFrame.origin.y += 100; // add 100 to y's current value
button.frame = newFrame;
Upvotes: 27
Reputation: 511
It's because if you were able to directly change a frame's origin or size, you would bypass the setter method of UIView's frame property. This would be bad for multiple reasons.
UIView would have no chance to be notified about changes to it's frame. But it has to know about these changes to be able to update it's subviews or redraw itself.
Upvotes: 1
Reputation: 17535
You know
button.frame.origin.y
return a value.
if you are using this one so you will get this error...
Expression is not assignable.
button.frame.origin.y = 100;
So this is correct way
CGRect frame = button.frame;
frame.origin.y = 100;
otherwise you can do like this...
button.frame = CGRectMake(button.frame.origin.x, 100, button.frame.size.width, button.frame.size.height)
Upvotes: 3