Open Shelf…

Text Entry in BackRow

Potentially one of the most useful features of the AppleTV to plugin authors is its text-entry subsystem. While the Apple Remote is not an ideal tool for the job, there are often occasions where text entry of some kind is useful, such as entering a URL, a password, the address of an AFP server from which to collect content.

As it turns out, basic text entry is actually very simple to implement. In today’s tutorial, we will create a simple layer controller class which allows you to change its title.

Sample code for this tutorial Download the sample code for this tutorial

The BRTextEntryControl Class

The text entry control itself is very programmer-friendly, in that it provides literally everything you need to set one up with the minimum of hassle, as shown in this excerpt from the header file:

- (id) initWithScene: (BRRenderScene *) scene;
- (id) initWithScene: (BRRenderScene *) scene
        hexInputOnly: (BOOL) hexOnly;
- (void) setFrameFromScreenSize: (NSSize) size;
- (void) setTextFieldLabel: (NSString *) str;
- (void) setTextEntryCompleteDelegate: (id<BRTextEntryDelegate>) delegate;
- (void) setInitialText: (NSString *) str;

Generally, unless you want to restrict the entry control to a specific (smaller than usual) part of the screen, it’s best to just use -setFrameFromScreenSize: to place the control onscreen. The text field label is the prompt before the text field itself, the initial text is the current content, which can be deleted or amended. The delegate will normally be the object creating the text field, but of course that isn’t a necessity.

The BRTextEntryDelegate protocol referenced above shows the functions the delegate is expected to implement:

- (void) textDidChange: (id<BRTextContainer>) sender;
- (void) textDidEndEditing: (id<BRTextContainer>) sender;

…and the BRTextContainer protocol defines only one method:

- (NSString *) stringValue;

This is the method you’ll use to fetch the changing or changed string.

Design

We’re going to have a very basic interface for our controller this time. There will be a header at the top of the screen, and a button at the bottom. When the button is activated, it will be replaced by the text entry control. The user will then be able to enter a new title, and when the click ‘Done’ the text entry control will be replaced by the button again, and the new title will be set.

This gives us our list of required member variables:

@interface AQTextEntryTestController : BRLayerController <BRTextEntryDelegate>
{
    BRHeaderControl *       _header;
    BRTextEntryControl *    _entry;
    BRButtonControl *       _button;
}

We’re going to need the ability to add and remove controls from ourselves (there is sadly no -removeControl: method in BRLayerController, meaning we’ll have to implement it ourselves), so that only the chosen ones can handle events. We will also want to use a transition animation — a crossfade, in this case. Since these functions will need to be performed both from the button press and from the end of text editing, it makes sense to put these into their own methods:

- (void) removeControl: (BRControl *) control;
- (void) fadeFrom: (BRControl *) from to: (BRControl *) to;

We will have to implement a callback for our button control:

- (void) editTitle;

And we will need to implement the functions from the BRTextEntryDelegate protocol above:

- (void) textDidChange: (id<BRTextContainer>) sender;
- (void) textDidEndEditing: (id<BRTextContainer>) sender;

The only thing left now is the implementation.

No Responses

Note that comments are displayed in reverse chronological order with topmost comments being freshest. Subscribe | Comment

Leave a Reply

You must be logged in to post a comment.