This post shows you how to make an app that has the following flow:
All your code must go into the
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.
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
Just like in Ruby, to instantiate an object of a class, you use the
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.
iOS provides the
Now for the
Now that you’ve typed out the stuff required, run the
- Enter text your name in an input field.
- Click a button and an alert box opens up to greet you.
Stuff you need to know
-
I’m assuming that you are comfortable with Ruby.
-
RubyMotion doesn’t support
require
autoload
define_method
-
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
- UIWindow
- UITextField
- UIButton
- UIAlertView
-
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 in code-commentary style, so read the code too.
Here’s how we do it
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
command 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.AppDelegate
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
This the order of elements in the iOS UI.
UIScreen (the screen)
|
|__UIWindow (the window)
|
|__UIViewController
|
|__UIView (generally UI elements)
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
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 Class.alloc.init
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
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.MainViewController
Now for the
MainViewController
, create the file app/main_view_conroller.rb
.# 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 #{@input_field.text}",
delegate: nil,
cancelButtonTitle: "ok",
otherButtonTitles:nil)
# Show it to the user
@alert_box.show
end
end
Run the app
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.