iOS development using RubyMotion

It's not likely that I'll use this "thoughts" section for much else, so I figured a journal chronicling what I'm learning about iOS development using RubyMotion might me remember things easier, and give me a reason to plow ahead.

I've tried writing apps for iOS a few times before, but it's never felt right to me. Hopefully this time around it sticks!

Booting up

When an iOS application starts, it needs at the very minimum a UIWindow object, but you immediately need a UIViewController if you're gonna get any real work done. When you create a new RubyMotion application, those are the first things you add to the AppDelegate that gets generated:

class AppDelegate
  def application(application, didFinishLaunchingWithOptions:launch_options)
    # add this code:
    @window = UIWindow.alloc.initWithFrame(UIScreen.mainScreen.bounds)
    @window.backgroundColor = UIColor.grayColor
    @window.rootViewController = MyApplicationController.alloc.init
    # as long as my_application_controller.rb is in the app/ folder, it will
    # already be available, no need to require it
    #
    # take up the whole screen
    @window.rootViewController.wantsFullScreenLayout = true

    # show the window
    @window.makeKeyAndVisible

    # dim the status bar
    application.setStatusBarStyle(UIStatusBarStyleBlackTranslucent)

    # return true to indicate this AppDelegate responded to this method
    true
  end
end

Neat. Next, the MyApplicationController, which extends UIViewController, will get a few methods called on it, notably viewDidLoad, where you can add subviews to the view (the view gets created in loadView, in case you want to mess with the root view creation).

class MyApplicationController < UIViewController
  def viewDidLoad
    # fun stuff here in a sec...
  end
end

Let's put code in there that does stuff. RubyMotion prefers to eschews the traditional Xcode way of creating interfaces using Interface Builder. Instead, you create them programmatically.

These UIKit views are very verbose stuff, with lots of options, lots of things I don't know! So I'll just throw some labels and buttons in there.

class MyApplicationController < UIViewController

  def viewDidLoad
    left = 20
    top = 40
    colors = {
      10 => UIColor.grayColor,
      20 => UIColor.blackColor,
      30 => UIColor.blueColor,
      40 => UIColor.greenColor,
    }
    @labels = []

    [10, 20, 30, 40].each {|size|
      label = UILabel.new  # calls alloc and init (?)
      label.font = UIFont.systemFontOfSize(size)
      label.text = "Label of size #{size}"
      label.textColor = colors[size]
      label.frame = [[left, top], [view.frame.size.width - left * 2, size + 10]]
      view.addSubview(label)
      top += size + 10
      @labels.push label
    }

    @label_index = 0
    @label = @labels[0]

    @button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
    @button.setTitle('Do Something', forState:UIControlStateNormal)
    @button.addTarget(self, action:'actionTapped',
                            forControlEvents:UIControlEventTouchUpInside)
    @button.frame = [[left, top], [view.frame.size.width - left * 2, 40]]
    view.addSubview(@button)
  end

  def actionTapped
    @label.text = 'Good job!'
    @label_index = (@label_index + 1) % @labels.length
    @label = @labels[@label_index]
  end

end

That's it, that's what I got. Plan for next thought: UIImageView and maybe a UITableView.

  • good_job.png

    Screenshot of my first foray into rubymotion development