mk12
mk12

Reputation: 26404

iPhone Dev - UIView frame and loadView

I'm learning to develop for iPhone (programmatically, I don't like IB). I only use IB for the frames of things, so I design in IB but only use it to check each control's frame. Something I've gotten very confused about is the frame of a UIView. First of all, if you do not implement loadView in a view controller, it automatically creates an empty UIView (and I've noticed that its black) and assigns that to self.view, correct? What about the frame? does it automatically figure out what the frame should be? I mean, it needs to be different depending on the if there is a status bar, if there's a tab bar, a toolbar, the orientation. In my tab bar app, it seems no matter what I set frame of my uiview is, it still looks fine. And also, the frames for UIView seem messed up in IB. Like the y value of a UIView taking up the whole window (except status bar) is 0, when it should be 20, because the status bar takes up the top 20 pixels. And in IB a view in a tab bar controller has a y value of 411, even though it begins right under the status bar. And whenever I NSLog a frame (the four numbers, view.frame.origin.x, view.frame... etc.) the x, y, width and height are always 0.. Can someone who understands it please explain it to me? Thanks!!

Ok, this is weird... This:

CGRect test = CGRectMake(0, 20, 320, 460);
NSLog(@"%d %d %d %d", test.origin.x, test.origin.y, CGRectGetWidth(test), CGRectGetHeight(test));

gives output:

0 0 0 1077149696

??? What's with that?

Upvotes: 1

Views: 4553

Answers (3)

mk12
mk12

Reputation: 26404

Answer: IB doesn't always show correct origin/location coordinates, and some things, like UITabBarController, resize the view to be what they want it to be no matter what you set it.

Upvotes: 0

Ramin
Ramin

Reputation: 13433

Pixel sizes are floats because on the desktop you need precise math when doing scaling and want to support proportional sizing. If you stick to integers and the window size is expanded by, say 1.2x, integer round-off will throw things out of line. They kept the same thing on the iPhone because you can have subviews that get auto-sized and floats offer more control over size and position.

As for the view positions, if you go into IB and select a view and check the "View Attributes" inspector you'll see one of the options is to show "Simulated Interface Elements." By default it has the Status Bar enabled (with Gray) and it allows for its height in the interface. If you check the size tab in the inspector, the view height is actually set to 460 (allowing for the 20 pixel status bar).

You can choose to include a top bar or a bottom bar and it will "simulate" those by adjusting the content height for you. This is just a positioning simulation so you can lay out your controls. At runtime, it's assumed you'll load the view into the proper viewcontroller which will have the proper chrome so it should all look right.

A lot of IB numbers are there for relative positioning. When you add the view to a navcontroller or a tabview, this view becomes a child of those parent views and by default they autoresize subviews. So if you've "simulated" for that top bar in IB, your controls should all be lined up properly and flow into the right place and you should see what you expect (of course, depending on what parent control ends up with your subview as a child).

BTW, you're missing out a lot of convenience by not using IB to wire up the controls and connecting them to IBOutlets. It really helps take out a lot of manual effort and extra code. It's like Superman refusing to use his X-ray vision and instead deciding to punch through walls :-)

Upvotes: 0

keno
keno

Reputation: 2966

First thing you should note is that CGRect's origin and size members use float, so in your NSLog statement you need to use %f, not %d. So for example,

NSLog(@"%f %f %f %f", test.origin.x, test.origin.y, test.size.width, test.size.height);

Upvotes: 5

Related Questions