CGRect is the type for the frame property in UIViews.
Which is a c struct defined in CGGeometry.h as the following:
struct CGRect {
CGPoint origin;
CGSize size;
};
typedef struct CGRect CGRect
What’s wrong with frame and CGRect? I mean they were written by Apple!
I position and resize views all the time, but I very rarely do it at the same time. What I mean is I might move the view to the position (100, 50), but maintain the size. This is how:
// method 1: use the original frame
// I have 3 lines of code for 1 task
CGRect frame = view.frame;
frame.origin = CGPointMake(100, 50);
view.frame = frame;
// method 2: recreate the frame rect
// I must pass the width and height
view.frame = CGRectMake(100, 50, view.frame.size.width, view.frame.size.height);
// method 3: not legal, but how I want to do it
view.frame.origin = CGPointMake(100, 50);
It might seem I’m complaining about writing a couple extra lines of code. But currently I’m updating the whiteboard feature in my app, which is over 2500 lines of code. The extra lines are not a hassle, they are just adding more mess to scroll past, along with affecting readability.
So if CGRect was a class, it would be able to comply with KVO. As far as I know, this is the reason the frame property not assignable. This means I could change the values of the CGRect and the view can be notified to redraw. Note: the setFrame method of UIView doesn’t just set a value, but instead lets the view know to redraw with a new size.
I’m not going to end my post with just that. Here’s a solution:
// include this function in a class, or in the prefix file
CGRect CGRectMoveOrigin(CGRect rect, CGFloat x, CGFloat y)
{
CGRect rect;
rect.origin.x = x;
rect.origin.y = y;
return rect;
}
// example
view.frame = CGRectMoveOrigin(view.frame, 100, 50);
// if CGRect were KVO compliant
view.frame.origin.x = 100;
view.frame.origin.y = 50;
I am aware of CGRectOffset, but what if I don’t want to do inline math to change the position? 🙂
In the end, I’m not actually going to use my method, now. I might in future projects. There are a lot of times where I’m only changing one of the 4 values in the CGRect, which would imply I want a ton more CGRectXXX(CGRect frame, ….) functions, and I don’t want that.
But direct access to the frame’s struct would be nice.