Although AIR for iOS offers access to the iOS virtual keyboard, you have limited control over the type of keyboard that appears. If you want additional keyboard configurations within your Flash project then you’ll need to build your own custom keyboard component. Although this will require some development effort it will allow you to tailor the user experience. For certain apps such as games, you may actually find a custom keyboard is the preferred option, as it will better fit your visual design.

Let’s see how to create one using Flash.

Flash iOS Apps CookbookThis tutorial is a previously unreleased recipe from Flash iOS Apps Cookbook and supplements the content found in Chapter 7, Working with Text and the Virtual Keyboard.
Flash iOS Apps Cookbook provides the recipes required to build native iOS apps using your existing knowledge of the Flash platform. Whether you want to create something new or simply convert an existing Flash project, the relevant steps and techniques are covered, helping you achieve your goal.

Getting Ready

An FLA has been provided as a starting point.

Download this recipe’s accompanying source bundle and open chapter7/recipe8/recipe.fla into Flash Professional.

The visuals for this application have already been created. Sitting on the stage is a virtual keyboard and a dynamic text field. The text field will be used to output what the user types.

The dynamic text field has been named field while the movie clip instance that represents the virtual keyboard has been named keyboard.

Entering a player's name with a custom virtual keyboard.

With the Selection tool (V) selected, double-click on the keyboard instance to examine its timeline. The keyboard contains 28 keys – 26 for the letters of the alphabet, an ok key for when the user is finished typing, and a del key to delete a character. You’ll find that each alphabetic key is represented by its own movie clip and that the instances are named a_key to z_key. This naming convention makes it easy to determine the letter that a key represents by simply examining the first character of its instance name. The remaining two keys have instance names of ok_key and del_key. Additionally there’s a movie clip named surface that sits beneath the keys and represents the keyboard’s body.

Double-click on any one of the keys to examine its timeline. Each is represented by two frames, where the second frame will be shown when the key is being pressed. The movie clip symbol for each key is linked to a class named Button, which was introduced in the Handling user interaction recipe from Chapter 4. Open Button.as and familiarize yourself with the code.

How to do it…

Perform the following steps.

  1. From Flash, select File | New and create a new ActionScript 3.0 class. Name it VirtualKeyboard.
  2. Add the following ActionScript to the class:
    package {
    	
      import flash.display.MovieClip;
      import flash.events.MouseEvent;
    	
      public class VirtualKeyboard extends MovieClip {
    		
        static private const keys:Array = [
          "a_key", "b_key", "c_key", "d_key", "e_key", "f_key", 
          "g_key", "h_key", "i_key", "j_key", "k_key", "l_key", 
          "m_key", "n_key", "o_key", "p_key", "q_key", "r_key",
          "s_key", "t_key", "u_key", "v_key", "w_key", "x_key",
          "y_key", "z_key", "ok_key", "del_key"
        ];
    		
        static public const KEY_ALPHABETIC:uint = 0;
        static public const KEY_DELETE    :uint = 1;
        static public const KEY_OK        :uint = 2;
    		
        private var _key:Object;
    		
        public function VirtualKeyboard() {
          mouseEnabled = false;
          surface.mouseEnabled = false;
          for(var i:uint = 0; i < keys.length; i++)
          {
            var key:Button = this[keys[i]];
            key.addEventListener(
              MouseEvent.MOUSE_UP, keyPressed);
            key.mouseChildren = false;
          }
        }
    		
        public function get key():Object {
          return _key;
        }
    		
        private function keyPressed(e:MouseEvent):void {
          var keyName:String = e.target.name;
          switch(keyName)
          {
            case "ok_key":
              _key = {type:KEY_OK};
              break;
    
            case "del_key":
              _key = {type:KEY_DELETE};
              break;
    
            default:
              var letter:String = keyName.charAt(0);
              _key = {type:KEY_ALPHABETIC, char:letter};
          }
    
          e.stopPropagation();
          dispatchEvent(e);
        }
      }
    }
    
  3. Save the class to the same location as your FLA and name it VirtualKeyboard.as.
  4. Move back to your FLA. Now you can link the class to your virtual keyboard's movie clip symbol. Within the library, right-click on the Keyboard symbol and select Properties. Click the Export for ActionScript checkbox. Enter VirtualKeyboard into the Class field. Click OK.
  5. Now we need some ActionScript that will populate the dynamic text field in response to the user interacting with the virtual keyboard. Create a document class and name it Main.
  6. For this class add the following ActionScript:
    package {
    
      import flash.display.MovieClip;
      import flash.events.MouseEvent;
    	
      public class Main extends MovieClip {
    		
        private const MAX_CHARS:uint = 10;
    		
        public function Main() {
          keyboard.addEventListener(
            MouseEvent.MOUSE_UP, keyPressed);
        }
    
        private function keyPressed(e:MouseEvent):void {
          var keyObj:Object = e.target.key;
          var keyType:uint = keyObj.type;
    
          switch(keyType)
          {
            case VirtualKeyboard.KEY_ALPHABETIC:
              if(field.text.length < MAX_CHARS)
              {
                field.appendText(e.target.key.char);
              }
              break;
    
            case VirtualKeyboard.KEY_DELETE:
              var text:String = field.text;
              field.text = text.substr(0, text.length - 1);
              break;
    
            case VirtualKeyboard.KEY_OK:
              keyboard.visible = false;
              break;
          }
        }
      }
    }
  7. Save the document class and name its file Main.as.
  8. Move back to the FLA and save it.
  9. That's us finished! Either test your FLA using ADL or deploy it to your device.

How it works...

Three simple classes were all that was needed to build your own custom virtual keyboard.

We won't go into the internals of Button.as since it was covered earlier in this book, but let's spend some time looking at both VirtualKeyboard.as and Main.as.

The VirtualKeyboard class is linked to the Keyboard symbol within your library and manages key presses. It does this by determining which movie clip was pressed before dispatching an event to any listeners.

The document class, Main.as, simply listens for this event and updates the dynamic text field to reflect the user's current input.

Let's move back to VirtualKeyboard.as within Flash Professional and take a closer look.

A constant named keys is declared within the class and holds within an array, the instance name of each key:

static private const keys :Array = [
  "a_key", "b_key", "c_key", "d_key", "e_key", "f_key", 
  "g_key", "h_key", "i_key", "j_key", "k_key", "l_key", 
  "m_key", "n_key", "o_key", "p_key", "q_key", "r_key", 		
  "s_key", "t_key", "u_key", "v_key", "w_key", "x_key",
  "y_key", "z_key", "ok_key", "del_key"
];

Within the class' constructor we make the keys interactive by simply looping through the keys array and attaching a MOUSE_UP event handler to each:

public function VirtualKeyboard() {
  mouseEnabled = false;
  surface.mouseEnabled = false;
  for(var i:int = 0; i < keys.length; i++)
  {
    var key:Button = this[keys[i]];
    key.addEventListener(
      MouseEvent.MOUSE_UP, keyPressed);
    key.mouseChildren = false;
  }
}

We receive this event when a user lifts their finger off a key, indicating a successful press. When this takes place, our keyPressed() handler is called and information regarding that key is created and stored. Here's the code for this again:

private function keyPressed(e:MouseEvent):void {
  var keyName :String = e.target.name;
  switch(keyName)
  {
    case "ok_key":
      _key = {type: KEY_OK};
      break;

    case "del_key":
      _key = {type: KEY_DELETE};
      break;

    default:
      var letter:String = keyName.charAt(0);
      _key = {type: KEY_ALPHABETIC, char: letter};
  }

  e.stopPropagation();
  dispatchEvent(e);
}

The handler checks the name of the movie clip instance that was pressed, and from the name determines which of the following key types it represents:

  1. The okay key.
  2. The delete key.
  3. An alphabetic key.

The type of key is stored within the _key member variable, and if the key represents a letter from the alphabet then its character is stored too. The class also provides a public getter method named key, which provides access to this information. We'll see the key property being accessed from the document class in a moment. Finally a MOUSE_UP event is dispatched to any listeners.

Okay, now take a look at Main.as again.

It simply listens for the keyboard movie clip dispatching a MOUSE_UP event. This event will only be dispatched if the user has successfully pressed one of the virtual keyboard's keys. You can see the event listener being added below:

public function Main() {
  keyboard.addEventListener(
    MouseEvent.MOUSE_UP, keyPressed);
}

Then within the keyPressed() event handler, we simply update the dynamic text field - field - in response to each of the user's key presses. Here's the method again as a reminder:

private function keyPressed(e:MouseEvent):void {
  var keyObj :Object = e.target.key;
  var keyType:uint = keyObj.type;	

  switch(keyType)
  {
    case VirtualKeyboard.KEY_ALPHABETIC:
      if(field.text.length < MAX_CHARS)
      {
        field.appendText(e.target.key.char);
      }
      break;

    case VirtualKeyboard.KEY_DELETE:
      var text:String = field.text;
      field.text = text.substr(0, text.length - 1);
      break;
			
    case VirtualKeyboard.KEY_OK:
      keyboard.visible = false;
      break;
  }
}

The handler calls the virtual keyboard's key property to determine which of the three types the pressed key belongs to. If it's an alphabetic key then the letter it represents is appending to the dynamic text field. If the user presses the del key then the last character is removed from the text field. Finally, if it was the ok key then the keyboard is simply hidden from view.

Building your own custom keyboard can create a more engaging experience for the user and provide consistency with your app's user interface. However if the native iOS keyboard that's available to you is sufficient then consider using it, as it's familiar and understood by all iOS users.

See also

  1. Thanks Christopher

    I’ve found your blog recently, looking for an iOS content scroll and now, I’m a fan. I’m really interested in your book “Flash iOS Apps Cookbook”, cause I finished my “AS3 Practical Manual” book last year, but for some publishing problems and also unfamiliarity of programmers in my country with flash platform, it wasn’t successful.

    Have fun

  2. this is my next project.

    im so glad I found your site, otherwise I would still be stuck in the mire of head scratching and hair pulling.

    rob