Designing a Universal iOS App with a Tableview Navigation
As I introduce in chapter 3 of The Web Designer’s Guide to iOS Apps, there are three options for designing a native iOS app:
- Designing for iPhone and iPod touch
- Designing for iPad
- Designing a universal app that will scale to run full-screen on all iOS devices
This is true whether you are designing with the NimbleKit JavaScript API or developing natively and writing your own Objective-C. This article focuses on the NimbleKit option.
Here is the difference: an iPhone / iPod touch app runs at its original scale on an iPad, and therefore runs in a small iPhone-sized window within the larger iPad screen. While you can touch the “2X” button to enlarge this app window, the results are not very satisfying: the image is simply doubled in size, but the resolution remains the same (and, because the pixels are enlarged, one might more accurately say that the resolution goes down by half!).
So if this is a problem for your app, what is the solution? One solution is to design separate iPhone/iPod touch and iPad versions of your app. This is fairly common — just look at all of the “HD” iPad versions of apps in the App Store.
But this isn’t the only option. And sometimes this isn’t the best way to address the issue, such as when a universal app might be preferred. The universal app has a few key distinctions:
- One purchase for multiple devices can mean less cost for your customers
- One app download can sync to multiple iOS devices owned by the same customer (to support owners of both an iPhone and iPad, for example)
So if this sounds like it meets your goals, read on!
When starting a new NimbleKit application project in Xcode, you are presented with three Device Family options:
- iPad
- iPhone
- Universal
Select Universal (Figure 1) and, after entering a Project Name and Company Identifier (see chapter 3 for more about this), click Next and then choose a location to save the new project directory (Xcode will create the project directory and files for you).
After Xcode creates the directory and file structure, you are presented with directory and file views of your project. Select main.html to display the HTML markup in the file panel (Figure 2). You will see the standard sample text that is in a new NimbleKit app project.
Next, let’s design a sample user interface that will adapt to both the iPhone/iPod touch and iPad screen sizes automatically. Because it’s a standard interface, we will work with a tableview navigation (see chapter 4). The tableview is added via JavaScript, and there are four steps to adding one to an app:
- Declaring
- Initializing
- Populating
- Showing
First, you will declare a new NKTableView instance and call it myNav. Add this declaration right below the JavaScript that calls the NimbleKit library, as shown here:
<script type="text/javascript" src="NKit.js"></script> <script type="text/javascript"> var myNav = new NKTableView(); </script>
Next, you will initialize the size and style of the tableview.
<script type="text/javascript" src="NKit.js"></script> <script type="text/javascript"> var myNav = new NKTableView(); myNav.init(0, 0, window.innerWidth, window.innerHeight, 'plain'); </script>
Note that parameters being set here are the starting point for drawing the tableview on the screen (X value = 0, Y value = 0, or the top left of the screen), the width and height (these are basically auto-width and –height commands), and the style of the tableview (plain; grouped is the second option).
Next, you will populate the tableview with rows of items or records. We will use the same Bill of Rights content that I use in chapter 5 of my book:
<script type="text/javascript" src="NKit.js"></script> <script type="text/javascript"> var myNav = new NKTableView(); myNav.init(0, 0, window.innerWidth, window.innerHeight, 'plain'); myNav.insertRecord("1st Amendment", "", "", "0", "", "navController.gotoPage('1.html')"); myNav.insertRecord("2nd Amendment", "", "", "0", "", "navController.gotoPage('2.html')"); myNav.insertRecord("3rd Amendment", "", "", "0", "", "navController.gotoPage('3.html')"); myNav.insertRecord("4th Amendment", "", "", "0", "", "navController.gotoPage('4.html')"); myNav.insertRecord("5th Amendment", "", "", "0", "", "navController.gotoPage('5.html')"); myNav.insertRecord("6th Amendment", "", "", "0", "", "navController.gotoPage('6.html')"); myNav.insertRecord("7th Amendment", "", "", "0", "", "navController.gotoPage('7.html')"); myNav.insertRecord("8th Amendment", "", "", "0", "", "navController.gotoPage('8.html')"); myNav.insertRecord("9th Amendment", "", "", "0", "", "navController.gotoPage('9.html')"); myNav.insertRecord("10th Amendment", "", "", "0", "", "navController.gotoPage('10.html')"); </script>
Finally, you will instruct the app to show or draw the tableview nav as you have defined it:
<script type="text/javascript" src="NKit.js"></script> <script type="text/javascript"> var myNav = new NKTableView(); myNav.init(0, 0, window.innerWidth, window.innerHeight, 'plain'); myNav.insertRecord("1st Amendment", "", "", "0", "", "navController.gotoPage('1.html')"); myNav.insertRecord("2nd Amendment", "", "", "0", "", "navController.gotoPage('2.html')"); myNav.insertRecord("3rd Amendment", "", "", "0", "", "navController.gotoPage('3.html')"); myNav.insertRecord("4th Amendment", "", "", "0", "", "navController.gotoPage('4.html')"); myNav.insertRecord("5th Amendment", "", "", "0", "", "navController.gotoPage('5.html')"); myNav.insertRecord("6th Amendment", "", "", "0", "", "navController.gotoPage('6.html')"); myNav.insertRecord("7th Amendment", "", "", "0", "", "navController.gotoPage('7.html')"); myNav.insertRecord("8th Amendment", "", "", "0", "", "navController.gotoPage('8.html')"); myNav.insertRecord("9th Amendment", "", "", "0", "", "navController.gotoPage('9.html')"); myNav.insertRecord("10th Amendment", "", "", "0", "", "navController.gotoPage('10.html')"); myNav.show(); </script>
That’s all there is to it! The auto-width and -height parameters make this universal app example a snap to program.
To add a final touch of familiarity, let’s also add a navigation bar at the top of the JavaScript code. You will give it a blue hue and title it “Bill of Rights.” You will also enable auto-orientation so the tableview will adjust for both portrait and landscape widths on all iOS devices:
<script type="text/javascript" src="NKit.js"></script> <script type="text/javascript"> var navController = new NKNavigationController(); navController.setTintColor(39, 54, 141); navController.setTitle("Bill of Rights"); function NKIsPageSupportsAutoOrientation() { return "yes"; } var myNav = new NKTableView(); myNav.init(0, 0, window.innerWidth, window.innerHeight, 'plain'); myNav.insertRecord("1st Amendment", "", "", "0", "", "navController.gotoPage('1.html')"); myNav.insertRecord("2nd Amendment", "", "", "0", "", "navController.gotoPage('2.html')"); myNav.insertRecord("3rd Amendment", "", "", "0", "", "navController.gotoPage('3.html')"); myNav.insertRecord("4th Amendment", "", "", "0", "", "navController.gotoPage('4.html')"); myNav.insertRecord("5th Amendment", "", "", "0", "", "navController.gotoPage('5.html')"); myNav.insertRecord("6th Amendment", "", "", "0", "", "navController.gotoPage('6.html')"); myNav.insertRecord("7th Amendment", "", "", "0", "", "navController.gotoPage('7.html')"); myNav.insertRecord("8th Amendment", "", "", "0", "", "navController.gotoPage('8.html')"); myNav.insertRecord("9th Amendment", "", "", "0", "", "navController.gotoPage('9.html')"); myNav.insertRecord("10th Amendment", "", "", "0", "", "navController.gotoPage('10.html')"); myNav.show(); </script>
Testing the app in iOS Simulator will reveal two full-screen tableview navigation layouts, one for the iPhone/iPod touch and the other for iPad (Figures 3 and 4).
To download the complete sample code for this exercise (including the additional screens for each Bill of Rights), visit:
http://iosapps.tumblr.com/downloads
In conclusion, if you have ever wondered how complicated it might be to design an app screen or navigation that is responsive to different iOS devices, I hope this example demonstrates that it does not need to be very difficult. But also realize that this is just one of many possibilities; consider exploring NimbleKit’s NKGetDeviceType function, too. That, coupled with some additional JavaScript if... then statements, could allow you to design entirely different user interfaces for iPhone/iPod touch and iPad.