Objective-C - When I add a subview, my subview is going out of the screen at the bottom. Misunderstanding of frames?

StackOverflow https://stackoverflow.com//questions/25069799

Question

Im practicing objective-C, and I try to do everything programmatically.

I'm making a simple view that I add on my view of the ViewController, but this subview is going out of the screen. When I set my frame, the position for the X and Y are respected, but the rest, no...

Here is the screenshot of my result : enter image description here

As you can see... The red subview is going out of the screen.

Here is my loadView where I add that subview :

HomeViewController.m - loadView

-(void)loadView
{
    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];

    UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(15, 15, self.view.frame.size.width - 30, self.view.frame.size.height - 30)];
    [subview setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:subview];
}

For the padding, I did put 15 for the position x and y... And for the frame, I did calculate with the size of the self.view by removing paddings... As you see, it works well for the width, but for the height, it is a big fail. It goes outside the screen.

In my AppDelegate.h, I set the navigationController.navigationBar.translucent = NO;, in order to that when I set position for x, and y, it starts well after the navigationBar .

I don't understand this weird behavior for the height... If someone has a good explanation for this please.

Thanks

Was it helpful?

Solution

First, you shouldn't rely on the value of self.view in viewDidLoad. It is set to a correct value later, in viewWillAppear:. You can keep your code, if you make your subview resize automatically when self.view is displayed. For that, set autoresizingMask on the subview:

subview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

(or add an equivalent set of constraints if you use Auto Layout.)

Also, I recommend to use bounds instead of frame:

UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(15, 15, self.view.bounds.size.width - 30, self.view.bounds.size.height - 30)];

It doesn't make a difference here, but it often does, e.g. if you calculate the frame's x and y based on the parent frame.

OTHER TIPS

loadView method just creates the view. At the point when loadView gets called there is no information about final view frame hence its children views cannot be placed properly.

The right place to update your children views' frames is viewDidLayoutSubviews:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    // update child view frame here
}

Remarks: you can define auto-layout constraints of your child view in code and they will be automatically applied to child views when view controller's view gets resized.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top