Storyboard:
Constraints:
Result:
I'm trying to understand autolayout and how I can use it inside a container.
I got a default ViewController that was made for me when I opened the Storyboard. I put a View Container inside there. And then I added a loose (not connected to anything) ViewController. I want the content inside the new ViewController to be put in the container.
So the added ViewController which will be put inside the Container consists of three labels where I am using autolayout.
Clicking on the black bar for the Container View Controller in the Storyboard I go to Identity Inspector and set the Custom Class to "ContainerViewController". Then I set the Storyboard ID to "ChildController" for the loose View Controller.
Then I override viewDidLoad in ContainerViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:#"ChildController"];
[self addChildViewController:child];
[self.view addSubview:child.view];
}
Why won't the constraints for the autolayout work when put in a container? I hoped they would, so I could take this further to a UIPageViewController.
EDIT:
So it seems to be the frame size. I need to do something like this before adding it as sub view:
child.view.frame = CGRectMake(0, 0, 265, 370);
Now I created an outlet for the Container in ViewController.h.
#property (weak, nonatomic) IBOutlet UIView *container;
But.. From ContainerViewController, how can I ask presenting view controller (ViewController) of this property when it's not set yet?
ViewController *parent = (ViewController*)self.presentingViewController;
UIView *container = parent.container;
NSLog(#"ParentView Container Width: %f, Height: %f", container.frame.size.width, container.frame.size.height);
It just gave me zero width and height, because the view hasn't loaded yet. Later on when it loads, I get the actual values..
NSLog(#"View Controller Container. Width: %f, Height: %f", self.container.frame.size.width, self.container.frame.size.height);
The question: How can I access properties of presentingViewController when they are ready/loaded?
when adding a child view controller you should set its view frame like this
UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:#"ChildController"];
[self addChildViewController:child];
[self.view addSubview:child.view];
//set the view frame
child.view.frame = self.view.bounds;
So the child view controller will resize its view frame and layout contraints will do their homework ;)
EDIT
put the code in -(void)viewDidLayoutSubviews like this:
-(void)viewDidLayoutSubviews{
[super viewDidLayoutSubviews];
UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:#"ChildController"];
[self addChildViewController:child];
[self.view addSubview:child.view];
//set the view frame
child.view.frame = self.view.bounds;
}
Just try to set frame in viewWillLayoutSubviews for view Controller
Related
I'm displaying a UIViewController as one of the pages in a UIPageViewController.
This viewController (VC1) has a size of (320, 568). What I then do is display another VC using this method:
- (void)displayContentController:(UIViewController *)content {
[self addChildViewController:content];
content.view.frame = self.view.frame;
[self.view addSubview:content.view];
[content didMoveToParentViewController:self];
}
Called this way:
NewViewController *newVC = [self.storyboard instantiateViewControllerWithIdentifier:#"NewViewController"];
[self displayContentController:newVC];
The reason I'm doing this instead of pushing it or presenting it modally, is because I need it to overlap the other UIViewController(VC1), blurring it while sliding with the UIPageViewController like VC1 normally would.
viewDidLoad in newVC is reporting a self.view.frame of (320, 568) at first, but then a little later it suddenly reports a self.view.frame of (320, 571) - rather than a height of 568.
I'm using autolayout.
Why is this and how can I resolve it?
In viewDidLoad() method frames don't give you actual size of controller views. To get correct sizes try to check it in viewdidlayoutsubviews() method of ViewController
I currently have a UIViewController which contains a menu bar and container UIView.
On main view load the container has an embed segue with a separate main content UIViewController.
When I click a button in the menu bar I have a custom segue set up to load a UITableViewController into the UIView container using the following code
-(void) perform {
BlockDetailViewController *src = (BlockDetailViewController *)[self sourceViewController];
UIViewController *dst = (UIViewController *)[self destinationViewController];
//Clear view of all subviews
for (UIView *view in src.viewContainer.subviews) {
[view removeFromSuperview];
}
//save destination
src.currentViewController = dst;
//set placeholderOutlet to destination
[src.viewContainer addSubview:dst.view];
}
This loads the UITableViewController into the UIView fine, however, it seems the UITableViewController size is set as the default window size which means the bottom cells of the UITableViewController are hidden from view. You can see them if you drag up but when you let go the bounce takes them out of the view.
How do I make sure the size of the UITableViewController is the same size as the UIView it is being placed into?
Thanks
You just have to create a a CGRect (frame) and set it to the views frame:
dst.view.frame = CGRectMake( CGRectGetMinX(self.view.frame),
CGRectGetMinY(self.view.frame),
CGRectGetWidth(self.view.frame),
CGRectGetHeight(self.view.frame);
the values should be float values. This is just an example.
When you define dst, you can use CGRect to set its position, width and height.
I want to add a view called anotherView on top of self.view. But I don't want anotherView to be a subview. Is this possible?
I want anotherView to be at the top of the page and push the contents of self.view down accordingly (without having to change the y or height values.
I have the following and it doesn't work:
UIView *anotherView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.view.frame.size.width, 80)];
anotherView.backgroundColor = [UIColor yellowColor];
[self.view insertSubview:anotherView aboveSubview:self.view];
The box is simply on top of the existing view.
Any visible view is subview of some other view or window.
But you can add anotherView to
self.view.superview
or even
self.view.window
or create new UIWindow object and add your subview to this window
Have you tried to present anotherView modally? That way you can make it to appear on top of everything being a completly new view controller. Ex:
[self presentModalViewController:anotherView animated:YES];
assuming of course anotherView is a subclass of UIViewController and has its own View property. Because if anotherView is just subclass of UIView then you can't present it without being a subview of the current View Controller.
EDIT:
Oh yes, you can just pass a nil to the completion block:
[self presentViewController:anotherView animated:YES completion:nil];
This is what i am doing
1. I am adding a UIView of width 960 on FirstViewController through xib so that it can accomodate 3 view controller
2. Then I am trying to add 3 viewcontrollers as subview on that view , by programmatically setting the frame
Problem:
While changing the x coordinate to 320 it is not showing the second view..
This is the code :-
Currently i am trying with 2 views
#pragma mark - SetupView View
-(void)setupView
{
//setting up Interval Home Screen on Container View
intervalHome=[[IntervalHomeViewController alloc]initWithNibName:#"IntervalHomeViewController" bundle:nil];
CGRect f=self.containerView.frame;
f.size.width=self.view.frame.size.width;
intervalHome.view.frame=f;
[self.containerView addSubview:intervalHome.view];
[intervalHome.btnAddCustomInterval addTarget:self action:#selector(addCustomIntervalScreen:)forControlEvents:UIControlEventTouchUpInside];
[intervalHome.btnAddInterval addTarget:self action:#selector(addIntervalScreen:)forControlEvents:UIControlEventTouchUpInside];
//setting up AddInterval screen on Container View
addInterval=[[AddIntervalViewController alloc]initWithNibName:#"AddIntervalViewController" bundle:nil];
[self.containerView addSubview:addInterval.view];
CGRect frame=f;
frame.origin.x+=self.view.frame.size.width;
addInterval.view.frame=frame;
addInterval.view.tag=99;
NSLog(#"Frameinterval=%#",self.addInterval.view);
}
#pragma mark - Switch to addInterval view
-(IBAction)addIntervalScreen:(id)sender
{
NSLog(#"Frame=%#",self.containerView);
CGRect frame=self.containerView.frame;
frame.origin.x+=self.view.frame.size.width;
self.containerView.frame = CGRectMake( frame.origin.x, frame.origin.y, frame.size.width,frame.size.height );
NSLog(#"Frame2=%#",self.containerView);
}
you should use UIPageViewController which is made exactly for that scenario :-)
I have a modal view controller that I show with UIModalPresentationPageSheet. The problem is that its default size is too large for my content: so I want to resize its frame to adjust accordingly with my content.
Does anyone know of a way/trick to do this?
Thanks.
Actually you can resize the view controller that gets presented with UIModalPresentationPageSheet. To do it you need to create a custom view controller class and add the following to the class:
<!--The header file-->
#interface MyViewController: ViewController{
//Used to store the bounds of the viewController
CGRect realBounds;
}
<!--In the .m file-->
//viewDidLoad gets called before viewWillAppear, so we make our changes here
-(void)viewDidLoad{
//Here you can modify the new frame as you like. Multiply the
//values or add/subtract to change the size of the viewController.
CGRect newFrame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height);
[self.view setFrame:newFrame];
//Now the bounds have changed so we save them to be used later on
_realBounds = self.view.bounds;
[super viewDidLoad];
}
//viewWillAppear gets called after viewDidLoad so we use the changes
//implemented above here
-(void)viewWillAppear:(BOOL)animated{
//UIModalpresentationPageSheet is the superview and we change
//its bounds here to match the UIViewController view's bounds.
[super viewWillAppear:animated];
self.view.superview.bounds = realBounds;
}
And then you display this view controller with a UIModalPresentationPageSheet. And that's it. This does work for iOS 5.1.1 and iOS 6 as of the date of this post.
You can't resize a UIModalPresentationPageSheet because its size is not modifable.
This works for resizing a view controller that's presented as UIModalPresentationFormSheet. I would give this a try, I'm not sure if it'll work or not:
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:navController animated:YES];
//these two lines are if you want to make your view smaller than the standard modal view controller size
navController.view.superview.frame = CGRectMake(0, 0, 200, 200);
navController.view.superview.center = self.view.center;