This post shows you how to make an app that has the following flow:
Here’s a video of it
I’m assuming that you are comfortable with Ruby.
and a few more. So most of your rubygems turnout to be useless, unless you hack them bit.
UI elements in iOS have a frame. Think of it as the frame for a photograph on your wall. When you create elements, you have to specify the frame, in the following format:
[[x, y], [width, height]]
You’ll be using the following UI elements
iOS documentation is available here - http://developer.apple.com/library/ios/navigation/
Don’t hesitate to copy-paste code to try out things. That is exactly why code snippets are for. Go even further and make your own modifications.
I learnt RubyMotion a few hours before making this app and have never written an iOS app as of this blog post. So if you find something can be done in a better way, share your suggestions.
This post is a bit lengthy because of the basics. So just hang on and the pastures on your side will turn green. Let’s create a new application using the
$ motion create click_to_greet Create click_to_greet Create click_to_greet/.gitignore Create click_to_greet/Rakefile Create click_to_greet/app Create click_to_greet/app/app_delegate.rb Create click_to_greet/resources Create click_to_greet/spec Create click_to_greet/spec/main_spec.rb
cd into the
click-to-greet directory. All relative paths mentioned from now on will be relative to this directory.
All your code must go into the
app directory. This is how your
app/app_delegate.rb looks like when your app is first generated:
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) true end end
The pattern is similar to the MVC pattern. And this app_delegate.rb is like the Rails routes file. It’s used to set the root controller for your application.
This the order of elements in the iOS UI.
UIScreen (the screen) | |__UIWindow (the window) | |__UIViewController | |__UIView (generally UI elements)
First, create a window for the application. And also set the root controller for it. Right now it’s just some class name and we’ll call it
MainViewControler. So your
app_delegate.rb should look like the following.
class AppDelegate def application(application, didFinishLaunchingWithOptions:launchOptions) # Get the frame for the window @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds) # Instantiate a new object of the MainViewController # and assign it as the root controller. @window.rootViewController = MainViewController.new # This makes the window a receiver of events (for now we are using touch). @window.makeKeyAndVisible # Because this method must return true true end end
Just like in Ruby, to instantiate an object of a class, you use the
Class.new method. In iOS, you have to allocate memory to the object first and then initiate it. In RubyMotion, the
Class.new method does the same as
iOS provides some helper class methods that allows you to do some tasks in a shorter way. So instead of instantiating an object and then assigning a frame to it like below.
@window = UIWindow.new @window.frame = UIScreen.mainScreen.bounds
iOS provides the
initWithFrame on UI elements. But this must be used with the alloc method, which is why you see:
@window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
UIScreen.mainScreen.bounds returns the frame, that the main screen provides for applications.
Now for the
MainViewController, create the file
# You have to inherit from UIViewController class MainViewController < UIViewController # Called to load the view # This is where you instantiate your view and set it as the controller's view. def loadView # Set the view for the controller # We don't need anything special for now. So we'll directly instantiate an object of UIView self.view = UIView.new end # Called after the view is loaded def viewDidLoad # A text input field instantiated with initWithFrame @input_field = UITextField.alloc.initWithFrame([[0, 0], [200, 40]]) # Set the text color using the UIColor class which offers named colors @input_field.textColor = UIColor.blackColor # Set the background color for the text field @input_field.backgroundColor = UIColor.whiteColor # Set the border style of the text field to rounded rectangle # We need a rounded border, defined by the constant UITextBorderStyleRoundedRect @input_field.setBorderStyle UITextBorderStyleRoundedRect # Add the text field to the controller's view self.view.addSubview @input_field # Initiate button with button type @action_button = UIButton.buttonWithType UIButtonTypeRoundedRect # Set the title for the default UI state, which is normal # Normal UI state is defined by the constant UIControlStateNormal @action_button.setTitle "Greet me", forState: UIControlStateNormal # Set the frame for the button @action_button.frame = [[100, 100], [100, 50]] # Add an event for the button when touched # 'self' refers to the handler class for the action in which the callback is defined # greet_user is the method is that'll be called when the event happens # The touch state is defined by the constant UIControlEventTouchUpInside @action_button.addTarget(self, action: :greet_user, forControlEvents: UIControlEventTouchUpInside) # Add the button to the view self.view.addSubview @action_button end # The touch callback for the button def greet_user # Instantiate an alert box with the title and a greeting message # And a text for the cancel button # Which will say "ok" # The arguments from the second to last, are not Ruby hash arguments # They are Objective-C style arguments. # You can't randomize the order or skip them if they are nil @alert_box = UIAlertView.alloc.initWithTitle("Greeting", message:"Hi [email protected]_field.text}", delegate: nil, cancelButtonTitle: "ok", otherButtonTitles:nil) # Show it to the user @alert_box.show end end
Now that you’ve typed out the stuff required, run the
rake command in the project’s directory. The iOS simulator should popup and showcase your app in all glory.