This is Part 1 of a tutorial that follows Apple’s “Your First iOS App”, but implements all of the user interface elements programmatically. View Part 2 here or view the complete code on Github. Discussion on Hacker News.
I created this tutorial for developers transitioning to iOS that don’t want to deal with Storyboarding or Interface Builder. It implements the “Hello World” app from Apple’s documentation entirely in code.
From Apple’s documentation:
When you run the finished app, you click inside the text field to reveal the system-provided keyboard. After you use the keyboard to type your name, you dismiss it (by clicking its Done key) and then you click the Hello button to see the string “Hello, Your Name!“ in the label between the text field and the button.
First, open Xcode and click on “Create a new Xcode project” I’m using version 4.6.
Use an empty application.
Fill out the remaining fields. Make sure “Use Automatic Reference Counting” and “Include Unit Tests” are checked. Core Data isn’t necessary for this tutorial.
Even though we chose to create an “Empty Application”, Xcode still created some default files. Navigate to the AppDelegate.m file by clicking the file browser on the left side of the screen.
The App Delegate file is your application’s way of communicating with the operating system, and includes several useful methods.
We’ll mostly be dealing with “application didFinishLaunchingWithOptions”, which is called immediately after the application launches.
If you click on the Run button in the top left, your application should build with a blank white screen.
You might have noticed a warning:
"Application windows are expected to have a root view controller at the end of application launch".
Don’t worry, we’ll set this next, but first we have to create a ViewController class. Click on File, New, File…
In the Cocoa Touch section, select Objective-C class and click Next.
You can choose the name of your class, but make sure to set it as a subclass of UIViewController below. I named mine “MainViewController”. The UIViewController is a fundamental class of iOS development, and is used to make and handle interaction with elements in the user interface. Click Next, and then Create.
You should now have MainViewController.m and MainViewController.h files with some boilerplate code inside. We’ll come back to those in a bit - for now, go back to your AppDelegate.m file.
First, make sure to import your MainViewController class at the top of the file:
#import "AppDelegate.h" #import "MainViewController.h"Next, take a look at the “application didFinishLaunching” method - it should contain some default code matching the one below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; }It’s here that we set the “root view controller” property - or the view that is displayed when the application launches.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.window.backgroundColor = [UIColor whiteColor]; /* create an instance of our view controller then set it as the window's root view controller */ MainViewController *viewController = [[MainViewController alloc] init]; self.window.rootViewController = viewController; [self.window makeKeyAndVisible]; return YES; }Running the app again should still give you a white screen, but this time the warning will disappear. In the next part of this tutorial, we’ll handle all of the on-screen elements.
This is the second article in a series of blog posts that we will write about LinkedIn's new iPad App. In the first post, we described how we build a snappy mobile experience using HTML5 local storage. In this article, I am going to talk about the challenges we faced building an infinitely swipe-able list.
What's a "Stream"?
When we started the iPad project, we thought through how we can create an engaging content consumption experience for our users. We decided to present the articles, network updates, and other similar content as a "stream": an infinite, swipe-able view. Here's the first page of my stream:
Problems with an infinite list on Mobile Devices
Mobile devices have less memory and CPU power compared to Desktop computers. If you render a very long list in the HTML, you run the risk of crashing the device. This makes it challenging to build large, interactive HTML5 apps for mobile devices. Native technologies provide UITableViewController to build long, infinite scrolling lists. UITableView contains reusable UITableViewCells which are optimized for memory, performance and responsiveness . For HTML5, we did not have any solution. So we set out to build one!
Technique #1: unloading images
UIWebView/Mobile Safari have strict limits for images. Our stream is full of big images, so we hit the limits very quickly. One option was to use the HTML5 Canvas element to draw images without running into memory issues. However, we found drawing very big images on canvas was slow, so we had to take another approach: whenever an image was swiped sufficiently off screen, we replaced the "src" attribute of the img tag with a very small image. This ensured that the memory used for rendering large images was freed up periodically. Also, we ensured that we did not introduce the empty image src attribute bug.
Technique #2: hiding pages
Unloading images did not reclaim enough memory to prevent crashes. So we started hiding individual pages of the stream by setting the CSS visibility property to hidden (denoted in Picture 2 by "Invisible" page). After this change, we not only saw more memory being reclaimed (resulting in app not crashing) but also faster render times because the browser did not have to paint the "invisible" pages on the UI.
Technique #3: removing pages
Introducing invisible pages covered 80% of our use cases. The app would still crash for the remaining 20%! We went a step further and started removing pages that were not required. As a side effect, if we removed a page to the left of the current visible page, the stream would shift left and the user would lose the scroll position. In order to maintain the scroll position, we had to replace the removed page (aka the DOM node), with an empty page of equal height and width (denoted by "Stub" in picture 2). If the user is viewing page 5, for example, we removed page 0 and replaced it with a stub.
Armed with these 3 techniques, our stream started looking something like the following images. As you can see in picture 1, if the user is currently viewing page3, one page before and after the current page is fully loaded. So if the user decided to swipe forward/backward, she can see the fully rendered page. We played around with loading the images and rendering the page while the user is trying to scroll. It worked perfectly on the iPad simulator, but on the actual device, you could see degradation in scrolling performance.
Picture 1
Picture 2
As seen in picture 2, when the user swipes to Page 5, Page 0 and Page 1 remove themselves, Page 2 becomes invisible and Page 3 unloads all of its images. At this point, the user can continue to swipe forward, and the stream pages will decide to unload images/hide/remove themselves based on how "far" they are from the visible page.
We had to use a variable sized "window" for the different versions of the iPad. For example, the iPad1 has the least memory, so we had to give it a very small window:
Technique #4: avoid scaling and box-shadow
As we worked, we ran across two more HTML/CSS optimizations that helped performance:
- Avoid client side scaling of images by specifying the width and height attributes in HTML img tags
- Avoid CSS box shadow: it's slow on webkit
Technique #5: minimizing DOM nodes
With the above optimizations, you'd expect the app to not crash ever, right? Wrong! During testing, the techniques above would let the app run longer, but after a while, it would still crash.
From our iPhone app experience, we knew that keeping DOM nodes to a minimum was the key to smooth scrolling and keeping memory in check. Keeping this in mind, we merged all the stub DOM nodes with one dummy node equal in size to all of them combined. The result: no matter how many pages we swiped to, the stream did not crash on any of the devices! The final mechanism is depicted in Picture 3:
Picture 3
A video of all the techniques in action
Here's a screencast of how the DOM behaves when the user is swiping forward in the Stream. On the left, we have the stream loaded in a Google Chrome window. On the right, we have the Google Chrome Web Inspector showing how we add/remove nodes and extend the dummy page's width to fill in for removed stream pages. Note how the DOM nodes remain at a constant number and how the first li in the ul (the "Dummy" node), grows in size (you may need to make the video full screen to see it well):
Failed Attempts
We did not get this right the first time around, so it's only fair to list some of the things we tried that didn't work. We started by using multiple UIWebViews, each one rendering one stream page and using UISwipeGestureRecognizer to swipe between them. We quickly realized that using multiple web views in one native app was a bad idea for memory and performance reasons.
We then tried an approach similar to the 3-DIV approach . It worked, but we were not satisfied with the swipe performance on the stream. Sometimes, if the user swiped while we were rendering one of the stream pages, the UIWebView, being single threaded, did not register the swipe.
Acknowledgements
Thanks to Akhilesh Gupta, Aarthi Jayaram, Ashit Gandhi, Kiran Prasad, and Ganesh Srinivasan. Also, a special thanks to Ryan for helping me compile the screencast for this blogpost.
At Appboy, we’re constantly working to provide developers with tools to deliver an excellent experience for their users. As a result, we have to consider two target audiences and use cases for many of our product decisions: the developers that use Appboy in their apps, and their users. A great example of a case where we’ve designed for both developers and users is the implementation of Appboy’s theming feature.
Application Theming
The Appboy platform functions as an “app-within-an-app” that provides developers with a variety of tools for interacting with users. Certain actions and UI elements allow a user to “drop in” to Appboy and gain access to the additional features that we provide. Once inside of Appboy, users interact with our own custom UI. A common request that we heard from developers was the ability to white-label the Appboy interface. For certain apps, we found that the Appboy color scheme clashed with the host application’s theme, creating a jarring experience for users. Additionally, some developers felt that including our branding elements in their apps (for example, text saying “Appboy” that was originally overlaid on the app’s header bar) was confusing to users. This developer feedback led us to build our over the air Theming offering, allowing developers to customize their users’ experiences.
The Dashboard Interface
The original Appboy interface used the same aquamarine and black theme as this blog. An example of the original UI is below:
Currently, developers are able to customize the color of the Appboy buttons, the application header, the tabbed navigation, and the distinctive Appboy lightning bolt. These options allow developers to dramatically alter the branding of the Appboy UI without disrupting the application flow or functional layout of the interface. An example of a fully themed app is below. Throughout Appboy, the original color scheme has been replaced with the color scheme of the host app. Our overall goal is to provide users with an aesthetically pleasing experience that captures both the host app’s look and feel and our own Appboy experience.
Native UI:
Appboy Interface UI:Allowing developers to style their apps can be a double-edged sword, however. Although the Appboy interface is embedded within our developers’ apps, we still feel a responsibility to have our interface look welcoming and appealing. Like giving your aunt Myrtle a karaoke mic after a few glasses of Merlot, giving developers the ability to drastically alter your interface with a keystrokes can be either a huge success or a debacle. To improve this process, we built a full theming demo on our dashboard using HTML5 and CSS to allow developers to preview their theming preferences.
iOS to Web
To create an efficient theming system, we designed a simple, sandboxed interface where developers could test out the look and feel of their app. By showing all of the styleable UI components in a single location, developers gain an accurate representation of how their themed app will appear in a holistic sense. We also included a CSS color picker widget to allow developers to more easily select the perfect color scheme for their app. To drive home the point of the demo, we also embed the theming demonstration in an image of an iPhone to provide a more immersive experience.
Pressing the “Preview” button from our demo automatically generates and applies new CSS rules to the appropriate DOM elements, instantly changing the interface to reflect the new color scheme selected. Coloring the buttons, tab controllers, and segmented controllers was a straightforward exercise, but coloring the header bar that runs across the top of iOS apps was more challenging. The iOS application header bar is usually colored with a gradient that produces a rounded, pseudo-3D effect. In addition to providing a visually appealing gradient, we also needed to superimpose the Appboy lightning bolt (which is also styleable) on top of the header itself.
Generating the lightning bolt was ultimately much more complex than we had anticipated. Not only did we need to arbitrarily color a non-rectangular geometric shape, but we needed to place it on top of a Canvas element that was also arbitrarily colored. We toyed with the idea of generating a colored lightning bolt image, but processing a new image on the server whenever a developer wanted to preview a new theme seemed unnecessarily complex. We also considered programmatically styling an alpha-only image using CSS, but this caused visual artifacts that bled over into our header bar.
Ultimately, we decided to bite the bullet and use HTML5 Canvas to programmatically draw exactly what we wanted on the header bar area. After creating the rounded bar gradient, we use the Canvas API to select the pixels in the area of the lightning bolt. When a developer presses the button to preview their theming options, we translate these pixels into an X-Y coordinate mapping and use parametric equations to identify the pixels that lie within the bolt. For example, the coordinates of a given pixel within the lightning bolt might need to obey the equations X > 2, Y > 10, and -3X + 20 > Y. We can then iterate over the selected pixels and selectively update the color of the pixels that compose the bolt itself. The overall effect is a visually appealing customizable lightning bolt. As a bonus, we now also use a variation of this real-world problem as an interview question.
Theming Results
Overall, theming has been a big success and is one of our most popular features. We’re currently working on expanding our theming options to include UI features such as fonts, enabling developers to customize their apps even further. If you have other ideas on ways to help us customize and improve our user (and developer!) experiences, please let us know!
Fluid UI - The fastest way to prototype iPhone and Android Mobile Apps
When I redesigned the KEYBOX icon for version 2.2, I promised to write about the icon design approach I took. It’s taken me some time to get around to it but here it is. In this post I want to talk about optimizing your app icon so that it has greater visual impact in the App Store. This is not an article showcasing a handful of awesome icons, there are already plenty of those.
The Basics
Most sales of iPhone apps are made via the App Store app present on each iPhone. When designing your app’s icon, how it will appear in this store is of utmost importance and as you can see from the image below, there are four important elements that introduce your app to the world…
- Icon
- App Name
- Price
- Review count and rating
People are visual by nature. Our eyes are drawn naturally to images and shapes.
When an iPhone user is quickly scrolling through a list of apps in the App Store, an icon that grabs the user’s attention may be the only thing preventing the remaining three elements and most importantly your app’s detail screen from being overlooked.
Before & After
The old KEYBOX icon is an example of how not to design an icon. It was my first attempt at iOS app icon design and, admittedly, a bad one at that. As you can see from the below image, it was flat and almost the same color as the App Store background. It’s almost as if it were hiding from the iPhone user and in retrospect it’s a miracle KEYBOX sold any units at all prior to the icon redesign.
Below is the new KEYBOX icon.
I’m not claiming that it’s the most impressive icon out there but it’s a far cry from the original. I wanted to retain the spirit of the original icon (a secure place to safeguard your secrets) while also communicating how advanced KEYBOX actually is. Even though the image of a safety deposit box is familiar and trusted it was beginning to feel…. well, old.
The new icon keeps the signature keyhole (which has been there since the J2ME version back in 2005), and adds a foggy glass window through which we can just barely make out the many secrets represented by colored lights. The exterior of the box appears sturdy and the orange lit lock lamp communicates the box’s locked state. The grooved black panel rising slightly above the white box denotes that it is where the user unlocks the box. I could go on forever but what I’m getting at is the detail this icon now offers gives it a tangible feel and almost looks as if it could be plucked right out of the screen.
Real Testing
As you might have already guessed, when I redesigned the new KEYBOX icon I wanted to be sure it stood out from not only crowd but also the App Store itself. The most important advice I can offer in this post is this: From day one, understand how icons (not just your own) will appear in the App Store.
To demonstrate what I mean, the iPhone App Store (the native app, not the browser-based iTunes app page) offers two background colors, dark gray (#98989C) and light gray (#ADADB0). On the left, right and bottom sides of the icon is a drop shadow. Below is a blown-up image of the KEYBOX icon as it appears in the App Store. Compare it to the icon above and note the drop shadow on both sides and below the icon.
Since translucency isn’t supported, you’ll need to emphasize your icon’s false sense of depth (the object casting the shadow) along these edges if you want a professional look.
Overcoming The Unnatural Icon
It should be obvious that an icon which doesn’t populate the bottom, left and right sides will look unnatural. We are forced to fill up those boundaries. I know I said this article wouldn’t be about existing examples of great looking icons but I just want to link to some creative icons that took this forced shape constraint and made something delightful with it. The lesson is let this constraint push you to be creative.
Porting Considerations
At some point you may want to port your app to the Mac, to Windows or maybe even to Android. At the time of this writing, iOS is the only platform that forces the rounded rectangle shape on us. If you’re porting your app away from iOS you’ll no longer be constrained this way. However offering the identical icon on a different platform can provide instant recognition with users already familiar with your iOS app so there is some merit in keeping the icon identical.
Standing Out
It goes without saying that you want people to notice your app. Once you have ensured that your icon fits well in the App Store you can now concern yourself with competing with other apps for attention. Below are some techniques other apps are already using. Your app icon should also follow suit.
- Using the drop shadow to provide depth.
- Using contrasting colors.
- Use alarming colors like red and yellow if appropriate.
- Using gradients to provide a sense of texture.
Below I’ll examine each of these techniques in detail…
Depth
As I mentioned earlier, people are visual and react to shapes and images. Objects that cast shadows appear to stand out. Since Apple renders a drop shadow under each icon we should use it by adhering to the rounded rectangle shape. The one element to be careful of is that this drop shadow also forces us to apply the correct lighting upon the object that is casting that drop shadow (from above, obviously). The only exception is when an icon is intended to be a flat window into a scene.
Another lesser used depth technique is the sink-into-screen icon.
Apple’s Photo Booth and Newsstand apps are excellent examples of this. Rather than protrude out of the screen towards the user they sink into it. The Photo Booth icon cleverly uses a border to create a small booth/room and shows the floor to give a sense that it can be walked into. The Newsstand icon appears as the typical magazine stand one might find in a street kiosk. The only caveat with this approach is that it leaves less room for the objects within the sunken space. Lastly, a sense of depth can be achieved by casting inner shadows. KEYBOX’s black panel casts two such shadows onto the white box to which it is attached.
The worst way to destroy the sense of depth is to opt for Apple’s default glossy effects. This effect encases your app icon in an chiclet-like button. To turn this off, select “Prerendered” in the project’s Target Summary Window (near App Icons). If you’re using a version of Xcode that doesn’t support this try setting the “UIPrerenderedIcon” preference to YES in Target Properties.
Contrasting Colors
The human eye is driven to contrasting colors. One of the best app icons to demonstrate this is the ever popular Temple Run by Imangi Studios. Its use of yellow and black helps it both stand out from the App Store’s gray background as well as pull the eyes of any iPhone user to it. Even if the game is not of interest to the user this icon cannot simply be ignored.
KEYBOX’s new icon also employs a contrast of white and black. The white contrasts with the App Store’s gray background and the black contrasts with the white.
Alarming Colors
Color psychology teaches us that some colors induce a sense of alarm in people. Red and yellow indicate spiciness, high temperature, danger, and even anger. Adding a white halo around these colors can amplify their effects. The topic of color psychology is too deep for this post but it is worth studying the effects certain colors have on a target audience and whether those effects are appropriate.
Gradients
In reality, your app’s icon is a flat array of pixels. To provide the illusion that objects in your icon are tangible use gradients. They trick the eye into believing that light is refracting off surfaces at different angles, angles that should only be possible if the object itself were not flat. Take the aforementioned Photo Book icon’s red curtain. It appears to ripple but of course this is just an illusion.
The Tools & Techniques
We’ve discussed theory long enough. Now for some tools and techniques.
As you are probably aware, the App Store requires that you prepare your icon in a variety of resolutions…
- 57×57 for non Retina display iPhones
- 114×114 for Retina display iPhones and iPod touches
- 512×512 for the App Store (will be resized at display time to a smaller size)
Obviously you won’t make the same icon 3 times but will instead resize it to each of these resolutions. Some people dabble only in raster graphics for this but I prefer vector graphics perfectly rasterized at the end to the right size.
I might be the only developer who isn’t using Photoshop / Illustrator to create app icons. I like to support Indie Developers and I’m an Acorn user. As for my vector graphics needs I discovered Inkscape and SVG years ago and never looked back. Inkscape is originally intended for Linux and on the Mac it has to run as an X11 application. This leaves a lot to be desired in terms of look and feel but it is a very capable SVG editor and gives me numerical precision over all my icons’ elements.
If you don’t spend much time doing graphics editing and don’t feel justified in forking over the amount of cash to buy Illustrator check out Inkscape. If you’re already in possession of Adobe software or any other software capable of the job by all means go with what you have.
I’ve prepared an Icon Template SVG file in Inkscape that provides the dimensions and rectangle rounded corners just the way Apple likes them. You can use this as a container for your icon and to export the various raster graphics at their respective resolutions. If you inspect the SVG XML you’ll find the exportable area to use with the “Export Bitmap” function. In this file I used a 512×512 rectangle with rounded corners (rx and ry set to 70.0).
A Modeling Contest
My approach for judging the visual appeal of my app icons is much akin to a modeling contest. Up until now I’ve made it sound as if creating an optimized app icon is down to a science. Nothing could be further from the truth. As if tweaking this or that element in isolation would eventually yield the perfect icon. Models in a beauty pageant are not judged in isolation, they are judged in tandem against one another, and so must our app icons!
The steps described below put you in charge of a modeling contest, for icons!
- Scour the iPhone’s App Store and take full 640×960 screenshots of screens with the most attractive icons you encounter.
- Of all these icons pick what you consider to be the best four. Any given App Store screen can only display five apps so yours will be the fifth competing for eye-balls against these four.
- Using Acorn, Pixelmator or any other graphics editor create a 640×705 image within which you’ll drop each 640×141 app slot.
- Place your app icon in the middle slot. If your app is not already available in the App Store you’ll need to get creative and override another app’s slot with your icon. Don’t worry about the app name or other text, we’re just concerned with the icon for the time being.
- Walk away from your Mac for at least 15 minutes and come back to gain a fresh and unbiased view. Remember, you want to see what App Store patrons who are otherwise indifferent to your app will see.
- Judge which icon is the most attractive.
At the end of this process, if your app icon doesn’t even come close to contending identify why that is not the case. From there, decide what actions to take in order to close the gap.
I’d love to provide you with a template full of beautiful icons against which you could compare your own but I don’t own the rights to those icons. I can only provide you with these instructions for creating your own template.
In Closing
Creating an app is no small task and takes weeks if not months from beginning to release. Regardless if you are selling your app or giving it away for free you want to get it into people’s hands and everyday it is getting harder to gain the awareness needed to accomplish this. Your app’s icon is the gateway to impressing potential users and you owe it to yourself to put as much effort into it as you did your app.
Speaking personally, KEYBOX’s sales have more than doubled in response to the new icon design. I wish I knew what I know now when I first released it. Hopefully you’ll be able to apply these techniques from the beginning for your app.
About the author
I create software to scratch personal itches and then polish it for you to enjoy! I believe simple design is sexy, craftsmanship is a lost art in desperate need of a revival and that the old fashioned way of doing business is best. Armed with stockpiles of coffee and great feedback and trust earned from people like you, I intend on staying the course, righting the wrongs and getting a nice buzz all the while. By Jay Fuerstenberg Google+
Starting today, the Metro style theme for JQuery Mobile, the popular open source mobile user interface framework, is available for download on GitHub and can be used as a NuGet package in Visual Studio.
The theme enables HTML5 pages to adapt automatically to the Metro design style when rendered on Windows Phone 7.5. The Metro style theme is open source and available for download here. This new Metro style theme’s development was sponsored by Microsoft Open Technologies, Inc. working closely with Sergei Grebnov, an Apache Cordova committer and jQuery Mobile developer.
The theme looks just gorgeous, doesn’t it?
The CSS and Javascript theme adapts to the current theme used in Windows Phone and applies the right styling to the jQuery Mobile controls.This allows mobile HTML5 web sites and hybrid applications to naturally integrate into the Windows Phone Metro style experience. This offers developers the choice of rapidly integrating the theme into their existing application but also to contribute to this open source project through GitHub.
You can see an extensive demo of the theme on this page and you can learn more on this site where we are publishing new articles, references and source code sample for developing with Apache Cordova and the Metro style theme for jQuery Mobile.
This is another milestone in our continuous engagement with the community. Our team has been working closely with the Windows Phone division to support the mobile HTML5 and JavaScript open source communities over the last year to bring popular open source projects to Windows Phone:
- A few months ago, we sponsored the development of full Windows Phone support for PhoneGap (now Apache Cordova), the open source framework that lets applications be built for iOS, Android, Windows Phone and other mobile platforms using HTML5, CSS and JavaScript.
- At the same time significant improvements were brought to jQuery Mobile (read more about this in our previous blog post): feedback from the community has been great and was partly responsible for our decision to expand our engagement with jQuery Mobile and sponsor this work.
We believe it is important for developers to have choices when targeting Windows Phone, and we also want them to be able to deliver a good experience to the users of their applications, especially when making the choice of using Web standards (HTML5, CSS and JavaScript) to target multiple mobile platforms by picking solutions such as Apache Cordova.
To do so, developers already enjoy a selection of Apache Cordova Plugins that give their application a Windows Phone touch such as Social Share, Bing Map launcher and Live Tile. Now developers can use the new open source Metro style theme for jQuery Mobile to give their mobile apps and websites the Metro style look and feel, and offer the final users an experience similar to the one they get with native applications.
As usual we are very interested in hearing from developers and gathering feedback about the experience of developing HTML5-based applications and websites on Windows Phone. Let us know what other features, tools and frameworks you’d like to see.
Abu Obeida Bakhach
Program Manager
Microsoft Open Technologies, Inc.
A subsidiary of Microsoft Corporation
Posted on April 30, 2012 | Author: Amir Nathoo | Share this post:
Last week we showed a screencast of Trigger.io Forge in action, this week we’ll explain how you can use a native top bar and native tab bar along with your HTML / CSS and JavaScript in a hybrid app created with Trigger.io.
We’ll add more native UI components in the future, but here’s how you can get started creating a beautiful, responsive mobile apps for iOS and Android using just web technologies.
These are screenshots of a simple recipe app that we created using the Trigger.io Forge native UI components, and we’ll explain how we built it. Along the way we’ll show you how to:
- Configure Trigger.io Forge to add native top bar and tab bar elements to your app
- Style the native elements
- Add listeners to and control the native elements from JavaScript
Please feel free to base your own projects on this – it’s a great springboard for a new project! The code is hosted on github here: https://github.com/trigger-corp/forge-template-list-and-detail
Create your app and add a top bar
You’ll need to use the Trigger.io Forge framework to be able to get native UI components using only web technologies. Get started by signing-up. There’s complete documentation on how to get setup and once you’ve done that just run:
forge createYou’ll be prompted for the app name and once the command completes, you’ll be setup with the code for a ‘Hello World’ app in the src subdirectory. Let’s start by adding a native top bar and testing that in the Android emulator.
Replace your existing src/config.json with this:
{ "author": "amir@trigger.io", "config_version": "2", "description": "View ingredients for your favorite recipes", "modules": { "is": true, "logging": { "level": "INFO" }, "prefs": true, "request": { "permissions": [] }, "tools": true, "topbar": true }, "name": "Recipe list", "platform_version": "v1.3", "version": "0.1" }Enabling the topbar is as simple as setting: “topbar”: true in the modules configuration. Let’s also clean-up index.html until we’re ready to customize it:
<!DOCTYPE html> <html> <head> </head> <body> <div class="content"> Hello world! </div> </body> </html>You can then run and test the app so far using the following forge commands:
forge build forge run android --android.sdk ~/Desktop/android-sdk-macosxAny problems at this point? Check out our FAQ, ask the community on StackOverflow or contact support@trigger.io.
Configuring a tab bar
Great! It turns out that adding the tab bar at the bottom is just as easy – you simply enable the module by adding “tabbar”: true to the src/config.json:
{ "author": "amir@trigger.io", "config_version": "2", "description": "View ingredients for your favorite recipes", "modules": { "is": true, "logging": { "level": "INFO" }, "prefs": true, "request": { "permissions": [] }, "tools": true, "topbar": true, "tabbar": true }, "name": "Recipe list", "platform_version": "v1.3", "version": "0.1" }But before that will look good and behave well we need to add some buttons and listeners so we can execute JavaScript to handle the page transitions when you click on each tab. To do that, let’s add a JavaScript file called src/js/main.js:
// A helper function so that when we change tab the web view scrolls to the top of the new page var scrollTop = function () { setTimeout(function () { document.body.scrollTop = 0; }, 0); } // This is the method we are going to call when a tab button is pressed var updateRecipes = function (search) { scrollTop(); // For now just pop up a message with the tab which was pressed alert(search); } // Set a better title for the topbar forge.topbar.setTitle("Recipe shopping list"); // Add our 3 tab buttons to the tabbar and add press listeners var starterButton = forge.tabbar.addButton({ text: "Starters", icon: "img/tomato.png", index: 0 }, function (button) { button.onPressed.addListener(function () { updateRecipes("starter"); }); // This is the default button, activate it immediately button.setActive(); updateRecipes("starter"); }); var mainButton = forge.tabbar.addButton({ text: "Mains", icon: "img/pizza.png", index: 1 }, function (button) { button.onPressed.addListener(function () { updateRecipes("main"); }); }); var dessertButton = forge.tabbar.addButton({ text: "Desserts", icon: "img/strawberry.png", index: 2 }, function (button) { button.onPressed.addListener(function () { updateRecipes("dessert"); }); });Here we’ve using the forge.topbbar.setTitle API call to alter the title at the top, and then used forge.tabbar.addButton to configure the tab bar buttons including adding a listener to execute JavaScript when they are pressed. We reference this file from src/index.html:
<!DOCTYPE html> <html> <head> <script src="js/main.js"></script> </head> <body> <div class="content"> Hello world! </div> </body> </html>You can find the images referenced in src/js/main.js in the example code in Github. You’ll also need to copy those across to your src/img directory.
Now if we build and test (this time on iOS), we see this:
Creating list views and controlling navigation
Ok, now we have the native UI elements in place, we need to create our list view and connect up the tabs so they trigger transitions.
We’ll use the lightweight zepto.js library to help us handle the DOM manipulation. We’ve blogged before on how to create fast HTML5 mobile apps using zepto.js and backbone.js. We’ll create the recipe list using HTML / CSS / JavaScript in the main part of the view since it’s simple to create good-looking lists this way.
First, let’s embed the recipe data and the zepto.js library. You can do that by downloading data.js and zepto.js from the example in Github and putting them in your src/js directory.
Then we update the updateRecipe function in src/js/main.js – this is called when a tab bar button is pressed:
var updateRecipes = function (search) { scrollTop(); $('.content').html('<ul class="list"></ul>'); $.each(data[search], function (i, recipe) { var el = $('<li><img src="'+recipe.thumb+'">'+recipe.title+'</li>'); el.on('click', function () { scrollTop(); $('.content').html('<div class="recipe"><h3>'+recipe.title+'</h3><img src="'+recipe.img+'"><ul class="ingredients"></ul><p><a href="#" onclick="forge.tabs.open(\''+recipe.source+'\')">View full recipe</a></p></div>'); $.each(recipe.ingredients, function (i, ingredient) { $('.ingredients').append('<li>'+ingredient+'</li>'); }); forge.tabbar.setInactive(); }); $('.list').append(el); }); }Now to complete the app, all we need to do is add some simple styling to the list and reference the JavaScript files in src/index.html:
<!DOCTYPE html> <html> <head> <style> body, html, li, ul { padding: 0; margin: 0; } body { font-size: 1.2em; } .recipe { text-align: center; } .recipe img { max-width: 80%; } .recipe li { display: block; font-size: 0.9em; padding: 2px; } .list { margin: 0; padding: 0; } .list li { display: block; border-bottom: 1px solid #aaa; padding: 0; margin: 0; width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .list li img { height: 50px; width: 50px; padding: 2px 7px 2px 2px; vertical-align: middle } </style> <script src="js/zepto.js"></script> <script src="js/data.js"></script> <script src="js/main.js"></script> </head> <body> <div class="content"> </div> </body> </html>That’s it
You should now be able to build and test the app to look like the screenshots at the top of this post. As an optional extra, you can also explore different styling for the topbar and tabbar by trying out the following API calls:
So now you can create rich hybrid apps, using real native UI components using Trigger.io! Let us know your feedback and how you get on.
Any problems at any point? Check out our FAQ, ask the community on StackOverflow or contact support@trigger.io.