Can I create a UIContainerView programmatically? - ios

I'm trying to create a dynamic view flow that uses UIContainerViews to host UIViewControllers. The UIContainerViews (or UIViewControllers) need to be programmatically added to the UIView to allow multiple side by side.
I've been looking around, but can't find any constructors I can use to create my UIContainerView.
Is there a simple way to do this or is it against normal guidelines for creating reusable views?
To sum up, I want to achieve something like this:
var containerView = UIContainerView()
containerView.add(myViewController)

A UIContainerView is just a visual way to add a viewController as a child of another and setting its bounds.
You can do this programatically by adding the second viewController as a child of the first, taking the second's view and placing it somewhere on the first's view.
Something like this;
childVC = [[SomeViewController alloc] init];
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[childVC didMoveToParentViewController:self];

Related

How to add UITableView inside custom UIView?

I want to create common custom view with uitableview. I can do it using view controller and add subview as follows.
ViewController *vwCon=[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
vwCon.view.center=self.view.center;
[self.view addSubview:vwCon.view];
But after scrolling table view app become crash. So how can I add uitableview inside custom UIView?
You shouldn't add a view controller as a subview - in fact Im not sure whether you are allowed to at all. You need to present a view controller modally, or push it as part of a navigation controller. I doubt you really want that though- instead just use a UIView here rather than a view controller. Then you can add that as a subview to another view.
You also mention tableviews though. Have you looked at the storyboard? Its easiest to do all that in there - just drag a UITableview object from the objects list on the right hand side, into the main view controller.

Accessing and manipulating parent view controllers views from a container view IOS

I am making an app where I have a container view that is half the screen of my view controller. From the container view controller's class I am trying to access and manipulate a view that sits out side of the container view. (picture below)
I am trying to access and add items to the scroll view from the container view class like so:
parent = (GFProfileViewController*)[self parentViewController];
UIScrollView *scroll = (UIScrollView *)[parent.view viewWithTag:222];
parent.titleHolders.contentSize = CGSizeMake(320 * 4,60);
UILabel *testLabel = [[UILabel alloc] init];
[testLabel setFrame:CGRectMake(0, 0, 100, 40)];
[testLabel setText:#"My Test label"];
[parent.titleHolders addSubview:testLabel];
scroll.backgroundColor = [UIColor blueColor];
how ever does not work. I tried even accessing the view from the parents "view with tag" method.
neither works.
I know the code is fine because when I move it to the parent vc all works as expected. I need to be able to manipulate the view from the container though. Can anyone help?
As nhgrif says, don't do that.
You should treat another view controller's views as private.
Again, as nhgrif says, create a public method in the parent view controller that takes the information needed and does the displaying itself.
If the view controllers are just being initialized then the parent view controller's view hierarchy may not exist yet. In that case you'd want to set properties to hold the value(s) you want to display, and then display them in your viewWillAppear method.
With storyboards and iOS >= 6, you can set up the child view controller using an embed segue, and then in your prepareForSegue method you can set the parent view controller up as the child view controller's delegate. That's a clean way to have the child communicate back to the parent. (I have a sample app on github that demonstrates this technique if you need a more detailed explanation.)
As far as programming ethics, correctness, good practices and whatnot, I think others have that covered. What you want to do surely isn't the clean way to go, but I often find myself going for such shortcuts, but you really need to know what you're doing, and if it isn't coming back to bite you later. The good thing is that it takes one line of code to achieve and has very low overhead. The problem is that such approach is highly dependent on the view structure, so if you change it, it will no longer work.
With that being said. What you tried doesn't work because the 'parentViewController' property isn't set on any arbitrary view. It should only be defined on the main view of the view controller, the one you can access from 'viewController.view'.
I will assume from your comment that your view structure is something like:
UIView
UIView
UIScrollView
Container
So basically starting from Container you need to go up one level and then down to UIScrollView like this:
UIScrollView = [((UIView*)[self.superview.subviews objectAtIndex:0]).subviews objectAtIndex:0];
I am unsure if you can search by tag from the upper view, since the one you're searching for is somewhere nested inside, farther than one level down. Assuming you can actually do that, this should also work and be more fail proof.
UIView *upperView = self;
while([upperView superview]){
upperView = [upperView superview];
}
UIScrollView *scroll = [upperView viewWithTag:222];

UIScrollView and Storyboard

I am testing out something I would like to have in my app. I have a UiViewController in a storyboard that has a UIScrollView - I now want to add other viewControllers to this scrollView and swipe between them.
I would like to add a view that I made in the storyboard into this UIScrollView. Is it possible?
I tried something along the lines of:
MYViewController *viewOne = [self.storyboard instantiateViewControllerWithIdentifier:#"myView"];
[self.scrollView addSubview:viewOne.view];
I've set the the scrollView size to be bigger than the screen and when the main view loads, I can see there is a scroll view (the scroll bars show) but my viewController is not inside it.
Anyone have any ideas?
The code you posted is still not right, on a couple of levels.
First, you should not use alloc/init for view controllers. You either need to use initWithNibName:bundle: (to create a view controller from a nib file) or instantiateViewControllerWithIdentifier: to load a view controller from a storyboard.
Second, you should not add a view controller's view as a subview of another view controller unless you use the parent/child view controller support that was added in iOS 5 and greatly improved in iOS 6. If you do what you are doing then all sorts of things won't work correctly: Auto-rotation, low memory warnings, background notifications etc. The list of things that can go wrong is unbounded.
The easiest way to do this is to add a container view as a frame to hold your child view controller, and then control-drag from your container view onto the scene that you want to set up as a child. This causes IB to set up and "Embed" segue. Embed segues do all the housekeeping you need to host one view controller's content inside another, with no code needed.
You could create a container view inside your scroll view's content view, and then it would just work fine.
I found the problem:
I was not allocating and initialising my viewController. Ooops.
This is the correct code:
BaseViewController *viewOne = [[BaseViewController alloc]init];
viewOne = [self.storyboard instantiateViewControllerWithIdentifier:#"myView"];
[self.scrollView addSubview:viewOne.view];

How to add childview programmatically in iOS?

I have googled for many days but don't find out. I just know how to do by IB, but not by programmatic way. I think [addsubview:view] is just only add sibling view, not parent-childview. Thanks guy for reading.
It is easy:
//allocate a view (or take it from IB or from where you want)
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(10,10,100,100)];
//add the view on the actual view (or any other view)
[self.view addSubview:newView];
So this is a parent-child case and not a sibling view.
In fact by [newView superView] you get the parent view.
You might be getting confused by the difference between subviews and child view controllers, which are what's used when we have Container View Controllers that manage & display a number of child view controllers.
Take a look at the "Implementing a Container View Controller" section of Apple's UIViewController documentation, and you'll see how they describe how child view controllers work.
And, to answer your question specifically, here are the four methods that involve Child View Controllers (from the documentation):
Here are the essential methods you might need to call:
1) addChildViewController:
2) removeFromParentViewController
3) willMoveToParentViewController:
4) didMoveToParentViewController:
And, of course, if you're really talking about subviews, there are a bunch of other people excitedly providing all sorts of answers to your question along this front. Hopefully you'll have the correct answer for your problem really quick.
You can subclass a class to achieve this.
Example:
#interface MSCustomView:UIView
Here UIView is the parent class and MSCustomView is the child class
The [UIView addSubView:] function adds a view as a child view to the view you call it on i.e
[view1 addSubView:view2] will add view2 as a child to view1.
In the Apple docs:
http://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/addSubview:
addsubview does just that. If you'll keep adding subviews to the same View you will basically create more siblings to that subview
From the iOS Developer Library:
Views can embed other views and create sophisticated visual
hierarchies. This creates a parent-child relationship between the view
being embedded (known as the subview) and the parent view doing the
embedding (known as the superview).
https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html
AddSubview add a view into parent hierarchy . IOS provide insertSubview too for ad child view. This
http://developer.apple.com/library/ios/#Documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html
provide a better approach to understand about it.
You can add sub view by [parentview addSubView:childView] in the syntax both childView and parentview will be of UIView type.

Possible to have a UINavigationController for a UITableView that doesn't fill the entire super UIView

This is on iOS5 w/ a storyboard.
I'd like to have a UINavigationController on the UITableView below but when I try the "embed in" option, it adds it to the Red UIView, not on the table itself. For lots of reasons this is not optimal. Is what I want to do not possible: to have a table subview with its own nav controller?
Oh - while I am here - what is the deal with UINavigationControllers not being able to be resized in a storyboard? I can only set "form" "page" or "full" - when I set it to "freeform" I am not able to enter any values to resize it
For lots of reasons this is not optimal
Actually, for lots of reasons what you are trying to do makes no sense. A UINavigationController has embedded within it (in Storyboard terms) an instance of a UIViewController. In other words, the nav controller's root view controller must be a view controller. Since UITableView is a subclass of UIView, you can't embed it inside a UINavigationController. And besides, you would never want to. A UINavigationController manages a hiearchy of view controllers. What are you trying to achieve that you think you need to put a UITableView inside of a UINavigationController? What you are probably trying to achieve is to place the view controller that the table view sits on inside a UINavigationController, in which case the result you're seeing in IB is the correct result.
UINavigationController is a view controller, not a view, so you can't embed it inside a view.
You should be able to get what you want with a little code: you can't embed it inside Xcode, but you can set up the UINavigationController and the red view separately, then write a few lines like this:
navigationController.view.frame = CGRectMake(20, 20, 280, 300);
[redView addSubview:navigationController.view];

Resources