There are several parts to implementing the view controller. You need to deal with the instance variables—including memory management—implement the changeGreeting:
method, and ensure that the keyboard is dismissed when the user taps Done.
You first need to tell the compiler to synthesize the accessor methods.
>> In the MyViewController.m
file, add the following after the @implementation MyViewController
line:
@synthesize textField; |
@synthesize label; |
@synthesize string; |
This tells the compiler to synthesize accessor methods for these properties according to the specification you gave in the interface file. For example, the declaration of the string
property is @property (nonatomic, copy) NSString *string;
), so the compiler generates two accessor methods: - (NSString *)string
and - (void)setString:(NSString *)newString
. In the setString:
method a copy is made of the string that’s passed in. This is useful to ensure encapsulation (the passed-in string might be mutable—you want to make sure that the controller maintains its own copy). For more about encapsulation, see “Mechanisms Of Abstraction” in Object-Oriented Programming with Objective-C.
You must relinquish ownership in the dealloc
method because all of the property declarations specify that the view controller owns the instance variables (retain
and copy
imply ownership, see “Memory Management Rules” in Memory Management Programming Guide).
>> In the MyViewController.m
file, update the dealloc
method to release the instance variables before invoking super’s implementation:
- (void)dealloc { |
[textField release]; |
[label release]; |
[string release]; |
[super dealloc]; |
} |
When it’s tapped, the button sends a changeGreeting:
message to the view controller. The view controller then should retrieve the string from the text field and update the label appropriately.
>> In the MyViewController.m
file, complete the implementation of the changeGreeting:
method as follows:
- (IBAction)changeGreeting:(id)sender { |
self.string = textField.text; |
NSString *nameString = string; |
if ([nameString length] == 0) { |
nameString = @"World"; |
} |
NSString *greeting = [[NSString alloc] initWithFormat:@"Hello, %@!", nameString]; |
label.text = greeting; |
[greeting release]; |
} |
There are several pieces to this method.
self.string = textField.text;
This retrieves the text from the text field and sets the controller’s string
instance variable to the result.
In this case, you don’t actually use the string instance variable anywhere else, but it’s important to understand its role. It’s the very simple model object that the view controller is managing. In general, the controller should maintain information about application data in its own model objects—application data shouldn’t be stored in user interface elements.
@"World"
is a string constant represented by an instance of NSString
.
The initWithFormat:
method creates a new string that follows the format specified by the format string, like the printf
function. %@
indicates that a string object should be substituted. To learn more about strings, see String Programming Guide.
If you build and run the application, you should find that if you tap the button, the label shows “Hello, World!” If you select the text field and start typing, though, you should find that you have no way to indicate that you’ve finished entering text and dismiss the keyboard.
In an iOS application, the keyboard is shown automatically when an element that allows text entry becomes the first responder, and is dismissed automatically when the element loses first responder status. (You can learn more about first responder by reading “Event Handling” in iOS Application Programming Guide.) There’s no way to directly message the keyboard; you can, however, make it appear or disappear as a side-effect of toggling the first responder status of a text-entry element.
In this application, the text field becomes first responder—and so the keyboard appears—when the user taps in the text field. You want the keyboard to disappear when the user taps the Done button on the keyboard.
The UITextFieldDelegate
protocol includes a method, textFieldShouldReturn:
, that the text field calls whenever the user taps the Return button (whatever text the button shows). Because you set the view controller as the text field’s delegate (“Making Connections”), you can implement this method to force the text field to lose first responder status by sending it the resignFirstResponder
message—which has the side-effect of dismissing the keyboard.
>> In the MyViewController.m
file, implement the textFieldShouldReturn:
method as follows:
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField { |
if (theTextField == textField) { |
[textField resignFirstResponder]; |
} |
return YES; |
} |
In this application, it’s not really necessary to include the theTextField == textField
test since there’s only one text field. It’s worth pointing out the pattern, though, since there may be occasions when your object is the delegate of more than one object of the same type and you may need to differentiate between them.
>> Build and run the application; it should behave as you expect. (Tap Done to dismiss the keyboard when you have entered your name, then tap the Hello button to display “Hello, <Your Name>!” in the label.)
If the application doesn’t behave as you expect, you need to troubleshoot (see “Troubleshooting”).
You finished the implementation of the view controller and so completed your first iOS application. Congratulations.
Take a moment to think about how the view controller fits into the overall application architecture. You’re likely to use view controllers in most iOS applications you write.
Then take a break, and start to think about what you should do next.
Last updated: 2010-07-01