Using Text with Labels, Text Fields, and Combo Boxes
When a program can offer a limited range of valid options to the user, that’s when you want to use check boxes, radio buttons, date pickers, or sliders. However, sometimes a program needs to allow the user to type in data that can never be predicted ahead of time, such as a person’s name. When a program needs to allow the user to type in data, that’s when you need to use a text field or a combo box.
A text field lets the user type in anything he or she wants including numbers, unusual characters, or ordinary letters. That means a program needs to verify that the user typed in valid data.
Sometimes a program can offer the user both the option of choosing from a limited selection of valid options or typing in data instead. For example, a program might ask the user to choose a country. Then the program can offer a limited range of likely options or give the user the freedom to type something else.
This ability to either choose from a limited range of options or type something in is the main advantage of a combo box. The combo box gets its name because it combines the features of a pop-up button (displaying a list of valid options) with the freedom to type anything in (like a text field).
While text fields and combo boxes are used to accept data from the user, labels are used to display information to the user. When you just need to display information such as displaying instructions or identifying the purpose of a text field (such as telling a user to type a name or address), you’ll want to use a label. Together, labels, text fields, and combo boxes work to accept and display text on a user interface.
Using Text Fields
Since a user can type anything into a text field, a text field stores data as a string, which you can retrieve using the stringValue property. However, since users can type in integer or decimal numbers, a text field is versatile enough to recognize such numbers.
If the user types in an integer, you can retrieve that value by accessing the intValue property. If the user types in a decimal number, you can retrieve that value by accessing either the floatValue or doubleValue properties.
No matter what the user types into a text field, you can retrieve the proper value. Since text fields can accept strings or numbers, your program can retrieve the proper value by accessing one of the following properties:
Note When the user types text into a text field, that typed text gets stored in all four properties: intValue, floatValue, doubleValue, and stringValue.
Beyond the standard text field, Xcode offers several text field variations for handling different types of text entry:
A number formatter lets you define valid numeric values the user can type into the text box such as a minimum or maximum value, or a specific way to enter data such as with a % sign or by typing the number out as “four” instead of typing 4.
Xcode gives you two ways to create a text field with a number formatter. First, you can drag and drop the Text Field with Number Formatter from the Object Library and place it on your user interface. Second, you can drag and drop the Number Formatter from the Object Library and place it on an existing text field on your user interface.
To quickest way to find both of these items is to type “Number Formatter” in the search text field at the bottom of the Object Library as shown in Figure 17-1.
Figure 17-1. The Text Field with Number Formatter and Number Formatter in the Object Library
Whether you create a new text field with the Text Field with Number Formatter item or apply Number Formatter to an existing text field, you’ll need to define the number formatter settings. To do this, you need to follow several steps:
Figure 17-2. The Number Formatter appears in the Document Outline
Figure 17-3. The Show Attributes Inspector pane
The Minimum and Maximum check boxes let you define a minimum and/or maximum value that the text field will accept. If you define a minimum value of 10 and the user types in a number less than 10, the text field won’t accept the number.
The Localize check box tells Xcode to use the user’s local settings to determine the appearance of a decimal point and currency symbol. In some parts of the world, they use a period for a decimal point while in others they use a comma.
Likewise for currency, Europeans would use the Euro symbol, Americans would use the dollar symbol, and British users would use the British pound symbol. Selecting the Localize check box ensures that your text field number formatter works no matter what part of the world the program may be used.
The Style pop-up menu lets you define different ways to format numbers. When you choose a Style, the Unformatted and Formatted text fields under the Sample category shows you how your numbers may look.
For example, in Figure 17-3, choosing the None Style means that if the user types in 1,234.75 into a text field with a number formatter and presses Return, the text field formats that number as simply 1235.
However, if the Style is Currency, Percent, Scientific, or Spell Out, that means the user can enter a number as defined by the Formatted example, and the text field will store the number as shown in the Unformatted example.
To see how to use these different number formatters, follow these steps:
Figure 17-4. The user interface of the NumberProgram
Figure 17-5. Modifying a pop-up button
@IBOutlet weak var popUpChoice: NSPopUpButton!
@IBOutlet weak var textBox: NSTextField!
@IBOutlet weak var labelResult: NSTextField!
@IBOutlet weak var numberFormat: NSNumberFormatter!
@IBAction func showResults(sender: NSButton) {
if popUpChoice.titleOfSelectedItem! == "None" {
numberFormat.numberStyle = NSNumberFormatterStyle.NoStyle
} else if popUpChoice.titleOfSelectedItem! == "Decimal" {
numberFormat.numberStyle = NSNumberFormatterStyle.DecimalStyle
} else if popUpChoice.titleOfSelectedItem! == "Currency" {
numberFormat.numberStyle = NSNumberFormatterStyle.CurrencyStyle
} else if popUpChoice.titleOfSelectedItem! == "Percent" {
numberFormat.numberStyle = NSNumberFormatterStyle.PercentStyle
} else if popUpChoice.titleOfSelectedItem! == "Scientific" {
numberFormat.numberStyle = NSNumberFormatterStyle.ScientificStyle
} else if popUpChoice.titleOfSelectedItem! == "Spell Out" {
numberFormat.numberStyle = NSNumberFormatterStyle.SpellOutStyle
}
labelResult.stringValue = String(stringInterpolationSegment: textBox.doubleValue)
}
The above Swift code in the IBAction method uses the titleOfSelectedItem property to determine which option the user chose. Then it uses multiple if-else if statements to change the number Style property of the number formatter.
The pop-up button lets you choose different number formatting styles so you can see how they work when you type a formatted number into the text field. By choosing different formatting styles, you can see how the text field lets you type in differently formatted numbers such as 25% (which gets converted into 0.25) or 1.2E3 (which gets converted into 1200.0).
Using a Secure Text Field, a Search Field, and a Token Field
A secure text field simply hides text behind bullets when the user types. This can be handy for masking actual text such as passwords, credit card numbers, or other sensitive information from view. Beyond masking anything typed in, a secure text field works exactly like a regular text field where you can retrieve the value typed using the intValue, floatValue, doubleValue, or stringValue properties.
A search text field looks like a typical search field you might find in a browser that displays a magnifying glass icon and close icon that can delete the text in the search field with one click. Each time the user types something in the search field and presses Return, the search field stores the text as a list stored in the recentSearches property.
By accessing this recentSearches property, you can view a list of everything the user previously typed in that search field.
A token field lets you type text and then it encloses that text inside a token. Despite the appearance of tokens, you can still retrieve the text of a token field by accessing the stringValue property.
To see how to use a secure text field, a search field and a token field, follow these steps:
Figure 17-7. The user interface of the TextProgram
@IBOutlet weak var searchBox: NSSearchField!
@IBOutlet weak var historyBox: NSTextField!
@IBOutlet weak var tokenBox: NSTokenField!
@IBOutlet weak var tokenResult: NSTextField!
@IBOutlet weak var secureBox: NSSecureTextField!
@IBOutlet weak var secureResults: NSTextField!
@IBAction func showHistory(sender: NSButton) {
historyBox.stringValue = String(stringInterpolationSegment: searchBox.recentSearches)
}
@IBAction func showToken(sender: NSButton) {
tokenResult.stringValue = tokenBox.stringValue
}
@IBAction func showSecret(sender: NSButton) {
secureResults.stringValue = secureBox.stringValue
}
Figure 17-8. The results of the TextProgram
Although Search Fields, Token Fields, and Secure Text Fields look differently, they behave exactly like a text field when you need to access the values stored inside them.
Using Combo Boxes
A text field lets the user type in anything while a pop-up button displays a fixed range of options. When you want to display a fixed range of options and let the user type in text, that’s when you can use a combo box.
A combo box is based on the NSComboBox class, which is based on the NSTextField class that defines all text fields. As a result, you can retrieve values from a combo box using the intValue, floatValue, doubleValue, or stringValue properties.
When using a combo box, you have two ways to fill its pop-up list of options. First, you can create an internal list using the Show Attributes Inspector pane. Second, you can use an external data source so the combo box retrieves data from a database file or over the Internet.
An internal list is best when you know ahead of time exactly how many and which items you want to store in a combo box, such as a list of countries or product names. To create an internal list, follow these steps:
Figure 17-9. The Items list lets you define items to appear in a combo box
To edit an existing item in the list, click on that item to select it and press Return. Now you can edit the text.
To remove an existing item, click on that item to select it and click the minus sign icon.
To add a new item, click on the plus sign icon. Then click on the newly added item, press Return, and edit the text.
The Visible Items text field defines how many items the combo box menu displays.
The Autocompletes check box lets the combo box displays items in its list that matches what the user started to type in. So if the user types one letter, autocomplete displays a list of all items in the combo box list that begins with the same letter the user typed.
The Uses Data Source check box determines if the combo box uses its internal Items list to display menu items, or retrieves data from another source. If the Uses Data Source check box is selected, then you’ll need to write Swift code to fill a combo box with data.
To see how to fill a combo box using an internal list, follow these steps:
Figure 17-10. The user interface of the ComboProgram
@IBOutlet weak var myCombo: NSComboBox!
@IBOutlet weak var comboResult: NSTextField!
@IBAction func showResult(sender: NSButton) {
comboResult.stringValue = myCombo.stringValue
}
This example used the default item list for the combo box. Experiment by adding or modifying this combo box item list and select the Autocompletes check box to see how these options modify the combo box.
A data source is best when a combo box needs to display data that may change over time, such as displaying a list of information from a database. To use a data source, you need to write Swift code. First, you need to adopt the NSComboBoxDataSource protocol in a class like this:
class AppDelegate: NSObject, NSApplicationDelegate, NSComboBoxDataSource {
Next, you need to write two functions. One function needs to count the number of items to display in the combo box. The second function needs to retrieve data to insert in the combo box’s list of items.
Finally, you need to specify a data source (the file that contains the data you want to display in the combo box) and make sure the usesDataSource property for the combo box is selected in the Show Attributes Inspector pane or set to true using Swift code.
To see how a data source works to fill a combo box with a list of items, follow these steps:
class AppDelegate: NSObject, NSApplicationDelegate, NSComboBoxDataSource {
let myArray = ["Sandwich", "Chips", "Soda", "Salad"]
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
myCombo.dataSource = self
myCombo.usesDataSource = true
numberOfItemsInComboBox(myCombo)
comboBox(myCombo, objectValueForItemAtIndex: 0)
}
This Swift code defines the data source for the combo box (identified by the myCombo IBOutlet) as self, which means the same class is also the data source. It makes sure the usesDataSource property is true to use a data source. Then it calls two functions defined by the NSComboBoxDataSource protocol.
func numberOfItemsInComboBox(aComboBox: NSComboBox) -> Int {
return myArray.count
}
func comboBox(aComboBox: NSComboBox, objectValueForItemAtIndex index: Int) -> AnyObject {
return myArray[index]
}
The numberOfItemsInComboBox function counts all the items in the myArray array and returns that integer. The comboBox function places each array item in the combo box’s item list.
This simple program shows how to retrieve a list of items from another data source (in this case an array called myArray) to fill an item list for a combo box. The complete code for the AppDelegate.swift file should look like this:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate, NSComboBoxDataSource {
@IBOutlet weak var window: NSWindow!
@IBOutlet weak var myCombo: NSComboBox!
@IBOutlet weak var comboResult: NSTextField!
let myArray = ["Sandwich", "Chips", "Soda", "Salad"]
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
myCombo.usesDataSource = true
myCombo.dataSource = self
numberOfItemsInComboBox(myCombo)
comboBox(myCombo, objectValueForItemAtIndex: 0)
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
func numberOfItemsInComboBox(aComboBox: NSComboBox) -> Int {
return myArray.count
}
func comboBox(aComboBox: NSComboBox, objectValueForItemAtIndex index: Int) -> AnyObject {
return myArray[index]
}
@IBAction func showResult(sender: NSButton) {
comboResult.stringValue = myCombo.stringValue
}
}
Summary
Text fields allow the user to type anything such as numbers or strings, so a text field offers multiple properties (intValue, floatValue, doubleValue, and stringValue) to store typed information in the proper data type. To restrict numeric information the user may type, you can use a number formatter to define minimum and/or maximum values along with defining different ways the user can enter numeric data such as with a percentage sign or a currency sign.
Besides ordinary text fields, Xcode offers several variations of text fields for specialized purposes. Labels are designed for simply displaying text without allowing the user to edit the displayed text. A secure text field masks typed in data to keep it safe from prying eyes. A token field displays typed in data as groups or tokens while a search field offers a property to remember previously typed in data.
Combo boxes combine the features of a text field with a pop-up button. A combo box can display a list of valid options that the user can click on, or the user can type in data. You can define a combo box’s list of options in the Show Attributes Inspector pane, or you can retrieve data from another source such as from an array.
The main purpose of text fields and combo boxes is to allow the user to type in any type of data. When the user types in data, you may need to write Swift code to verify that the entered data is actually valid for your program.