Chapter 7. Interface Builder and WebView – More Goodies!

"Time is precious; waste it wisely."

Anonymous

In this chapter we will learn about some features of iOS development with RubyMotion. Xcode is a very advanced IDE and has many qualities, which we can exploit to develop faster and better iOS applications. In this chapter we will also learn how to use an Interface Builder for rapid development with RubyMotion. We will also have a look at some key elements of Xcode, such as .xib, .nib, and WebView, to create real-life interactive apps.

Interface Builder

Xcode's Interface Builder allows you to create your application's user interface visually, instead of writing code. Interface Builder is a great tool that is very simple to use and is pivotal in making iOS development really fast. Therefore, the Interface Builder used along with RubyMotion further reduces development time. We can say these are two delicious recipes independently, but when used together, it's the ultimate formula to make beautiful iOS apps as quickly as possible.

Interface Builder comes with Xcode. Before we jump into using Interface Builder, it's important to understand that although Interface Builder creates the UI using the drag-and-drop mechanism, it is however not creating the Objective-C code behind the scene. It's creating an XML description of the GUI you're building, and the Cocoa Touch framework uses that XML to actually create the UI elements, such as label and textbox, for your application at runtime. Everything we do in Interface Builder could be done by writing lines of Ruby code—that's exactly what we have been doing from the beginning of this book—but shortly you will see how things get really easy with a GUI builder.

Note

XCode uses XML only for the editing stage, which is then compiled to nibs. Cocoa Touch never sees the XML source.

Before we begin using Interface Builder, let's understand some jargon associated with XCode development. The GUI builder provides options to drag-and-drop buttons, table views, and text fields into your app window. The resulting interface is stored as a .xib file. A .xib file is an XML representation of your objects and their instance variables, and it is compiled into a .nib file when your application is built. The .xib file is easier to work with but the .nib file is smaller and easier to parse, that's why the file that actually ships with your application is a .nib file.

Tip

The .nib file is short for NeXT Interface Builder.

Let's try the Interface Builder

So far we have created the views for our Restro application views by writing code in Ruby. In this section, let's create a view using the GUI-based Interface Builder. We will create a Contact Us form and use it in our application.

The Interface Builder is integrated into Xcode, which is a one stop IDE for any Apple-related development, whether it's for iOS devices or Mac. We will create a .xib file and then use this file in our RubyMotion project by performing the following steps:

  1. Open Xcode and click on Create a new Xcode Project.
    Let's try the Interface Builder
  2. Click on Single View Application, as we need only one .xib file.
    Let's try the Interface Builder
  3. Enter this data in the project-creation wizard. Notice that we have selected the device as iPhone. We can also see the other options, such as iPad and Universal. If you want to create a single application to be used on both iPhone and iPad, use the Universal option from the drop-down list. Also, unselect the Use Storyboards option.
    Let's try the Interface Builder
  4. Save the project in a folder of your choice; your project will then be loaded in XCode. Click on ViewController.xib and you will be able to see the Interface Builder.
    Let's try the Interface Builder

The Interface Builder has a fairly simple layout; it consists of four main windows:

  • View
  • Library
  • Document browser
  • Inspector

The View window is where you construct your interface. You will drag-and-drop items from the Library window onto the View window to place them. The document browser allows you to browse hierarchically the elements you have placed in your .nib file. Finally, the Inspector window shows you all of the different attributes of the selected element and allows you to edit them.

And now the magic begins; drag Navigation Bar from Library to view the section as shown in the following image:

Let's try the Interface Builder

When you select Navigation Bar, you will see many properties in the Inspector window. Change the tag value to 1 in the Inspector window. Remember that we will use this tag value in the RubyMotion project code. We need to wire our View Controller elements. The easiest way to do this is to use its Tag attribute. Tag is an integer property of the UIView class that you can use to identify your views. Basically, you have to set a unique integer for each UIView class you need to access from your UIViewController element.

Let's try the Interface Builder

Similarly, add a text field for e-mail and change the value for the placeholder to Email as shown in the following screenshot. There are a lot of properties associated with every Library object; for example, in case of a text field, we have changed the keyboard value to Email as it suits our requirement; but you are free to go ahead and play with other properties too. Using Email will show a keyboard customized for entering e-mail addresses.

Let's try the Interface Builder

Next, we need a button. Let's drag-and-drop a button onto the View window.

Let's try the Interface Builder

.xib to RubyMotion

In this section, we will import our .xib file into our RubyMotion project. Open the folder of the Xcode project and locate ViewController.xib. It's inside a folder named en.lproj; copy it into the resources folder of your Restro application, which we created in the last chapter.

Update the about_controller.rb file in the restro app, which we created in the last chapter, with the following code:

def setupNavigationBar
  back= UIBarButtonItem.alloc.initWithTitle("Back", style:UIBarButtonItemStylePlain,target:nil ,action:nil)
  self.navigationItem.backBarButtonItem = back;
  contact_us_button = UIBarButtonItem.alloc.initWithTitle("Contact Us", style:UIBarButtonItemStylePlain ,target:self, action:"contact_us")
  self.navigationItem.rightBarButtonItem = contact_us_button
end
def contact_us
  contact_us_controller = ContactUsController.alloc.initWithNibName("ViewController", bundle:nil)
  presentModalViewController(contact_us_controller, animated:true)
end

As we have imported the .xib file from Xcode to the RubyMotion project, RubyMotion creates a .nib file automatically when we build the code with the Rake command. Here, we are creating a View Controller variable with an initializer initWithNibName that receives a parameter, which will be the name of the .nib file. This initializer has the responsibility of instantiating the .nib file and wiring the View declared in the view property of the View Controller variable.

Create a file contact_us_controller.rb inside the app folder as follows:

class ContactUsController < UIViewController
end

Let's fire up the terminal and run the application with the following command:

$rake

The following screenshot shows the output of the preceding command:

.xib to RubyMotion

Next, let's update contact_us_controller.rb with the following code:

class ContactUsController < UIViewController
  HEADER_TAG = 1
  EMAIL_BOX_TAG = 2
  INFORMATION_BOX_TAG = 3
  SUBMIT_BUTTON_TAG = 4
  def viewDidLoad
    @header = self.view.viewWithTag(HEADER_TAG)
    @email_box = self.view.viewWithTag(EMAIL_BOX_TAG)
    @information_box = self.view.viewWithTag(INFORMATION_BOX_TAG)
    @submit_button = self.view.viewWithTag(SUBMIT_BUTTON_TAG)
    @submit_button.addTarget(self,
            action:"send_message", forControlEvents:UIControlEventTouchUpInside) 
    tapGesture = UITapGestureRecognizer.alloc.initWithTarget(self,
action:"hideKeyboard")
    tapGesture.cancelsTouchesInView = false
    view.addGestureRecognizer(tapGesture)
  end 
  
  def send_message
    if form_valid?
      puts "Submitted the button with correct values"
      close
    else
      puts "Invalid Values"
    end
  end
  def close
    dismissModalViewControllerAnimated true
  end 

  #method to hide keyboard when user taps on a scrollview
def hideKeyboard
    @information_box.resignFirstResponder
end

def form_valid?
  not @email_box.text.empty? and not @information_box.text.empty? and not @email_box.text.match(/A([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})/i).nil?
end
end

Let's start the application by using the following command:

$rake

Enter a few incorrect values in the form and you will get Invalid value printed on the terminal. Once you enter the values correctly in the form and submit it, it will be pulled down.

.xib to RubyMotion

Now let's understand the code. First we have assigned the tags to the attributes that we had created in Interface Builder. And then we have used these tags to wire our variables to those components.

self.view.viewWithTag(HEADER_TAG)

The preceding command will retrieve a subview of self.view based on its tag.

We have also created an action item for the Submit button. That means when we click on the Submit button, it will call the action send_message.

    @submit_button.addTarget(self,
      action:"send_message", forControlEvents:UIControlEventTouchUpInside)

In the send_message action, we are checking whether the form is valid or not.

Some developers like to design the user interface using Interface Builder; others prefer to work entirely with code. One of the reasons is that when connecting Interface Builder outlets and actions to your code, it is easy to make a mistake. This often results in an error that is more difficult to debug than if you had simply written the entire code, as you have to debug in two places (Interface Builder and your code) instead of just one (the code).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.17.28