官术网_书友最值得收藏!

Exploring text elements

There are different ways to display text in iOS. You can draw strings directly in a graphic context through NSString or NSAttributedString or take advantage of the power of Text Kit, a framework dedicated to text drawing that is involved in all the controls we'll see in the next paragraphs. UIKit provides some really helpful classes built on Text Kit, which will simplify your work, allowing you not to worry about the way text is drawn. Let's go through all these classes.

Presenting text with UILabel

UILabel is a class that simply draws strings. Its text and attributedText properties define the text that is displayed by the label; the former receives a simple NSString instance to display plain text, while the latter receives an NSAttributedString instance to include styles, such as bold and italic, or draw strings with different colors and fonts:

The aspect of a label can be changed using dedicated properties:

  • textColor: This is used for plain strings. It defines the color of the text with a UIColor instance.
  • highlightedTextColor: This defines the color of the label when the highlighted property is set to true (for example, when you add a label inside a table cell and the cell is selected).
  • textAlignment: This accepts an NSTextAlignment value to define the alignment of the text, such as Center, Left, or Justified.
  • shadowColor-shadowOffset: This attaches a custom shadow to the label defined by color and offset with a CGSize value.

Labels are displayed on a single line by default. To allow the strings to be displayed on multiple lines, you have to set the numberOfLines property that, in conjunction with the lineBreakMode property, provides the needed information to split and truncate the text on more lines.

Here are some examples with different line-break modes:

Starting with iOS8, the width of a multiline label can be automatically calculated through Auto Layout and defined by the preferredMaxLayoutWidth property. If you are supporting previous versions of iOS, you might need to define an explicit value for this property. The label's default font is system font, but it can be easily changed with the font property.

In some particular cases (or if you define an explicit width with preferredMaxLayoutWidth), the label bounds might not fit a string in its entirety. With the adjustsFontSizeToFitWidth property, you can set the font size to be decreased until the string is entirely visible inside the label bounds. With the minimumScaleFactor property, you can obtain a similar effect by defining, with a proportion, the minimum size to which the font can be reduced before the string gets truncated (for example, a font with size 24 and a minimum scale factor of 0.5 can be reduced up to a minimum value of 12).

Receiving user input with UITextField

A text field is a control used to receive text inputs. The way users interact with this control is mainly handled by iOS; when a text field is selected, it becomes the first responder, and the system keyboard is automatically presented and starts listening for user input (more information about keyboards will be provided later in this chapter).

When a user is done with a text field, you can send resignFirstResponder() to the text field itself, and the keyboard will be automatically released. The selection of a text field can be forced through the becomeFirstResponder() function, which moves the focus on the text field when a user selects it.

For some properties, UITextfield instances are similar to labels. You can set and get the displayed text through text and attributedText, and you can also provide specific textColor, font, and textAlignment classes.

The text field draws text on a single line, and it can be plain or attributed text. If the allowsEditingTextAttributes property is set to true, a contextual menu with bold, italic, and underline styles selection is presented after a long press:

If the placeholder property is defined, this value is shown in place of text when the text field is empty. By default, the placeholder's color is light gray. The best way to set a custom placeholder is by defining the attributedPlaceholder property. As soon as the text field is selected, the placeholder text is removed.

The appearance of the text field can be modified through the borderStyle property, which accepts UITextFieldBorderStyle values such as .None, .Line, .Bezel, and .RoundRect. If the .None border style is chosen, you can provide the background and disabledBackground properties with one image, each to be used as a background. If the text field is disabled (meaning the enable property is equal to false), the second image is used.

You can go further with the customization by defining the leftView and rightView properties, which are two reserved views placed on the sides of the text field that add functionalities or specific information related to the current field content.

The visibility of these views is handled by two other properties—leftViewMode and rightViewMode—which require a UITextFieldViewMode value. They are strictly related to the text field's state. You can chose to never (.Never) show these views, always (.Always) show them, or present them while the user is editing (.WhileEditing) or not (.UnlessEditing).

With a really similar logic, by just defining the clearViewMode value, you can show a "clear" button to the right of the field that automatically removes the current content:

As for many other controls, a delegate handles and receives important information from the text fields; your controllers can implement the UITextFieldDelegate protocol that handles messages such as textFieldDidBeginEditing: when the user selects a text field and textFieldShouldReturn: when the user presses the "done" button on the keyboard. Some of these messages are also sent as notifications, so you can register an observer to handle specific text field changes.

Multiline text with UITextView

This class, which is a subclass of UIScrollview, is really similar to the text field, but it handles and displays multiple lines of text. A text view is typically used to display a large amount of text, such as the body of a document or a long message.

Some of its properties are the same that we listed for the UITextField class; you can, in fact, set and get the current text or attributedText class and define textColor, font, and textAlignment.

Sometimes, you need to use a text view to show content that isn't editable by users. In this case, you can simply set the editable property to false. The text will be drawn using all the properties previously defined, but users won't be able to change the current content. It is possible to also prevent text selection by disabling the selectable property.

Note

When a text view is selected, it becomes the first responder, and the keyboard is automatically shown, just as for the text field.

A really interesting feature of UITextView instances is the ability to detect strings formatted as links, addresses, phone numbers, or events and automatically convert text into interactive elements that trigger actions when tapped. For example, if a user taps a phone number, an alert-style prompt displays a button that starts a call; if the number is long pressed, the user can choose to call the number, create a new contact, copy the string, or send a message to this number. Other examples are links opened with Safari, addresses opened with the Maps application, and events that can be added to the calendar.

Note

You can choose which of these formats should be detected in the text view with the dataDetectorTypes property. Just note that in this case, the text view should be selectable but not editable.

These elements can be selected through Interface Builder or programmatically using a bitmask of UIDataDetectorTypes (for example, .Link, .PhoneNumber, .CalendarEvent, .Address, .None, and .All).

With the help of the Text Kit framework, we can perform some really complex operations on the text displayed in a text view. For example, we might want to add an image inside the text view while having the current text nicely wrapped around this image. An easy way to implement this layout is using the image frame to define an area that cannot contain text.

The code is straightforward, as follows:

        var image = UIImageView(image: UIImage(named:"Image"))
        self.textView.addSubview(image)
        let exclusionPath = UIBezierPath(rect: image.frame)
        self.textView.textContainer.exclusionPaths = [exclusionPath]

The image is attached as subview of the text view, and then an exclusion path is defined using UIBezierPath with the shape of image.frame. The last step is defining the exclusion paths for textContainer. As you can see in the following image, the text is drawn around the area occupied by the image frame:

The main events taking place during the interaction with the text view can be handled by implementing UITextViewDelegate. The protocol defines methods such as textViewDidBeginEditing:, which tells the delegate that the editing has begun, and textViewDidChangeSelection:, which is triggered if the text view is selectable and the user highlights a portion of the text (the current selection can be retrieved using the selectedRange property).

Notes about the keyboard

When users interact with components such as text views or fields, these elements ask the system to display a keyboard to be able to receive user input.

The keyboard is a window that is independent from the user interface. This means that the keyboard just overlaps your UI without performing any automatic adjustments to the underlying views. You are, therefore, responsible for updating the UI so that it shows the appropriate elements in the available portion of the screen. You can already imagine that a really common issue occurs when the currently selected field gets overlapped by the keyboard.

There are different solutions that can help us fix this layout problem, but probably the easiest is to wrap UI elements inside UIScrollView and resize this view when the keyboard is displayed. We will discuss more about how to resize and move UI elements using Auto Layout in Chapter 4, Auto Layout.

Tip

On iPad, the keyboard can be hidden and shown by the users with a button. However, it's an edge case, so it is a good choice to handle the layout without requiring the user to manually change the keyboard visibility in order to display the underlying content.

Keyboard events

You can subscribe to some useful notifications triggered by the system to be notified of keyboard events. Take a look at the following table:

Keyboard configuration

To help users type any input, the keyboard can be configured to better fit the kind of data the text field expects. As both UITextField and UITextView implement the UITextInputTraits protocol, you can define some properties that adjust the keyboard behavior and its appearance. You can also completely change the type of the keyboard with the keyboardType property that receives a UIKeyboardType value, such as NumberPad, URL, EmailAddress, and even Twitter. Depending on the selected type, the keyboard's layout changes to show only the useful keys.

Other useful configurations are keyboardAppearance, which alters the color of the keyboard (you have only two choices here: dark or light), and returnType, which helps you set the label of the return type by picking one among the available options such as Go, Done, Next, and Google.

主站蜘蛛池模板: 荥经县| 东丰县| 青浦区| 塔城市| 开封市| 崇明县| 启东市| 乌拉特中旗| 钟祥市| 伊春市| 福州市| 南涧| 日土县| 屏边| 会宁县| 尼木县| 边坝县| 宾阳县| 鹤岗市| 左权县| 理塘县| 余江县| 广西| 正宁县| 登封市| 西城区| 霍林郭勒市| 曲水县| 永新县| 油尖旺区| 通化市| 炉霍县| 金华市| 呼图壁县| 鄂州市| 蓝山县| 仲巴县| 太仓市| 上饶县| 沅陵县| 九龙坡区|