Technology

An iOS Single View Controller App Built in Xamarin

2 Feb 2015 5:19pm, by

When you are creating an iOS app, you typically use many View Controllers. These are the iOS objects that manage a screen and control navigation between screens. It’s possible though to create a multi-formapp with just one View Controller and in this article, I’ll show you how.

The full source code including all project files of thi sapp is on The New Stack GitHub account.

What Does the App Do?

It displays a screen with a couple of buttons. These are wooden buttons and one says “Cork”, the other “Calc”. Clicking “Cork” switches to two buttons arranged vertically titled “Wood” and “Calc” both with a cork background. Clicking the “Calc” button displays a simple numeric keypad with 0-9, a decimal point and Del and Send buttons. Click these buttons to enter a five digit number with a decimal point. The DEL key removes the last digit or character pressed and SEND pops up a box showing the value entered and switches back to the two button display.

All three different screens have been implemented by reusing just one View Controller.

The App’s Architecture

The smallest iOS app needs just an AppDelegate and a UIViewController. In this app’s AppDelegate it creates and sets the SingleViewController as the root controller, the one that starts things off. This is a very simple class that inherits from the base UIViewController class and overrides the ViewDidLoad method to call a method StartUp(). When a ViewController becomes active for the first time, the ViewDidLoad() method is called. Here it creates a instance of the MainView class, assigns it to the View controller’s View property and then calls the MainView instance Start() method.

View Controllers are the linchpins of an app and if you use the iOS StoryBoard feature, you can create an app with most if not all of the donkey work of managing View Controllers done for you. I chose to make this app 100% code, so no nibs or storyboards were used. For a simple app this is ok but when you develop something more complicated you’ll appreciate what storyboards and nibs can do for you.

The View

Each View Controller has a View that’s an instance of a UIView and that displays content in a rectangular part of the screen and lets the user interact with that content. You can have a screen made up of multiple View Controllers each handling part of it, or you can have one View Controller for the whole screen as I’ve done, with multiple controls.

Each iOS control is a View as the control’s class inherits from UIView. To populate a view with controls, you just create the controls you need and add each control to the View using View.AddSubview( control ). This adds the view to the View.Subviews array and this array manages the controls in the view and how they appear. All the code for creating buttons etc has been put in the lib.cs file e.g lib.GetTextureButton.

To keep the app relatively uncomplicated I put all the view code into MainView.cs. It could have been put in the ViewController file but it’s always better to separate views and view controllers. The MainView class is the control and inherits from UIView. In the constructor called from the SingleViewController StartUp() method, the iPhone’s UIScreen.MainScreen.Bounds are passed in; these have the dimensions of the screen. So the MainView control has access to all of the screen including the top status line with battery, 3G signal strength etc.

The MainView constructor caches a few values in the lib class particularly FrameWidth and FrameHeight. These are used to calculate button size. As there are two square buttons, the calculated button size is stored in lib.ButtonWidth from the iPhone’s screen width and used to calculate the horizontal coordinates col1 and col2 and use them in placing the buttons.

What’s a Unified API?

Apple require that all apps be converted to Unifed Apps by June 2015, that is they can run on 64 bit or 32 bit architecture. Xamarin now supports this and this app has been developed as one. You’ll notice that it uses variable types like nint and nfloat where the n stands for native, so a nint is 32 bits on a 32 bit architecture and 64 bits on a 64 bit architecture while an int is always 32 bits on both architecture. iPhone 5 and earlier use a 32 bit architecture while iPhone 5S and after use 64 bit.

Tear It Up and Start Again

The TidyViews() method clears the screen and is called from the three methods Start(), Calc() and Cork(). It removes all of the controls in the view (more accurately views from the subviews) so new controls can be added. This is the key mechanism that makes possible multiple screens with just one View Controller.

The MainView methods Start, Cork and Calc all have a signature that matches the .NET event handler. It’s a method with two parameters: object sender and EventArgs e. I’ve explicitly defined it as the delegate type Anaction in lib.cs with this line.

One of the parameters of the lib.GetTextureButton is Anaction and it’s wired up to the TouchUpInside event using a lambda expression. You can see this in GetTextureButton with this line. If you don’t know C# delegates or Lambda expressions don’t worry too much, they are basically anonymous functions. This syntax below can be quite baffling but all it does is add the passed in function d to the button TouchUpInside event handler.

Whatever is passed in as the Anaction parameter d becomes the target of a click. In this code below a button with the text “Cork” is added at the coordinates (Col1, bottomy) and when the button is clicked, it calls the the Cork() method.

The keypad keys use the UIButton.Tag property to identify which key was pressed in the ClickButton() event handler. The button tag value is converted to a string in lib.TranslateButtonIndexToString(). If the SEND button was clicked and there’s a string then it calls ShowValue() to display the value using a UIAlertController.

Don’t Confuse iOS Delegates and C# delegates

In iOS when you see the word delegate it means a class that does something for another class and is a very common pattern throughout iOS. In C# though a delegate means an anonymous function.

Conclusion

It’s a bit one trick ponyish but could prove useful for creating simple apps.

Fearture image via Flickr Creative Commons.

A newsletter digest of the week’s most important stories & analyses.