Adding 3 UIViewControllers in Single UIView-programmatically - ios

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 :-)

Related

How do I set the size of UITableView as a subview in a Container View with Auto-layout

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.

unwind segue changed my UITableView bounds

I have an unwind segue, but I don't know what unwind segue will do against the views' bounds. It indeed changed my UITableView bounds. Is there a way to re-size my views in/after unwind segue?
I find out that unwind segue will not call any view will/did appear nor load anything. I am confused why my UITableView bounds changed.
I created all view and controllers with storyboard. I got a sidebar and home view, and on sidebar, there is a setting button to load a setting view exactly the same size as the sidebar view.
When home view -> slide out sidebar, I manually calculated the table view bounds, in order to show all cells:
-(void) viewDidAppear {
[super viewDidAppear];
[self.ProjectTableView setFrame:CGRectMake(self.view.bounds.origin.x,
self.SideBarHeaderBGImageView.bounds.size.height + self.HomeButton.bounds.size.height + self.AlertButton.bounds.size.height,
self.view.bounds.size.width,
self.view.bounds.size.height - self.SideBarHeaderBGImageView.bounds.size.height - self.HomeButton.bounds.size.height - self.AlertButton.bounds.size.height)];
}
I use a unwind segue for the setting view to go back to side bar view:
- (IBAction)unwindToSideBar:(UIStoryboardSegue *)unwindSegue
{
// get the unwind view controllers
#ifdef DEBUG
NSLog(#"%# triggered unwind segue to SideBar", unwindSegue.sourceViewController);
#endif
if ([unwindSegue.sourceViewController isKindOfClass:[UserSettingViewController class]]) {
__block UIViewController *UserSettingVC = unwindSegue.sourceViewController;
//setup animateFrame
CGRect animateFrame = CGRectMake(-UserSettingVC.view.frame.size.width,
0,
UserSettingVC.view.frame.size.width,
UserSettingVC.view.frame.size.height);
[UIView animateWithDuration:0.3
delay:0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
UserSettingVC.view.frame = animateFrame;
UserSettingVC.view.alpha = 0.0f;
}
completion:^(BOOL finished) {
UserSettingVC.view.alpha = 0.0f;
[UserSettingVC willMoveToParentViewController:nil];
[UserSettingVC.view removeFromSuperview];
[UserSettingVC removeFromParentViewController];
UserSettingVC = nil;
//[self resizeSubViews];
//NSLog(#"self view height %f, bg %f, home %f, alert %f, proj y %f", self.view.bounds.size.height, self.SideBarHeaderBGImageView.bounds.size.height, self.HomeButton.bounds.size.height, self.AlertButton.bounds.size.height, self.SideBarHeaderBGImageView.bounds.size.height + self.HomeButton.bounds.size.height + self.AlertButton.bounds.size.height);
//NSLog(#"proj height %f", self.view.bounds.size.height - self.SideBarHeaderBGImageView.bounds.size.height - self.HomeButton.bounds.size.height - self.AlertButton.bounds.size.height);
}];
}
}
I tried to set the ProjectTableView frame again in the completion block, though it print correct values, but the real size is not correct.
I tried to print the UITable View bounds, seems normal, but my bottom cells cannot display. If I pull the window up, you can see them, but when release my fingers, it will go beneath the screen.
I suspect the unwind segue reset my UITable View size, but I don't know where to re-calcualate them again. The unwind segue will not invoke ViewDidAppear.
I figured it out, it is about auto layout. Disable or add enough layout will work.

How to access properties from view after it loaded

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

SplitViewController's master side sometimes is not rendered correctly when changing orientation in IOS 6.1

I have a tab bar controller that has some tabitems. Some of the tabitems are splitviewcontrollers. Sometimes, when I change orientation, the left side of the splitview controller does not render correctly, I have a black square in the bottom. By changing the orienation again, the problem is solved.
There is nothing special in my code. In the viewdidload I have:
[self.navigationController setNavigationBarHidden:YES];
self.splitViewController.delegate = self;
And one splitviewcontroller delegate method is handled trivially:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
I have nothing more, just some tableview on it with some cells on the detail side.
I've seen such issue and the only workaround I came up with was to reset the size of the left side view controller's view and also it's navigation controller's view:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if (self.splitViewController) {
viewHeight = ...
navViewHeight = ...
CGRect viewFrame = CGRectMake(0, 0, 320, viewHeight);
self.view.frame = viewFrame;
CGRect navControllerViewFrame = CGRectMake(0, 0, 320, navViewHeight);
self.navigationController.view.frame = navControllerViewFrame;
}
}
Where viewHeight and navViewHeight you can calculate from screen height depending on current orientation (which has already been set when didRotateFromInterfaceOrientation: is called). I guess these values should be equal for you as you hide the navigation bar.

How to resize a modalViewController with UIModalPresentationPageSheet

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;

Resources