Cross Platform
Android
iOS
Mac

Transitioning from Xcode 3 to Xcode 4

A Guide for Existing Xamarin.iOS Users

With the introduction of Xcode 4, the workflow for creating Xamarin.iOS applications that have interfaces designed in Interface Builder has changed. This article shows how to make the transition from Xcode 3 to Xcode 4 by introducing Xcode 4 and covering how to design interfaces in the new integrated Interface Builder.

Overview

Xcode 4 has seen a major overhaul since Xcode 3, These changes include a number of important new features. However, for Xamarin.iOS developers, the biggest difference is that Interface Builder (IB) is no longer a standalone application, but is integrated directly into Xcode. This was done to better streamline the process of integrating interface definitions with the backing Objective-C code.

So, if you’re developing in Xamarin.iOS and want to create your user interface in Interface Builder, you need to learn a new workflow for integration between Xcode and Xamarin Studio.

Requirements

In order to use Xcode 4 with Xamarin.iOS, you must have at least Xamarin.iOS v4.0.4.1, and Xamarin Studio v2.8. This guide does not apply to Xamarin.iOS for Visual Studio.

Additionally, if you’re working with an existing Xamarin.iOS project, you will need to upgrade it to the new project file format.

Upgrading Your Project

When you open an older project with Xamarin Studio, it will prompt you to upgrade your project file:

We recommend you choose Back up and migrate, which will create a “backup” folder in your project directory and copy your old project file there. In case something goes wrong with the conversion, it can be helpful to be able to restore the original project file.

Introduction to Interface Builder v4.0

Although Interface Builder is now integrated into Xcode, it’s still largely the same, with the exception of how Outlets and Actions are now created and wired up. Specifically, it gives you the ability to create an Outlet or an Action and wire it up to a control all in one step.

To try this, double-click a .xib file from Xamarin Studio. It launches Xcode 4 and shows the integrated Interface Builder designer:

In the toolbar there is a View Pane button:

If you click on the right button, it will show the Utility Area of Xcode, which contains tab versions of the old Interface Builder windows:

As you can see, Xcode is split into different areas:

The Project Navigator contains Objective-C stubs of your C# files, as well as the other files in your project such as .xibs, images, etc.

The Utility Area is separated into two sections, with the Inspector tabs at the top, and the Library tabs at the bottom:

If we look at the Inspector tabs, most of them should be familiar (with the exception of two new ones), as they are the same inspectors that were individual windows in Xcode 3. The only difference is that they’re now compacted into one area of the UI. The following illustration shows each of the tabs, side-by-side:

From left-to-right, these tabs are:

  • File Inspector – New in Interface Builder 4, the File Inspector shows file details, such as the file name and location, as well as other information.
  • Quick Help – Also new in Interface Builder 4, the Quick Help tab is part of Xcode 4’s redesigned help system and provides contextual help based on what is selected in Xcode.
  • Identity Inspector – The Identity Inspector remains largely unchanged from Xcode 3 and provides information about the selected control.
  • Attributes Inspector – The Attributes Inspector also remains largely unchanged and allows you to customize various attributes of the selected control.
  • Size Inspector – The Size Inspector also remains largely unchanged and allows you to control the size and resizing behavior of the selected control.
  • Connections Inspector – The Connections Inspector also remains largely unchanged and shows the Outlet and Action connections of the selected controls.

The Document Inspector can now be found on the left side of the Editor Area and is collapsed by default. You can expand it by clicking the > button at the bottom of the area:

Outlets and Actions Review

It’s helpful to remember that Outlets and Actions are the method in which controls are able to interact with code in iOS programming. Outlets correspond to properties that represent controls within the UI, and Actions wire a control interaction directly to a method in your code.

In this regard, we can think of Outlets as accessible controls whereas Actions provide a mechanism in which multiple controls can have their events wired to a single method.

Inspecting Outlets and Actions

If you’re working with an existing project that already has Outlets and Actions, you can view them just as you did before, in the Connections Inspector tab. Select the Outlets or Actions of the control you want to view and then select the Connections Inspector tab:

The sample application for this article has three buttons, one is exposed via an Outlet, and two are wired directly to a method in the code-behind via an Action. Additionally, this application has a label, which gets updated when one of the buttons is clicked.

Here we see an important difference between Xcode 3 and the newer version. In Xcode 4, Outlets and Actions are exposed in the header (.h) file that corresponds to the twin C# file. For example, if we look in Transitioning_To_Xcode_4ViewController.h, we’d see:

// WARNING
// This file has been generated automatically by Xamarin Studio to
// mirror C# types. Changes in this file made by drag-connecting
// from the UI designer will be synchronized back to C#, but
// more complex manual changes may not transfer correctly.
 
#import <UIKit/UIKit.h>
 
@interface Transitioning_To_Xcode_4ViewController : UIViewController {
       UIButton *_btnClickMe;
       UILabel *_lblOutput;
}
 
@property (nonatomic, retain) IBOutlet UIButton *btnClickMe;
@property (nonatomic, retain) IBOutlet UILabel *lblOutput;
- (IBAction)actnButtonClick:(id)sender;

@end

This allows your Outlets and Actions to be visible to Interface Builder. As we’ll see in a moment, Xamarin Studio watches this file and will create the corresponding Outlets and Actions in your C# file, when you create them in Interface Builder.

Adding Outlets and Actions

In Xcode 4, Apple has added a new way to create Outlets and Actions directly in code via Control-dragging. More specifically, this means that in order to create an Outlet or Action, you choose which control element you’d like to add an Outlet or Action, hold down the Control button on the keyboard, and drag that control directly into your code.

For Xamarin.iOS developers, this means that you drag into the Objective-C stub files that correspond to the C# file where you want to create the Outlet or Action.

In order to facilitate this, Xcode 4 introduced a split-view in the Editor Area called the “Assistant Editor” that allows two files to be visible at once (the .xib file in the Interface Builder designer, and the code file in the code editor).

In order to view the Assistant Editor split screen, click the middle button of the Editor choice buttons in the toolbar:

This will open up the split-screen view, with the currently selected file open in both views. To replace the file on the left with the code file where you want to create the Outlet or Action, choose the corresponding .h file from the Project Navigator.

Creating an Outlet

In order to create the Outlet, use the following procedure:

  1. Determine for which control you want an Outlet.
  2. Hold down the Control key on the keyboard, and then drag the control to an empty space in your code file after the @interface definition.

You can drag from the Document Inspector as well, which can be helpful if you have a complicated UI with nested controls.

A popover will then show, giving you the option to choose either Outlet or Action, and a name and a type for it:

Click Connect after you’ve filled out the form, and Xcode will insert the appropriate code in the .h file:

Save the file, and then go back to Xamarin Studio. If you open the .designer.cs file that corresponds to the .h file that was just modified in Xcode, you’ll see your new Outlet:

In the previous example, we created an Outlet called btnClickMe. We can now use the Outlet as we normally would:

public override void ViewDidLoad ()

{
       base.ViewDidLoad ();
       //any additional setup after loading the view, typically from a nib.
       //---- wire up our click me button
       this.btnClickMe.TouchUpInside += (sender, e) => {
              this._numberOfTimesClicked++;
              this.lblOutput.Text = "Clicked [" + 
                   this._numberOfTimesClicked.ToString() + "] times!";
       };
}

Creating an Action

Creating an Action is done the same way as creating an Outlet, Control-drag from the control into the code, but choose Action as the Connection type in the popover menu:

Name the Action and select on which event you’d like the Action to be called.

You can also strongly-type the type controls that can call this action. If you don’t strongly type it, you’ll have to cast the sender object to its appropriate type when you want to use it, as we’ll see in a moment.

You may want to wire up multiple items to the same action (which is the entire point of using an Action, as opposed to an Outlet).

To do this, instead of Control-dragging to a blank space in the code, you Control-drag to an existing Action:

In this case, we Control-dragged from the Connections Inspector, which allowed us to select the event on which we wanted to call the Action, but we could have just as easily Control-dragged from the control in the designer or in the Document Inspector.

Once our action is wired up, we can use it just as we would if it were created in Interface Builder 3:

/// <summary>
/// This is our common action handler. Two buttons call this via an action method.
/// </summary>
partial void actnButtonClick (MonoTouch.Foundation.NSObject sender)
{
       this.lblOutput.Text = "Action button "
+  ((UIButton)sender).CurrentTitle + " clicked.";
}

Summary

In this article we saw that Xamarin.iOS and Xamarin Studio have full support for Xcode 4’s integrated Interface Builder. The workflow is slightly different from Interface Builder 3, but it’s still fairly simple, once you understand the changes.