Is it possible to initialize a UINavigationController subclass from a NIB? - cocoa-touch

I have a UITabBarController based application. The tabs will be created from database entries, so I don't know them in advance. I'd like to programmatically initialize a UINavigationController subclass (I have a few different kinds) for each tab.
Ideally, I would really like to draw the whole UINavigationController subclass + it's subview using Interface Builder, just like you can do when you add define the view for each tab in IB (that's when you know what the tabs will be in advance). I've tried setting the "Class identity" to my UINavigationController subclass name, then add a UINavigationController inside it, but obviously it didn't inject the instance at the "File's owner" level...
Thanks

I've ended up not subclassing UINavigationController, it appears it isn't what's recommended. I quickly realized that there wasn't a whole lot of benefit from designing the UINavigationController's from within IB. Instead, I subclassed UIViewController, wrote the few lines of init for theUINavigationBar (custom buttons, custom middle image) in my viewDidLoad. It's just better to simply wrap the subclass with [[UINavigationController alloc] initWithRootController: subclass]; when I programmatically fill my tabs. Subclassing UINavigationControllerdirectly prevented me from properly using the navigationItem property of my inject view.

Related

ios UIview in views

I have a uiview that has all my buttons, that has its controller. How can I include the button view in all my uiviews using the interface builder? The buttons must work when click. The purpose is to increase maintainability.
You can create a custom UIView in interface builder like this:
Loading custom UIView from nib, all subviews contained in nib are nil?
Then add your custom view to other views in IB by adding a normal UIView and changing the class to your subclass.
Try this. I'm not sure that adding UIView in Interface Builder will work, but adding subview programmatically always works.

Combined UITableView with other elements - how to create and use the view?

Ive a project close to doing everything I need it to do. Its got a Main page which has four buttons that allow you to choose an option. Then a tableview page is launched from those options and displays a parsed XML feed from a website. You can then select one of the options in the table to see a detail view of the item, enquire about it, etc.
My problem is I need to add more elements to the TableViewController page, other than the tableview itself. I want a customized back button (not the navigation controller standard) plus some labels, images, etc.
In the TableViewController xib, the tableview itself fills the page. I cant resize it to add more elements above it. I can add a 'view' window seemingly above the tableview and put things in it. But it seems to add the view to the tableview. This means that when I scroll the table, the other elements like new back button, scroll away as part of the table.
So I'm led to wonder whether I need this page not to be a tableviewcontroller, but a viewcontroller, with a tableview inside it, as well as my other view with buttons, etc. Is that the right way to go? But if thats the case, then how do I instantiate the tableviewcontroller within code? Because my page will not be of that type anymore - it will be just a viewcontroller. But in code Im making a tableviewcontroller .. slightly scared by that route tbh.
Any illumination on this would be much appreciated, as various searches have left me none the wiser. Thanks.
To customize it, this is the way to go:
Change your class to be a view controller instead, which implements the TableViewDelegate and TableViewData Source protocols.
In the view didLoad of you controller, create the table view, set its delegate, data source, and any other properties you wish and add it as a subview to your view.
tableView = [[[UITableView alloc] init] autorelease];
tableView.delegate = self;
tableView.dataSource = self;
// .. Other customization
[self.view addSubview:tableView];
I suggest doing this programatically rather than IB.
Instead of a UITableViewController, you want a UIViewController that has an IBOutlet UITableView. Drag and drop a UITableView component from Storyboard and hook it up, and position it as needed on the screen. This UIViewController should implement the UITableViewDelegate and UITableViewDataSource methods.
Edit: Remember that a UITableViewController is just a subclass of UIViewController so you don't really have to get rid of all your code. :) You only need to make minor tweaks to your header and main file, and change the Storyboard to be a UIViewController instead of UITableViewController as I mentioned above.

Possible to present UIView without UIViewController in UIPopoverController?

Is it possible to quickly present a UIView in a UIPopoverController without having a UIViewController managing the UIView?
Currently I have a "DelegateViewController" that gets my view passed. Then I use that controller for presentation. But I'm wondering if there is an easier way?
If you have a UIView, then you can easily create a plain UIViewController as a container.
UIViewController* controller = [[[UIViewController alloc] init] autorelease];
controller.view = myView;
Is it possible to quickly present a UIView in a UIPopoverController
without having a UIViewController managing the UIView?
No. UIPopoverController manages a view controller, not a view. When you create a popover controller, you have to provide the view controller that will manage the content. That doesn't mean that you have to create a special view controller subclass in every place where you use a popover -- as bendytree points out, you can use a plain old UIViewController if you want. But you can't just pass UIPopoverController a view -- it has no way to accept it, and wouldn't know what to do with it if did.
It usually makes sense to have a UIViewController for a view since the controller handles all the interaction and setting up of the view. Although you can in some situations put "naked" views on screen the UIPopoverController is designed to work with a UIViewController and the ViewController paradigm is very well established and encouraged in the iOS world, so even if you think you don't seem to need a view controller it should not be harmful to have one and you might always want to extend the current functionality, right?
Please Note: If you are on iOS 5.0 creating views in Popovers is very simple and a matter of dragging-and-dropping the view controllers and hooking them up on the storyboard. Example: How to create Popovers with Xcode Storyboards

IOS custom button

I need a custom button like Instragram has in profile tab (the buttons that shows the number of photos and followers) but i don't know how to start to implement it.
Do i need to subclass UIButton or is there other way easier?
I think, the easiest approach would be to create a UIButtom with the typeUIButtonTypeCustom and add a subview to it with imageviews and labels as subviews to create the UI. Composition over inheritance.
Subclassing UIButton seems to me to be the obvious solution. I agree that subclassing UIViewController makes no sense. You don't use UIViewController objects to manipulate individual subviews within a view hierarchy controlled by another UIViewController object.
There are plenty of ways to do this, personally I would subclass UIViewController. Then you can edit its .xib in interface builder to make it look however you want and set different values programmatically. Then to detect a tap on the button you can just use the touchesBegan and touchesEnded (I'm pretty sure those aren't complete method names, check in the docs for more info on them) methods. If you want you could also set up a UITapGestureRecognizer for the view instead.

Accessing Views created in Interface Builder

I've created a ChildViewController class, and then a nib that uses that class.
Then I created a BaseView, that includes some buttons, and some text that I'll be changing programmatically.
Then I created two more views (Boy and Girl), that I want to be able to lay behind the baseview so that the background color is different along with some graphics in an ImageView. I've named the views that I created in IB 'Boy' and 'Girl'...
But when I go back to my code where I'm calling ChildViewController, I'm not sure how to access the views I created so I can call insertSubView. Do I need to instantiate them in code? (in ViewDidLoad perhaps?) Does the nib create the instances when it loads?
I'm confused about how to handle multiple views for a single ViewController
edit =================
#Pablo Santa Cruz
Your answer assumes that i have two nibs and two view controllers (one for each view). I want to know if I can use one nib and one controller, and load in UIViews. It seems silly to create another nib and controller, when all want to do is change the background color and some graphics. Can't I programatically load in UIViews into a UIViewController?
Add IBOutlets in your App Controller class in Xcode then link them in IB (ctrl-click or right-click) from the connections tab in the Inspector to the object.
Then you will be able to send method calls to the objects.
The code in Xcode should look like this:
#interface AppController : NSObject
{
IBOutlet Girl girlIvarName1;
IBOutlet Boy boyIvarName2;
}
#end
You can access a UIView programatically by assigning a value to its tag property, which can be set in IB on the first tab of the inspector (Command 1)
The tag value defaults to zero, so if you want to access it specifically, make it non zero and unique. e.g. 100, which I will use in the example code below
Once the tag is set you can access the view using the following code in your UIViewController that was initWithNibName for the NIB containing the tagged view
UIView *aView = [self.view viewWithTag:100];
You can get instances for your IBuilder views with this piece of code:
boyViewController = [[BoyViewController alloc] initWithNibName:#"BoyViewController" bundle:nil];
girlViewController = [[GirlViewController alloc] initWithNibName:#"GirlViewController" bundle:nil];
Assuming your NIB file names are BoyViewController and GirlViewController. With those instances, you can do whatever you need to. I.E., adding them to a parent view (with addSubView message on the parent).