Finding File Owner in Xcode 4.2 - xcode

Please glance at the image below and help me find a File Owner for the class.
Generally i would connect my UILabel to it, but, alas, i can't find it.
Question: What should i connect my Label to?
Storyboard:
Meanwhile class is set up as

As storyboards don't have an owner, you can use the View Controller instead.
Ctrl click (or right click) the label, drag the blue line to connect up with the orange View Controller.

Right click the Label and connect to the View controller scene

You have put your finger on a key difference between storyboards and nibs: when a nib is loaded, an owner instance is specified, but a storyboard is not loaded with an owner, so there is no file's owner in a storyboard. Your ViewController instance is created by the storyboard and is proxied in the scene (listed as View Controller), so you can draw a connection between that and an interface item. But if you want to form a connection with an already-existing instance not represented in the storyboard, you'll have to identify that instance in some other way (perhaps by a tag) and find it and runtime and form the connection in code after the storyboard loads.
For example, in this code, I manually load a storyboard (to use its initial scene in a popover) and then form connections from some bar button items within it:
UINavigationController* nav =
(UINavigationController*)[[UIStoryboard storyboardWithName:#"Storyboard"
bundle:nil]
instantiateInitialViewController];
// there is no file's owner...
// so we can't just draw the connection from button items to ourself,
// because we are not proxied in the storyboard
// so, locate the button items in some other way and do it in code
UIViewController* root = [nav.viewControllers objectAtIndex: 0];
[root.navigationItem.leftBarButtonItem setTarget:self];
[root.navigationItem.leftBarButtonItem setAction:#selector(save:)];
[root.navigationItem.rightBarButtonItem setTarget:self];
[root.navigationItem.rightBarButtonItem setAction:#selector(cancel:)];
In some cases, there's a trick you can use to inject an arbitrary existing instance into a scene so that a connection to it will work: make that instance the first responder. There is a first responder proxy in every scene, so this can give you something to connect to by drawing within the storyboard. So, this code could work instead of the above:
[self becomeFirstResponder];
UINavigationController* nav =
(UINavigationController*)[[UIStoryboard storyboardWithName:#"Storyboard"
bundle:nil]
instantiateInitialViewController];
(And the button action connections have been drawn in the scene from each button to the first responder proxy object.)

Menu: Navigate - Reveal in Project Navigator
In the Project Navigator, Click on the "Main Storyboard"
Menu: View - Show Assistant Editor
You should have the Storyboard on the left with your label, and the view controler.h text on the right.
Click on your label, hold down the control button, and drag a blue line to the View Controler.h source code on the right. Type in a reference name (for example myLabel), and click connect.
Automagically you will see something like this generated:
#property (weak,nonatomic) IBOutlet UILabel *myLabel;
Inside the View Controler.m, you will see something like this generated:
#synthesize *myLabel;
Inside your IBAction events, you can set the label:
myLabel.text =

Related

Dragging UIButton on UIView in Interface Builder not working

I created a new Xib file, called MainViewController.xib. I dragged a View onto the builder, then plopped a UIButton on top of the view. Nothing happened, my button is on the view but not considered a subview. There is no hierarchy tree on the left column under the View icon that tells me my button is a subview.
Why is that? Every time I control+drag from the button to the view icon, the information for constraints pops up, instead of anything regarding an IBOutlet connection.
I'm using Xcode 7.1.2
I can control+drag to from my button to my .h file and create a property, but other than that, it's not recognized as a subview. Any help at all will be appreciated, I'm losing my mind.

xCode can't Control-drag into .m file

I'm trying to change the results field in the sample app SimpleURLConnections in the AppleDeveloper Library from an Image View Object in the GetController.m to a Text View so that it will display responses that aren't images. (I know some code that checks the response type also needs to change.)
When I drag a Text View object (or ANY object) from the Utilities pane to the MainWindow.xib in the editor pane, it appears to be created ok but when I try to Control drag from the Text View into the #property area of GetController.m, I don't get any "Insert Outlet.." popup or new entry in the GetController.m file? (By experimentation, I can get it to populate an IBOutlet in the AppDelegate.m file.
What am I doing wrong?
Thanks,
Rick
It may be because you are doing it wrong.You added the textview to mainWindow and Getcontroller is a controller entity[its a view controller i think.] .An xib will be connected to the outlet if and only if it has the custom class correctly set to that class.
Add a view controller with custom class in attribute inspector set to that Getcontroller and then you can connect the outlet
When u drag the control to the **.m , u should press the key "control",

Standard Back Button in XCode (XIB)

I can't get the standard back button of iOS into a navigationBar because I can't find it in the Object Library, so can I do it with code or something else?
I just want the normal, standard, blue back button - you know which I mean.
To "automatically" have a back button you need first have a UINavigationController. Then you need to take a different UIViewController and add it as the root view controller in UINavigationController's init method:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:someOtherViewController];
Be sure to also set a title for someOtherViewController, usually in it's viewDidLoad or initializer. I'll tell you why this is important in a second:
self.title = #"Some other VC";
Then take a second UIViewController and push it onto your navigation controller:
[navigationController pushViewController:anotherViewController animated:YES];
You now have two UIViewControllers on your navigation stack: someOtherViewController and anotherViewController.
Your view will now have a back button with "Some other VC" in it. This is the title of the view controller that was just moved out of view:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
http://simplecode.me/2011/09/04/an-introduction-to-uinavigationcontroller/
I would also suggest reading up on how UINavigationControllers work and searching this site a bit more for customizing the back button. There are plenty of threads about it.
You can't add the back button yourself. The back button is part of the Navigation controller. If you embed a Navigation controller into your view(s), the back button will appear and be populated by the name of the previous view.
If you're using storyboards select your view controller, then in top menu choose "editor" -> "embed in" -> "navigation controller".
Edit: Here is an exmaple.
I'm running Xcode 7.2. This was driving me crazy, but I figured it out. Here are all the pieces you need to make the Back button appear (make a test project to prove it):
1) You have to have a Navigation Controller and it has to be set to be the initial view controller. So add the Navigation Controller, you will import two tables. Click on the Navigation Controller and on the properties list, check the box that reads "Is Initial View Controller". You will now see and arrow pointing to this view.
2) In our case we want a ViewController and not the included / connected TableViewController, so delete the TableViewController (RootController) and add a new ViewController.
3) Connect the Navigation Controller to the new ViewController by clicking on the top bar of the Navigation controller and orange circle with the arrow pointing left. Hold the Control button on your keyboard down and click and drag from the orange circle to the ViewController and let go. When given the list of options on how to connect the two views, select 'root view controller'.
Done! Now you the functioning navigation bar and you automatically get the back arrow on all segues added. Test this. Add another ViewController and connect to it with a button on the existing ViewController. Use the Control-click-drag approach from the button to the newest ViewController. Select the 'show' option for the new segue you created.
Run it. You'll see the back option has automatically appeared when you click the button and moved to the newest ViewController.
This is all provided by the Navigation Controller, but only when you make another controller the RootController. Happy navigating!

Configuring the backBarButtonItem of a View Controller's Navigation Item in a Storyboard

It's easy enough to drag and drop bar button items onto a view controller's navigation bar in a storyboard in Interface Builder. In this way, you can set the leftBarButtonItem and rightBarButtonItem outlets of the view controller's navigation item. But there's also a backBarButtonItem outlet, and it's not obvious at all how to set it. How can I set a custom back bar button item using Interface Builder?
Select the view controller whose navigation items you want to change. The black bar displaying the identity of the view controller changes to an iconified tray of its referenced objects.
Drag and drop a bar button item from the object library onto the tray.
Right-click on the view controller's navigation item in the main object tray on the left-hand side. Wire up the newly added button as the navigation item's backBarButtonItem outlet.
Select the bar button and configure it in any way you choose with the Attributes Inspector.
As #wcochran noted above, when working with viewControllers pushed onto a navigationController's stack, the backBarButtonItem outlet is already wired and can't be changed. Furthermore, selecting the child VC's navigationItem and changing the Back Button text in IB doesn't do what you would expect.
Now you might think that replacing the child VC's backBarButtonItem would solve the problem, but it doesn't. Confusingly, if you want to set the title of the back button of a child VC, you have to set the back button title of its parent (!), like so:
- (void)viewWillAppear:(BOOL)animated // in the parent VC!
{
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
}
This won't do anything on the parent VC. In fact, if the parent is the navigationController's RootViewController, there won't be a back button at all. But the child will inherit (or pick up) the back button you've created.
This only applies to the immediate child VC, so if you want to maintain the label down through the navigationController's stack you need to set it on each parent.
Thanks to #wiliz in #iphonedev for explaining this to me.
As #AdamBlock noted above, you have to set things right in the parent VC.
He shows how to do this programmatically. It is also possible to do this in interface builder.
Select the parent VC
Select the navigation Item
Open the Attributes inspector
Set the title for the Back Button.
In Interface Builder, you can change the Navigation Item back button's title.
Programmatically, you can set a custom back button in your view controller's viewDidLoad method. In this example we set the button's image to an image named "customImage.png":
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Custom" style:UIBarButtonItemStyleBordered target:self action:nil];
// Set custom image here
backButton.image = [UIImage imageNamed:#"customImage.png"];
self.navigationItem.backBarButtonItem = backButton;
}

Code Pattern: Loading TabBarController objects directly from independent .xib file (instead of from MainWindow.xib)

I've looked around online, and haven't been able to find an acceptable solution to this problem...
I'm looking for a simple code pattern:
Load a TabBarController object (with associated subview controllers) from a separate .xib file, instead of including and loading automatically from a default MainWindow.xib.
In XCode terms, starting from a new iPad/iPhone project as a "Tab Bar Application", the goal is to solve the following:
Create the project
Move: TabBarController, TabBar, FirstViewController, and SelectedSecondViewController from MainWindow.xib, into a new "TabBarController.xib" file
After moving, MainWindow.xib should only contain: File's Owner, First Responder, App Delegate, Window
In TabBarController.xib, File's Owner and First Responder are set to: UIApplication and UIResponder, respectively.
Change "didFinishLaunchingWithOptions" in the main application delegate to the following:
REMOVE:
[self.window addSubview:tabBarController.view];
ADD:
UITabBarController *uiTab = [[UITabBarController alloc] initWithNibName:#"TabBarController" bundle:nil];
[self.window addSubview:uiTab.view];
With these changes, the application builds and runs, but when the TabBarController loads the tab bar is "empty" -- there don't appear to be any contents in the controller.
In looking in the debugger, either the "init" isn't initializing from the data correctly, or something in the .xib file is not set correctly.
What is the correct solution to this? I realize there are other ways of doing this, and yes, I have them working in other applications.
What I'm looking for however, is a specific solution using the default project, that can be used as a general pattern for setting up iOS code.
Thanks in advance for any help
js
I think i know what you are looking for because i want the same thing.
Create New Empty xib file at interface builder.
Add to the xib TabBarController from the library.
Edit whatever you need on this tab bar controller on the xib.
Of course, save...
Determine from which view controller do want to create that xib with tab bar controller. In other words, who is the view controller that will cause this tab bar controller to appear.
Let's call that view controller ParentViewController
In that view controller, create an IBOutlet to a TabBarController.
Back to the xib, make the identity of the File's Owner to the ParentViewController and of course dont forget to hook up the outlet of the tab bar controller in the file's owner to the tab bar controller in the xib.
save the xib and you are ready to go.
When you want to present that tab bar, just decide which way you want to do it: Modally,Popup or something else (Not inside a navigation controller because Apple dont allow tab bar controllers to be inside navigation controllers).
When you decide, just present your tab bar controller outlet the way to present any other view controller. for example:
[self presentModalViewController:self.myTabBarController animated:YES];
Assuming you start with the "Tab Bar Application" template and move the UITabBarController and associated view controllers to a new nib as you described...
In your new nib, File's Owner should be set to your AppDelegate class. Then connect the outlet "tabBarController" of File's Owner to the UITabBarController.
Then in your -[application:didFinishLaunchingWithOptions:], do not remove this line:
[self.window addSubview:tabBarController.view];
Instead, load the new nib right before that with your app delegate as the owner:
[[NSBundle mainBundle] loadNibNamed:#"TabBarController" owner:self options:nil];
That will set your tabBarController property (since you made that connection in the nib) and then you can proceed as normal. What you were doing was actually creating a whole new UITabBarController, and not loading the one from the nib at all. (well, ok you were loading it for a brief moment, but then not doing anything useful with it)
Hope that helps.

Resources