In a navigation based application, when I want to create and use other uiviews and uitableviews I need to create their controller and views. in an example I saw that I can simply create a new controller with .xib file, design it, and just call that xib file from my navigationcontroller.
In another example, some stuff was going on also in the mainwindow.xib and some new controllers and navigation items were added from the mainwindow.xib.
What is the difference between these methods? when and why I should need to open and edit the mainwindow.xib file to add a controller?
The mainwindow.xib is your UIWindow component which you can see as a representation of your iphone screen, it will always be there no matter what. In your examples when you are showing your view controller dirrctly that is because the controller is already a subview of your UIWindow which is the mainwindow.xib in the Interface Builder.
There really is no difference between the 2 methods, in the first one you are adding your controller as a subview progrmatically using:
[window addsubview:mynavcontroller]
And in the second one youbare doing it thru interface builder, you may use whichever method you feel more comfortable with.
You do not really need a controller to show a view, however they can be handy if you want to do any extra stuff such as rotating your view or loading certain data when the view is loading. That being said you could add your view as a subview of your window and it would still work.
Related
I have implemented Facebook type left Slide Bar layout in my first view of iphone app. Now, I want to implement this throughout all view controllers (screens) in application, means irrespective of the view the left slide bar should appear on clicking the menu button at the top in all views.
My app contains 25-30 viewcontrollers and my slide bar layout should appear in all views..
Can anyone suggest, how can I include above FB Layout in all views
Thanks in advance
Ramu
Simple, The one view controller in which you have implemented the FB layout and is working. Make it the base class on top of UIViewController. And as for the rest of all the ViewControllers, inherit them from the MasterClass that you just created. Doing this will make the swipe gesture that brings forth the slide bar available to all of your 30 view controllers.
EDIT
Lets see, we have UIViewController, now first of all you create a UIViewController's subclass: say FBViewController ..In this FBViewController you implement the FBLayout such that the swipe and all is working ..on it ..test your app first using only this FBViewController as rootViewController and check all the functionalities.Once everything is working fine, grow on it. What I mean is this.
Say you are creating a Tabbed application, where all the three tabs are supposed to have the same FBLayout style. Then do these steps.
Create FBViewController, it inherits from UIViewController (using UIViewController subclass template, also check the generate XIB button) also have an XIB for it FBViewController.XIB (fully implement FBLayout in it. This will be your base class)
Then Create three more ViewController classes (FirstViewController, SecondViewController, ThirdViewController) again from the UIViewController subclass template, but for these three dont check the generate XIB button. these three will use the XIB of the base class FBViewController (If you are wondering how, then go to step 3 :))
Go to header file of FirstViewController class you created, there you can see #interface FirstViewController: UIViewController replace it with #interface FirstViewController: FBViewController, but before it import FBViewController.h to the header file. Repeat the same for the Other two classes- SecondViewController, ThirdViewController. Since these three will inherit from FBViewController. In their viewDidLoad [super viewDidLoad] will load FBViewController and generate the view. after [super viewDidLoad]; line you can implement ur own methods.
In the three classes just change the initWithNibName method to change the tab bar name and title.
In appDelegate go to didFinishLaunching method and put these three view controller in a tabBarController, set the tabBarController as rootViewController.
And we are done. If your FBViewController is working fine. You will see that all the three classes behave the same way. Thanx to the power of Inheritance.
Cheers, play a bit, have fun.
I had the same problem. I was using a facebook-style menu, and needed it in all view controllers.
You can use a Container Controller. A Container Controller can have the base layout, which I defined in a nib, containing a navigation bar and a bar button item to toggle the menu, and then add child view controllers and remove them as you need them. That way, you can throw whatever view controller you need to the container controller and it will display it.
You can also add gesture control to slide open/close the menu easily.
You will have to make the Container controller your self, it is not standard. I think it is better solution than inheritance, since if you use inheritance you can't make a for example UITableViewController, all your controllers will be of the type of yuor master class. Of course, you can fix this anyway with delegates.
It may sound a bit tricky, but see this tutorial which I used: http://www.cocoanetics.com/2012/04/containing-viewcontrollers/
It wasn't accutally that hard.
EDIT: You can just use a UINavigationController as well. Just set the base view controller to the view controller you want to display, and you can prevent it adding the back button etc to the nav bar by overriding the default methods. Make a UINavigationController as rootNavigationController. Might be simpler.
I'd highly recommend using an open source solution that handles all the edge cases for you - it's both the easiest, most robust and most maintainable (since the community will keep it up to date fro you). ViewDeck seems to be the most popular solution though I have also had success with PPRevealSideViewController. They both provide a very robust implementation that would take a long time to do yourself (e.g. you can optionally enable swipe on the navigation bar or even content area to open the menu). Furthermore they separate the sliding logic and the revealed menu (which can be any view controller you like, but most likely a table view controller) out of your other view controllers. That way any viewcontroller can have a side menu without duplicating any code - separation of concern is great :)
You can make a SharedInstance for SideView class. I am doing same thing for iAD to show throught-out the application.
Please see the the link of iAdSuite ,In which the BannerViewController is SharedInstance so they are easily used for all View Controller
http://developer.apple.com/library/ios/#samplecode/iAdSuite/Listings/TabbedBanner_TabbedBanner_BannerViewController_m.html
I have an WizardSequenceViewController with an IBOutlet WizardView *_wizardView. In many WizardSequenceViewController.xib file I have the view outlet connected to the File's Owner - WizardSequenceViewController. I have a subview of that view defined with the class attribute set to WizardView. I have connected that WizardView to the outlet in the File's Owner. Finally, in my WizardView.xib I have a UILabel that I have placed in the file to test if the view is being rendered. When I select the WizardSequenceViewController from my tab bar, I see the superview view but not the subview _wizardView. When I set a breakpoint in my -(id)initWithCoder method in my WizardView.m file I see it stop there, so I know that it is calling that initializer (and thus it should be using the xib to load that file). I have tried many iterations and variations to get this thing to work but I can't and I am going crazy. Does anybody have any ideas?
From Apple doc "View Controller Basics, About Custom View Controllers":
The one-to-one correspondence between a view controller and the views in its view hierarchy is the key design consideration. You should not use multiple custom view controllers to manage different portions of the same view hierarchy. Similarly, you should not use a single custom view controller object to manage multiple screens worth of content.
Note: If you want to divide a view hierarchy into multiple subareas and manage each one separately, use generic controller objects (custom objects descending from NSObject) instead of view controller objects to manage each subarea. Then use a single view controller object to manage the generic controller objects.
Maybe you can't do a view-and-subview outlet setup in a view controller. And I'm not sure assigning the subview outlet to a separate NSObject subclass would work either, because how would you present it? Could you write your subview programmatically, using initWithFrame and addSubview, instead of making it an outlet? Or, if you really want to set it up graphically, could you assign it to a separate view controller as owner? Then the top view controller will call presentModal on the sub view controller. Or, if all you need is a UILabel as a subview, just add the label to the main view?
Even I faced a similar issue. But got it resolved by following steps given in the following link. Hope it helps.
http://blog.yangmeyer.de/blog/2012/07/09/an-update-on-nested-nib-loading
I have created Storyboard with several views calling each other, now I need to create the code
I notice that XCode didn't created .h and .m controller files for each View from storyboard.
Should I create them manually?
Should I keep only one controller? (or few depending of separation of concerns on MVC)
Is there a pattern for developing this?
thanks
The usual approach is one view controller pr. screen full of content. You can imagine having one view controller for a tableview, with any sort of content, and then another view controller that presents that content in a new screen full of content if a row is pressed.
Normally when you have subviews inside of your view controllers, you wire them up in interfacebuilder. Then for instance if you want to populate a view that has a uiimageview and a uiactivityindicatorview inside it, you can control their behavior and how their populated from the view controllers code. You could also if you want something very generic and you feel that one view will probably take up a lot of code in your view controller, create a uiview subclass for it, and then set the class in interface builder.
Did this help? Please let me know if you need more clarification.
It's entirely up to you whether you have a ViewController for each view. If you have many views I would recommend it. Even if you have 2 or 3 views you probably still should. Things can get really confusing when each view has a different task but all have similar IBOutlets.
TLDR; Personally, I would say it was good practice to have a ViewController for each view if each view has a separate task.
In iOS5 using storyboard feature I want to create a custom container which will have 2 ViewControllers embedded in it. For Example, embed Table view controller as well as a view controller both in one ViewController.
That is, one view controller will have 2 relationship:
to table view controller
to view controller which in turn will have 4 UIImage view Or UIButton in it
Is creating this type of relationship possible using storyboard's drag drop feature only & not programmatically?
,You should only have one view controller to control the scene. However, this viewController might have two other view controllers that control particular subviews on your scene. To do this you create properties in your scene viewController, in your case one for your tableViewController and one for your view. I like to keep things together so I make both these viewControllers outlets and create them in interface builder. To create them in interface builder pull in an Object from the Object library and set its type to the relevant viewController. Hook it up to the appropriate outlet you just created in your scene's viewController - Note: this is important otherwise the viewController will be released if you are using ARC and crash your app. Then hook these viewControllers up to the view you want them to control and you are done.
Alternatively you can instantiate and hop up your viewControllers in your scenes viewController should you prefer to do this.
Hope this helps.
Edit: On reflection this is not a good idea and actually goes against the HIG you should maintain only one ViewController for each screen of content and instead try to create a suitable view class and have the single view controller deal with the interactions between the various views.
There is a way to do it that isn't too hacky. It is described at the following URL for UITabBarControllers, which you could use the first view controller in the list control the first subview, and the second one control the other. Or, you can probably adapt the code to work with UISplitViewController.
http://bartlettpublishing.com/site/bartpub/blog/3/entry/351
Basically, it works by replacing the tabbarcontroller at runtime after iOS has finished configuring it.
I have a mainwindow.xib file with a UITabBarController as the base view controller of the app. So inside the UITabBarController I've added about 10 sub UIViewController objects as tabs. Most of them are just a UITableViewController subclass or a UINavigationController containing a UITableViewController subclass.
In this design, each UIViewController is fully loaded on app startup, including calling the viewDidLoad method of each view controller. Is there any way to get around that? Since the view controllers are just UITableViewControllers with no other outlets, it seems excessive to create a NIB for each tab (which I assume would allow the viewDidLoad to only get called when the user first switches to the tab? Or am I wrong on that?)
Anyway, my question mainly, is: how is it conventionally done? If you have 10 different view controllers on one UITabBarController, do you put them all in mainwindow.xib? If so, should each have its own NIB, and if not, where do you put them, and how do you add them to the tab bar?
What you want to do is to define the UIViewController views in a different xib file for each view - the reason they all get instantiated is that when the xib loads, all objects held in the xib load - and that means all your views and view controllers since you have defined them there.
In MainWindow.xib where you have the tab bar defined, you can still set within each tab the view controller type that will be called and also the XIB file to use for that type (create a new project with the "TabBar application" template and the second default view will be like this).
Then as you press tabs the view controllers will be instantiated from the different XIB files you have defined.
Note that this means if you are using IB to add buttons to the navigation bar, you have to do that back in the TabBar xib and not in the xib you use to define the view. You can still link actions to the view controller definition within the tab.
The way Apple suggests doing it for pure NIB files is how you say: Each sub-view in its own NIB file.
Instead of doing this, I would create the UITabBarController programmatically. That way you can define all your simple views in code, and still load complex views from NIB files.
Personally, I prefer creating as many of my views programatically as possible. The compiled code has a smaller footprint than the NIB files and I feel like I have more control. I mostly use Interface Builder to mock up applications.