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.