hooking up two different storyboard viewcontrollers to a same class - iphone

I am new to Iphone development. My app consists of two storyboards one for the Ipad and other for the Iphone.Now, my problem is I have an IBOutletCollection of UILabels hooked up as a property with one of the viewcontrollers in my Iphone storyboard..How am I suppose to hook up the same Ipad storyboard viewcontroller with the IBOutletCollection of UILabels for the same class..?
Thanks in advance..

Just like you'd hook up any other IBOutlet, IBOutletCollection or IBAction.
Your UIViewController sub-class contains the bits which let you hook something in a storyboard to it.
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *tabButtons;
In your storyboard, you can assign the view controller to be of a certain class, in this case it will be a your UIViewController sub-class. Now all you have to do it drag the storyboard artifacts to your existing IBOutlet stubs. It works.
You can do this for multiple storyboards using the same class (or multiple view controller in the same storyboard too). When you load it into memory, you specify the item in the storyboard, then the storyboard creates and instance of the view controller and hooks up all the references, so all is good.
MyViewController *myVC = [storyboard instantiateViewControllerWithIdentifier:#"foo"];

Related

XIB - ViewController communication

I load a view from a XIB into a ViewController: the XIB is an IBOutlet of the viewcontroller.
The view contains two UITextFields and a UIButton. The button must invoke a function in the viewcontroller.
The textfields should respond to the typical textfields delegates, and in any case, communicate with the "parent" ViewController in a bidirectional way.
What's the best way to do this?
While it's quite clear for me how to deal with the button (I can use a delegate in the UIView class and conform the viewcontroller to the delegate), it's unclear for me how to deal with the textfield delegates.

storyboard error with uitableview

I am getting this error while trying to create my app structure with story boards
static table views are only valid when embedded in
UITableViewController instance
I have created this sotry board that has a Navigation controller and then several views that branch off the main view that has a tableview in it.
one of the views that I have made off the main view has this error.. I have several other views with the same set up but none of them are having this issue yet.. im woudnering if I resolve this issue then they will say the same thing after as it was the first view I set up..
any help would be appreciated.
I was able to put a static UITableView inside my UIViewController by simply dragging the UITableView onto my ViewController in IB, and hooking both the delegate and data source to my view controller and then implement (even if i'm using a static table, just to make Xcode shut up)
#interface MyController : UIViewController <UITableViewDelegate, UITableViewDataSource>
#property (strong) IBOutlet UITableView *myTableView;
#end
If you wanted to put multiple UITableViews inside your ViewController with IB, you could create separate files/classes for each UITableView, and then hook them up as delegates. I see a bunch of answers that insist you must subclass from UITableViewController and it's just not the case.
#interface MyTableViewDelegate : NSObject <UITableViewDataSource, UITableViewDelegate, UIScrollViewDelegate>
When you say view, I'm assuming you mean UIViewControllers. For static tables, your view controller needs to be (must be) a UITableViewController, which is a subclass of UIViewController that handles tables, specifically static tables in your case.

iOS how to add not from source coding multiply viewsControllers to one ViewController

I'm having some problems because I don't know how it can be done. Someone help me please.
Problem:
I have a project with a UIViewController class with created all time when I create a new project in Xcode. In this viewController, I have a xib file for designing in Xcode.
What I need is to create some views and design them in Interface Builder like this:
But I need these views to be UIViewControllers, not UIViews.
The project should look like:
So I don't know how I can do this in IB but I can do it from source code in ViewController.m
tab  = [[TabBarController alloc] initWithNibName:#"mytestview" bundle:nil];
   [tab.view setFrame:CGRectMake(100, 100, 400, 600)];
   [self.view addSubview:tab.view];
But it's not my views it's a different object, and if I want to change position or size I must do it from code. How I can do same things in Interface Builder?
Let's consider following example based on Master-Detailed Application for iPhone only.
So, add new view controller in newly created project in Xcode:
I called it NewInsideViewController. Create it without xib:
Open DetailViewController.xib. Drag View Controller and View(*) objects from library to Objects area like this (I changed view's color to LightGray):
Choose this View Controller and change its Class from UIViewController to NewInsideController at the Identity Inspector:
Assign our View(*) to NewInsideController as a view:
Now all main actions in IB finished. We need to create instance of NewInsideController in our DetailViewController. You can do it by hand, but Xcode has a nice feature - drag-n-drop ;)
I called this property as myNewInsideController and DetailViewController.h looks like this:
#import <UIKit/UIKit.h>
#import "NewInsideController.h"
#interface DetailViewController : UIViewController
#property (strong, nonatomic) id detailItem;
#property (strong, nonatomic) IBOutlet NewInsideController *myNewInsideController;
#property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
#end
Well, now our NewInsideController ready to work and manage its view. Let's add button and action to that view in order to verify this:
Write some code in IBAction in NewInsideController.
- (IBAction)insideButtonClick:(id)sender {
float rPart = arc4random()%100/100.0f;
float gPart = arc4random()%100/100.0f;
self.view.backgroundColor = [UIColor colorWithRed:rPart green:gPart blue:0.5f alpha:1.0f];
}
Run program.
If I understand the question clearly:
You have a parent view and controller, coming from a XIB.
You have placed subviews into the parent view.
You're wanting each subview placed into the parent view to have it's own (custom) controller, but you don't know how to add view controller's to your hierarchy (XCode will not let you drag view controllers into a view's canvas).
So, to answer the question succinctly: Let's assume you have a handful of custom UIViewController's in your project (each view controller consisting of a .h and a .m). Remember that you if you are laying these out in the context of the parent, they shouldn't have their own XIBs (you cannot nest XIBs in IB). What is important to note here is that you should only "layout" the interface in one location. If you want to have a XIB for each subview, this is not the correct approach. What you can (not should) do, however, is have several custom viewControllers, each connected to it's own view sitting within your parentView, and you can have the outlets of your sub view controller's set to objects in this parentView. Phew, kinda messy. The other thing you'd need to be aware of is that your parent view controller would need a reference to each of it's sub view controllers in order for you to be able to access those sub-controllers and their outlets programmatically, so for each sub view controller you add, you would also need to add an IBOutlet in your parent view controller pointing to each subviewController:
ParentViewController.h
#property (nonatomic, weak) IBOutlet CustomUIViewController *firstCustomController;
And then for example to set the background color on the view of your first custom subview/controller:
ParentViewController.m
[[[self firstCustomController] view] setBackgroundColor:[UIColor whiteColor]];
Open up your parent view controller in IB. If you look in your drawer of available objects, you'll find a generic UIViewController object. Drag this into your parent view controller (NOT onto it's views canvas, rather into the parent UIViewController object itself as seen in the left-column of IB builder). Select the generic view controller you've added and set it's class to your desired UIViewController subclass. Now, when your XIB loads, it will instantiate an instance of your custom view controller along with whatever you've added to it's canvas.
Finally, drag a generic UIView onto your canvas, placing it inside your existing controller's view (your screenshot already shows this as done). Right-click your custom view controller, and connect it's 'view' outlet to the view you added.
Now when you run, your custom view controller has a view that is on the screen that is the view of your custom controller subclass, and you didn't do any of it in code.
So now that you've done it, consider whether or not it is the best choice: Nested view controllers are messy to build (as you've seen) and aren't necessarily a good design decision: http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/
Although iOS5 does support nested view controllers, personally I'd avoid using them. I value a best practice dictating one screen = one view controller.
You never, EVER, want to take views which are already under the control of a certain view controller, and make them subviews of another view controller's view.
View Controllers are the C part in the MVC design pattern - They are in charge of controlling a view (and its subviews). You can't take a view which is being managed by a controller, and stick it as a subview of a different controller's view - If you do that, it becomes ambigous who is responsible to manage this view.
Even though this "sticking" might be possible technically, it creates code which is hard to understand, hard to maintain, and most importantly - will cause bugs due to the unclarity of who is responsible to manage the view, and due to the fact that Apple's View/Controller framework doesn't support this.
For example: If the device is low on memory, Apple makes sure to unload views which are not currently displayed. Apple relies on the view controllers hierarchy to know when it can unload views. If you stick the view controller's view in another view controller's view, it's very likely that the view will never be unloaded even if it isn't visible.
Instead of breaking the view controller hierarchy, do one of the following:
Just add subviews to your view normally, either in interface builder, or in -viewDidLoad: to add them programatically, or (rarer) override -loadView.
Use view controller containment, either with Apple's ready-made ones (UINavigationController,UISplitViewController etc.) or with your own container view controllers (iOS>5).
Display view controllers modally.
The bad idea of breaking a view controller hierarchy is indeed very common and often seen in 3rd parties, probably because it's so easy and seemingly straightforward. Unfortunately this causes the aforementioned bugs :-(
I really recommend to everyone participating in this thread and comments to read Apple's View Controller Programming Guide, and watch WWDC 2011 "View Controller Containment" video.

Custom UIView from outlet

I know this has been discussed a number of times but I still have some problems getting around the problem, so any help would be appreciated. I have a class MyView which subclasses UIView. So far so good, in this custom class I basically configure the layout, UI, etc.
Now, I have a separate UIViewController and what I want to do is create an outlet for that custom view. In the view controller's Nib I set the view's class to that of my custom view and connect it to the outlet, but I can't see anything apart from a blank view.
How and where do I load the view from nib? Do I simply say self.theOutletForMyCustomView = load from nib or is it something else? Thanks for your help
First of all, you have to set the name of your CustomView inside your UIViewController nib file like that
Then, you have to retain your property like that inside your UIViewController interface :
#property (nonatomic, retain) IBOutlet CustomView *myCustomView;
or an ivar should work, but assign an IBOutlet property doesn't work.
And if you customize your CustomView inside your CustomView class implementation. Beware of doing your initialization in awakeFromNib or initWithCoder: instead of initWithFrame:

Understanding Outlets in Interface Builder

I'm doing an exercise to try to truly understand Interface Builder and Outlets.
Using Xcode 4.0 I've chosen the template for Window Based Application. I then:
Go into Interface Builder and add a UINavigation Controller.
Set the Window Outlet RootView Controller to the Navigation Controller.
Go to AppDelegate.h to create a UINavigation Controller called
navController and give it an IBOutlet.
Go to AppDelegate.m in the didFinishLaunchingWithOptions to set
self.window.rootViewController to self.navController.
Create a new UIViewController called FirstViewController complete
with .xib file.
My question is, how do I set the root view controller in the mainWindow.xib outlet as the FirstViewController? But more importantly could someone explain to me the reasoning behind how you do this?
In other words, I would like FirstViewController to be the first view controller the user sees in my app. And I would like to understand exactly the mechanics behind making this happen.
Thanks for all the help!
interface bilder's outlets is just a links between graphical part of your program, and your code. In other words, they explane what code controlls this graphical object. You see, objective-c is very MVC-oriented. .xib file is V(view), outlet and your code, that linked with .xib by this outlet - is C(controller). M(model) should be somewhere alse in your code.
Now, about root view controller. I prefer implement it like below:
import your firstViewController to AppDeledate.h and implement navigationController:
#import "firstViewController .h"
#class firstViewController
...
UINavigationController *navigationController;
...
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
now, in interfacebuilder (mainWindow.xib), add navigationController object and link it with implemented property. Then, add a ViewController object in that navigationController, select this ViewController Object and set in inspectors it's class to firstViewController and xib file to firstViewController. Finaly, in AppDelegate.m in the didFinishLaunchingWithOptions to set self.window.rootViewController to self.navigationController. That's it.