Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

create a view programmatically with frame set to superview's frame?

I have a navigation based application where I place my custom views in the navigation view.

First, I wanna know how to get the "navigation view"'s frame so that I can place my custom view on it properly.
Also, I sometimes hide navigation bar and want to make sure I get the frame info correctly. (not with [[UIScreen mainScreen] bounds] )

Second, in general, how do I access the superview's frame so that I can place a view accordingly?
I tried the following with no success.

-(void) loadView {
[super loadView];
UIView* myView = [[UIView alloc] initWithFrame: CGRectZero];
self.view = myView;
self.view.frame = self.view.superview.frame;
[myView release];
}

or setting the frame in layoutSubviews, but noticed layoutSubviews not getting called. I guess that's because I don't have any subviews in this particular view?

Thank you

-Edit-

with given answers, i now know that i need to set the view.frame to superview's bounds.
The problem is that i'm unable to access superview inside viewDidLoad.
I can see that superview is correctly set in viewWillAppear but not in viewDidLoad.

I found out that viewDidLoad gets called at various times, such as when pushed by pushViewController or accessing self.view
I have the following code and viewDidLoad gets called from nil == controller.view.superview.

if (nil == controller.view.superview) {
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * page;
    frame.origin.y = 0;
    controller.view.frame = frame;
    [scrollView addSubview:controller.view];
}

Since I can't access superview from viewDidLoad, i can't layout the view as i previously did in viewDidLoad. This seems so inconvenient and unnecessarily complex.
Any suggestion please?

like image 509
eugene Avatar asked Nov 09 '10 05:11

eugene


2 Answers

The superview property is nil until your view is added as a subview somewhere. In general, you can't know what the superview will be within the loadView method.

You could use autoresizing properties, as suggested by Costique. Check out the Resizing Subviews in the official UIView docs.

You could also set the frame after the call to loadView, for example in something like this:

MyViewController *myController = [[MyViewController alloc] init];
myController.view.frame = window.bounds;
[window addSubview:myController.view];

By the way, it is generally safer to use the parent's bounds property for the frame of the subview. This is because a parent's bounds are in the same coordinate system as the subview's frame, but the parent's frame may be different. For example:

UIView *parentView = /* set up this view */;
UIView *subView = /* set up subview */;
[parentView addSubview:subView];
parentView.frame = CGRectMake(30, 50, 10, 10);
subView.frame = subView.superview.frame;  // BAD!!!
// Right now subView's offset is (30, 50) within parentView.
subView.frame = subView.superview.bounds;  // Better.
// Now subView is in the same position/size as its parent.
like image 82
Tyler Avatar answered Oct 05 '22 15:10

Tyler


Just set the autoresizing mask and the navigation controller will do the rest:

myView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
like image 42
Costique Avatar answered Oct 05 '22 14:10

Costique