-
15 May
Introducing ProMotion, a Full-Featured RubyMotion Application Framework
(This is a guest post from Jamon Holmgren, creator and maintainer of ProMotion)
Last August I started working on a new RubyMotion app. I quickly realized that one of UIKit’s most frequent pain points is working with
UINavigationControllers
,UITabBarControllers
, andUIViewControllers
— it just took too many lines of code to move around in my app. That led to the idea behind ProMotion: abstracting the screen and navigation handling in a Ruby-like way.It has been a great experience building it and I’m going to show you how ProMotion could make your next iOS project a lot easier (with lots of code examples!). The source is also available on GitHub.
Screens: Ruby-like UIViewControllersProMotion subclasses
UIViewController
andUITableViewController
to provide a ton of new functionality and abstraction and calls themProMotion::Screen
. (You can also use ProMotion with Formotion or your ownUIViewController
).Note: from now on I’ll refer to
ProMotion
by its shortcut alias,PM
.class HomeScreen < PM::Screen title "Home" end
Pretty simple. What about
viewWillAppear:animated
and other Obj-C methods? We implement simpler versions of those for your use:def on_init # Fires right after the screen is initialized end def on_load # Fires just before a screen is added to a view for the first time. end def will_appear # Fires every time the screen will appear end def on_appear # Fires just after the screen appears somewhere (after animations are complete) end def will_disappear # Fires just before the screen will disappear end def on_disappear # Fires after the screen is fully hidden end
Invisible UINavigationControllersWhen you create a screen you can pass in attributes. One of these is
nav_bar: true
which creates aUINavigationController
and pushes the screen onto it. You don’t have to manage the navigation controller at all.open HomeScreen.new(nav_bar: true)
Within that screen you can open other screens and they’ll be pushed onto the UINavigationController automatically.
open SecondaryScreen
If you pass in a class instead of an instance, ProMotion will instantiate it for you.
Easy TabBarControllersOpening and managing a
UITabBarController
is a pain in Objective-C. ProMotion makes it very simple and natural.class AppDelegate < PM::Delegate def on_load(app, options) open_tab_bar HomeScreen, AboutScreen, ContactScreen, HelpScreen end end # in app/screens/home_screen.rb class HomeScreen < PM::Screen def open_another_tab # Switches to the AboutScreen created above if its tab title is “About”. open_tab “About” end def open_new_screen_in_another_tab # Programmatically switches to the HelpScreen # and pushes the SecondaryScreen onto its UINavigationController. open SecondaryScreen, in_tab: “Help” end end
Smart SplitViewControllersSplit view controllers are as easy as tab bars.
open_split_screen MenuScreen, DetailScreen
From the left-hand part of the split screen it’s easy to open a child screen in the right. Just add
in_detail: true
to theopen
command:open SomeDetailScreen, in_detail: true
This is ignored if there isn’t a split screen so it’s ideal for use in universal apps.
Effortless Table ScreensYou can easily build list views (“tables”) in ProMotion. Formotion is excellent for building forms, but sometimes you just want a menu or list of information. That’s where ProMotion’s built-in
TableScreen
works well.class HelpScreen < PM::GroupedTableScreen title "Help" def table_data @help_table_data ||= [{ title: "Get Help", cells: [{ title: "Email us", action: :email_us }] }] end def email_us mailto_link = NSURL.URLWithString("mailto:jamon@clearsightstudio.com") UIApplication.sharedApplication.openURL(mailto_link) end end
When the Email us cell is tapped, ProMotion fires the
email_us
method.For plain tables, you can add
searchable
andrefreshable
easily:class StatesScreen < PM::TableScreen title “States” searchable refreshable def table_data # list of states end def on_refresh # refresh your data here, usually async some_async_call do # update your data stop_refreshing update_table_data end end end
Styling with StyleEverybody has their favorite iOS styling system and ProMotion works beautifully with all of them. Pixate, NUI, and of course RubyMotion’s Teacup are all very good choices.
For those who want a simple, Teacup-lite styling system, ProMotion comes with one built-in.
set_attributes self.view, background_color: UIColor.grayColor add UILabel.alloc.initWithFrame([[10, 10], [300, 45]]), text: “Welcome to ProMotion!”, resize: [ :left, :right, :top ], background_color: UIColor.clearColor, text_color: UIColor.whiteColor, shadow_color: UIColor.blackColor, number_of_lines: 0, text_alignment: UITextAlignmentCenter, font: UIFont.boldSystemFontOfSize(18.0)
This
Perfect for ProductionUILabel
is added to the view and all the attributes are set. Snake case is converted to camel case automatically when appropriate. There are also some nice helpers like theresize
setting forUIViewAutoresizingMasks
.ProMotion is already being used in production apps around the world and is becoming quite stable. It’s likely that version 1.0 will be coming soon without major changes to the API.
Without RubyMotion, it’s very unlikely that a system like ProMotion would exist. There’s nothing like it in the Objective-C world and the community is a lot different there. It’s a testament to the RubyMotion community as well as Laurent and his team for making this possible.
This is just an intro to ProMotion — head over to the GitHub repo to learn more. I hope you take a look at it for your next project!
Jamon Holmgren (@jamonholmgren) is the owner of ClearSight Studio, a mobile app and web development studio located near Portland, OR.