Reputation: 6557
I'm just curious why can't you access view.center.x or view.center.y but you can access view.center and change it.
I wanted to write this code:
imgView_.center = scrollView_.center;
if (imgView_.frame.origin.x < 0)
imgView_.center = CGPointMake(imgView_.center.x + (imgView_.frame.size.width - self.view.frame.size.width) / 2, imgView_.center.y);
if (imgView_.frame.origin.y < 0)
imgView_.center = CGPointMake(imgView_.center.x, imgView_.center.y + (imgView_.frame.size.height - self.view.frame.size.height) / 2);
As:
imgView_.center = scrollView_.center;
if (imgView_.frame.origin.x < 0)
imgView_.center.x = imgView_.center.x + (imgView_.frame.size.width - self.view.frame.size.width) / 2;
if (imgView_.frame.origin.y < 0)
imgView_.center.y = imgView_.center.y + (imgView_.frame.size.height - self.view.frame.size.height) / 2;
I find the second way a lot more elegant, but I can't access the x and y, so I thought I'd ask if anyone knows what's Apple's reason for blocking it.
Upvotes: 0
Views: 2598
Reputation: 53000
In the fragment imgView_.center.x
the .center
is a property access while the .x
is a field access. The type of the property is CGPoint
, which is a structure type which is passed by value.
If you have a variable of type CGPoint
you can directly assign to individual fields, e.g.:
CGPoint myPoint;
myPoint.x = 3;
However when passing a CGPoint
value to a function or method you cannot pass just one of it's fields - it makes no sense. E.g. if you have the function:
void doSomething(CGPoint aPoint);
you could pass myPoint
:
doSomething(myPoint);
but there is no way to say "just pass the x
field" - what would that even mean? The function is expecting a CGPoint
, what would passing it one coordinate mean?
When you put the fragment imgView_.center
on the left hand side of an assignment you are just using a shorthand for calling a method. E.g.:
imgView_.center = myPoint; <=> [imgView_ setCenter:myPoint];
and just like with the function above there is no way to say "just pass the x
field".
The key point is a property access is not a variable access, even though it is often thought of as one, but a function/method call; so you can't assign to the individual fields of a property of structure type.
On the right hand side accessing a field of a property is fine. E.g. on the rhs imgView_.center
translates to [imgView_ center]
- which returns a CGPoint
value, and you can access a field of structure value, so on the rhs imgView_.center.x
translates to [imgView_ center].x
and all is OK. But note that in both cases (setCenter:
and center
methods) the methods themselves take/return a complete CGPoint
.
HTH.
Upvotes: 2
Reputation: 13222
The UIView
property center
is a CGPoint
which is of type struct
and not an ObjectiveC class.
Even though writing this
view.center.x = view.center.x +10;
looks similar to
CGPoint center = view.center;
center.x = center.x +10;
view.center = center;
they are different things.
According to the compiler view.center
is a method call [view center]
and center.x
is accessing the public ivar of the struct CGPoint
. If you write all of this in a single line
view.center.x = view.center.x +10;
compiler is unable to resolve this and throws an error Expression is not assignable
. Reason is view.center.x
is further resolved as function call,
objc_msgSend(view, @selector(center))
Now you are trying to modify the return value of a C function as below
objc_msgSend(view, @selector(center)).x = 20 //(Some value on RHS)
which is not meaningful as the function return value isn't stored anywhere, hence the resulting expression is not assignable.
For more information read through this answer.
Hope that helps!
Upvotes: 2
Reputation: 3960
See center property defined in UIView's
UIViewGeometry
category as below
@property(nonatomic) CGPoint center;
By declaration of center property, we have getter & setter methods for center property. it means we have setter & getter method for structure not for the values inside structure.
and Center is a CGPoint
structure variable that has two CGFloat
value x and y.
that's by we can't set directly x and y values in center property. it is similar to Frame property.
Upvotes: 3