1. Trang chủ
  2. » Công Nghệ Thông Tin

Tài liệu Lập trình ứng dụng cho iPhone part 14 docx

24 327 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Monitoring events and actions
Thể loại Book chapter
Định dạng
Số trang 24
Dung lượng 0,92 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

It starts out at the first responder of the key window, which is typically the view where the event occurred—in other words, where the user touched the screen.. Any object in the chain

Trang 1

Monitoring events and actions

In the previous chapter you learned how to create the basic view controllers that fulfill the controller role of an MVC architectural model You’re now ready to start accepting user input, since you can now send users off to the correct object Users can interact with your program in two ways: by using the low-level event model or

by using event-driven actions In this chapter, you’ll learn the difference between the two types of interactions Then we’ll look at notifications, a third way that your program can learn about user actions

Of these three models, it’s the events that provide the lowest-level detail (and which ultimately underlie everything else), and so we’ll begin with events

14.1 An introduction to events

We briefly touched on the basics of event management in chapter 10, but as we said

at the time, we wanted to put off a complete discussion until we could cover them

in depth; we’re now ready to tackle that job

This chapter covers

■ The SDK’s event modeling

■ How events and actions differ

■ Creating simple event- and action-driven apps

Trang 2

Part 1 of this book, dealing with web design, outlined how events tend to work on the iPhone The fundamental unit of user input is the touch: a user puts his finger on the screen This could be built into a multi-touch or a gesture, but the touch remains the building block on which everything else is constructed It’s thus the basic unit that we’re going to be examining in this chapter.

14.1.1 The responder chain

When a touch occurs in an SDK program, you have to worry

about something you didn’t have to think about on the

web: who responds to the event That’s because SDK

pro-grams are built of tens—perhaps hundreds—of different

objects Almost all of these objects are subclasses of the

UIResponder class, which means they contain all the

func-tionality required to respond to an event So who gets

to respond?

The answer is embedded in the concept of the

responder chain This is a hierarchy of different objects

that are each given the opportunity, in turn, to answer an

event message

Figure 14.1 shows an example of how an event moves up

the responder chain It starts out at the first responder of the

key window, which is typically the view where the event

occurred—in other words, where the user touched the

screen As we’ve already noted, this first responder is

prob-ably a subclass of UIResponder—which is the class reference

you’ll want to look to for a lot of responder functionality

Any object in the chain may accept an event and resolve it, but whenever that doesn’t occur the event moves further up the list of responders From a view, an event

will go to its superview, then its superview, until it eventually reaches the UIWindow

object, which is the superview of everything in your application It’s useful to note that from the UIWindow downward, the responder chain is the view hierarchy turned on its head, so when you’re building your hierarchies, they’ll be doing double duty

Although figure 14.1 shows a direct connection from the first responder to the window, there could be any number of objects in this gap in a real-world program

Often the normal flow of the responder chain will be interrupted by delegation A

specific object (usually a view) delegates another object (usually a view controller) to act for it We already saw this put to use in our table view in chapter 13, but we now understand that a delegation occurs as part of the normal movement up the responder chain

If an event gets all the way up through the responder chain to the window and it can’t deal with an event, then it moves up to the UIApplication itself, which most fre-

quently punts the event to its own delegate: the application delegate, an object that we’ve

been using in every program to date

App Delegate

The Application

The Window

First Responder

Figure 14.1 Events on the iPhone are initially sent to the first responder, but then travel up the responder chain until someone accepts them.

Trang 3

Ultimately you, the programmer, will be the person who decides what in the sponder chain will respond to events in your program You should keep two factors in mind when you make this decision: how classes of events can be abstracted together at higher levels in your chain, and how you can build your event management using the concepts of MVC.

At the end of this section we’ll address how you can subvert this responder chain

by further regulating events, but for now let’s build on its standard setup

14.1.2 Touches and events

Now that you know a bit about how events find their way to the appropriate object, we can dig into how they’re encoded by the SDK First we want to offer a caveat: usually you won’t need to worry about this level of detail because the standard UIKit objects will generally convert low-level events into higher-level actions for you, as we discuss

in the second half of this chapter With that said, let’s look at the nuts and bolts of event encoding

The SDK abstracts events by combining a number of touches (which are sented by UITouch objects) into an event (which is represented by a UIEvent object)

repre-An event typically begins when the first finger touches the screen and ends when the last finger leaves the screen In addition, it should generally only include those touches that happened in the same view

In this chapter we’ll work mainly with UITouches (which make it easy to parse gle-touch events) and not with UIEvents (which are more important for parsing multi-touch events) Let’s lead off with a more in-depth look at each

sin-First responders and keyboards

Before we leave this topic of responders behind, we’d like to mention that the first responder is a very important concept Because this first responder is the object that can accept input, it’ll sometimes take a special action to show its readiness for input This is particularly true for text objects like UITextField and UITextView, which (if editable) will pop up a keyboard when they become the first responder This has two immediate consequences

If you want to pop up a keyboard for the text object, you can do so by turning it into the first responder:

Trang 4

to-UITOUCH REFERENCE

A UITouch object is created when a finger is placed on the screen, moves on the screen, or is removed from the screen A handful of properties and instance methods can give you additional information on the touch, as detailed in table 14.1

Together the methods and properties shown in table 14.1 offer considerable tion on a touch, including when and how it occurred

Only the phase property requires additional explanation It returns a constant that can be set to one of five values: UITouchPhaseBegan, UITouchPhaseMoved, UITouch-PhaseStationary, UITouchedPhaseEnded, or UITouchPhaseCancelled You’ll often want to have different event responses based on exactly which phase a touch occurred

in, as you’ll see in our event example

UIEVENT REFERENCE

To make it easy to see how individual touches occur as part of more complex gestures, the iPhone SDK organizes UITouches into UIEvents Figure 14.2 shows how these two sorts of objects interrelate

Just as with the UITouch object, the UIEvent object contains a number of properties and methods that you can use to figure out more information about your event, as described in table 14.2

Table 14.1 Additional properties and methods can tell you precisely what happened during a touch event Method or property Type Summary

whether touch began, moved, ended, or was canceled

view Property The view where the touch began

locationInView: Method Gives the current location of the touch in the specified

UITouchPhaseEnded locationInView:

(28,32)

UITouch phase:

UITouchPhaseMoved locationInView:

Trang 5

The main use of a UIEvent method is to give you a list of related touches that you can break down by several means If you want to get a list of every touch in an event, or if you want to specify just gestures on a certain part of the screen, then you can do that with UIEvent methods This ends our discussion of event containers in this chapter Note that all of these methods compact their touches into an NSSet, which is an object defined in the Foundation framework You can find a good reference for the NSSet at Apple’s developer resources site.

THE RESPONDER METHODS

So, how do you actually access these touches and/or events? You do so through a series of four different UIResponder methods, which are summarized in table 14.3 Each of these methods has two arguments: an NSSet of touches that occurred during the phase in question and a UIEvent that provides a link to the entire event’s worth of touches You can choose to access either one, as you prefer; as we’ve said, we’re going

to be playing with the bare touches With that said, we’re now ready to dive into an actual example that demonstrates how to capture touches in a real-life program

14.2 A touching example: the event reporter

Our sample application for events is something we call the event reporter, which will offer a variety of responses depending on how and when the iPhone screen is touched We have two goals with our sample program

Table 14.2 The encapsulating event object has a number of methods and properties

that let you access its data.

Method or property Type Summary

touchesForView: Method All event touches associated with a view

touchesForWindow: Method All event touches associated with a window

Table 14.3 The UIResponder methods are the heart of capturing events.

touch the screen

move across the screen

leave the screen

the phone is put up to your head, or other events that might cause an external cancellation

Trang 6

First, we want to show you a cool and simple application that you can write using events, one that should get you thinking about everything you can do.

Second, we want to show some of the low-level details of how events work in a visual form Therefore, if you actually take the trouble to code and compile this program, you’ll gain a better understanding of how the various phases work as well as how tap-ping works

You’ll kick off this development process by creating a project named eventreporterthat uses the View-Based Application template That means you’ll start with a view con-troller already in place We’ll also use this example to show how an MVC program can

be structured

14.2.1 Setting things up in Interface Builder

By now you should be comfortable enough

with Interface Builder that you can set up all of

your basic objects using it For this program

we’ve decided that we want to create three new

objects: two button-shaped objects that will

float around the screen to mark the beginning

and end of touches, plus a status bar to go at

the bottom of the screen and describe a few

other events when they occur

Because you want all of our new objects to

lie beneath the view controller in the view

hier-archy, you call up the view controller’s own

.xib file, eventreporterViewController.xib As

usual, you’ll add your new objects to the Main

Display window that represents the view

con-troller’s view

All of your work in Interface Builder is, of

course, graphical, so we can’t show the code

of this programming process However, we

have included a quick summary of the actions

you should take The results are shown in

fig-ure 14.3

■ Set the background color of the UIView to an attractive aluminum color You do this on the Attributes tab of the Inspector window, as you would with most of your work in this project

■ Create a UILabel, stretch it across the bottom of the screen, and set the color to

be steel Also, clear out its text so that it doesn’t display anything at startup

■ Create two UITextFields This class of objects is generally used to accept input, but we opted to use the objects for our pure display purposes because we liked their look (Don’t worry; we’ll show how to use the full functionality of a UIText-Field toward the end of this chapter.)

Figure 14.3 Two UITextFields (one

of them hidden) and one UILabel, all set against an aluminum-colored background, complete the object creation we’ll need for our eventreporter project.

Trang 7

■ Center each UITextField at the center of the screen using Interface Builder’s handy positioning icons This location’s coordinates will be 159, 230.

■ For each UITextField, input text that lists its starting position; this will later be updated by the program as the text field moves Deselect the user interac-tion–enabled option for each UITextField so that users can’t manipulate them.The process takes longer to explain than it takes to accomplish You’ll have a working interface in just a couple of minutes

CREATING IBOUTLETS

Because you’ll modify all three of these objects during the course of your program’s runtime, you need to link them to variables inside Xcode You’ll want to link every-thing to your controller, since it’ll be taking care of updates, as is appropriate under the MVC model

The tricky thing here is that the view controller doesn’t seem to appear in our eventreporterViewController.xib file—at least not by that name Fortunately, there’s a proxy for it Since the view controller is what loads up the xib, it appears as the file’s owner in the nib document window You can therefore connect objects to the view controller by linking them to the file’s owner proxy This is a common situation, since view controllers frequently load additional xib files for you

Listing 14.1 shows your view controller’s header file, eventreportViewController.h, following the addition of these IBOutlets The listing also contains a declaration of a method that you’ll use later in this project

@interface eventreporterViewController : UIViewController {

IBOutlet UITextField *startField;

IBOutlet UITextField *endField;

IBOutlet UILabel *bottomLabel;

14.2.2 Preparing a view for touches

Touch events can only be captured by UIView objects Unfortunately, as of this writing, there’s no way to automatically delegate those touches to a view controller Therefore,

in order to manage touch events using the MVC model, you’ll typically need to class a UIView, capture the events there, and then send messages to the view control-ler

In your project you’ll create a new object class, reportView, which is a subclass of UIView You then link that new class into the view controller’s existing view through Interface Builder You open up eventreporterViewController.xib, go to the Identity tabListing 14.1 An IB-linked header

Trang 8

for the view object that you’ve been using, and change its

name from UIView to reportView, just as you did in

chap-ter 13 when you created a table view controller subview

Any new methods that you write into reportView,

including methods that capture touch events, will be now

reflected in your view To clarify this setup, figure 14.4

shows the view hierarchy that you’ve built for your

even-treporter project

With a brand-new UIView subclass in hand, you can

now write methods into it to capture touch events and

forward them on to its controller This code, which

appears in reportView.m, is shown in listing 14.2

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

only the events for their specific phase So, for example, the

touchesBegan:with-Event: method would only have UITouchPhaseBegan touches in it In forwarding on these touches we could have kept the different phases distinct, but we’ve instead decided to throw everything together and sort it out on our own on the other side Second, we’ll comment one final time that these methods send us two pieces of information: a set of touches and an event They are partially redundant, and which one you work with will probably depend on the work you’re doing If you’re not doing complex multi-touch events, then the NSSet of touches will probably be sufficient Third, note that you’re sending the touches to the view controller by way of the nextResponder method As you’ll recall, the responder chain is the opposite of the view hierarchy at its lower levels, which means in this case the nextResponder of reportView is the UIViewController We would have preferred to have the UIView-Controller just naturally respond to the touches messages, but we made use of our responder chain in the next best way As of this writing, the compiler warns that next-Responder may not know about the manageTouches method, but it will; this warning can be ignored

Listing 14.2 A collection of methods report touches in UIViews

UIViewController UIWindow

reportView UILabel UITextField UITextField

Figure 14.4 Working primarily in Interface Builder, we’ve connected up six objects that we’ll be using to report iPhone events.

Trang 9

We’ll see some other ways to use the nextResponder method toward the end of our discussion of events.

AN ASIDE ON THE TEXT FIELDS AND LABEL

If you were to actually code in this example, you’d discover that this program correctly responds to touch events even when the touches occurred atop one of the text fields

or the label at the bottom of the page How does your program manage that when you only built event response into the reportView?

The answer is this: it uses the responder chain The text fields and the label don’t respond to the event methods themselves As a result, the events get passed up the

responder chain to the reportView, which does leap on those events, using the code

we’ve just seen

14.2.3 Controlling your events

Intercepting touches and forwarding them up to the view controller may be the toughest part of this code Once the events get to the view controller, they run through a simple method called manageTouches:, as shown in listing 14.3

} else if (touch.phase == UITouchPhaseMoved) {

bottomLabel.text = @"Touch is moving ";

} else if (touch.phase == UITouchPhaseEnded) {

Listing 14.3 manageTouches, which accepts inputs and changes views

B

C

D E C C F

Trang 10

Once you get a touch, the first thing you do is determine what phase it arrived in Originally you could have determined this information based on which method a touch arrived through, but since we combined everything you have to fall back on the phase property Fortunately, it’s easy to use You just match it up to one of three con-stants C, and that determines which individual actions your program undertakes Having different responses based on the phase in which a touch arrive is com-mon—which is in fact why the event methods are split up in the first place Our exam-ple demonstrates this with some distinct responses: you move your start field when touches begin, you move your end field when touches end, and you update the bot-tom label in both the moved and ended phases.

In your UITouchPhaseBegan response, you delve further into your touch’s data by using the locationInView: method to figure out the precise coordinates where a touch occurred D You’re then able to use that data to reposition your text field and

to report the coordinates in the text field E You later do the same thing in the UITouchPhaseEnded response

Finally, you take a look at the tapCount in the UITouchPhaseEnded response F This is generally the best place to look at taps since the iPhone now knows that the user’s finger has actually come off the screen As you can see, it’s easy to both run a command based on the number of taps and to report that information

Figure 14.5 shows what your event responder

looks like in action You should imagine a finger that

set down on the space where the begin text field is

sit-ting and that is currently moving across the screen

And with that, your event reporter is complete

Besides illustrating how a program can respond to

touches, we have highlighted how the MVC model can

be used in a real application

Your project contained four views: a reportView, a

UILabel, and two UITextFields It was tempting to

process events in the reportView itself, especially since

you had to create a subclass anyway, but instead you

pushed the events up to the view controller, and in

doing so revealed why you’d want to do MVC modeling

Since it takes on the controller role, you gave the

view controller access to all of its individual objects,

and therefore you didn’t have to try to remember

what object knew about what other object Tying

things into the view controller, rather than scattering

them randomly across your code, made your project

that much more readable and reusable, which is what

most architectural and design patterns are about

Figure 14.5 Your event responder uses a few graphical elements to report events as they occur.

Trang 11

14.3 Other event functionality

Before we complete our discussion of events entirely, we’d like to cover a few more topics of interest We’re going to explore how to regulate the report of events in a vari-ety of ways and then describe some deficiencies in the event model

14.3.1 Regulating events

As we mentioned earlier, there are some ways that you can modify how events are reported (and whether they are at all) As you’ll see, three different objects give you access to this sort of regulation: UIResponder, UIView, and UIApplication We’ve listed all the notable options we’re going to discuss in table 14.4

Since UIView is a subclass of UIResponder, you’ll generally have access to the methods from both classes in most UIKit objects You’ll need to do some additional work to access the UIApplication methods

UIRESPONDER REGULATION

You’ve already seen that UIResponder is the source of the methods that let you ture events; as shown here, it’s also the home of the methods that control how the responder chain works

Most of the responder chain–related methods won’t be directly used by your code, instead typically appearing deep in frameworks becomeFirstResponder and

Table 14.4 Properties in various objects allow for additional control of when events are monitored.

Method or property Type Summary

method

Returns the next responder in the chain by default but can be modified

property

A Boolean set to NO by default; controls whether multi-touches after the first are thrown out

Trang 12

resignFirstResponder (which control who the first responder is) and FirstResponder, canResignFirstResponder, and isFirstResponder (which return Booleans related to the information in question) all typically fall into this category It’s the last UIResponder method, nextResponder, which may be of use in your pro-grams As defined by UIResponder, nextResponder just returns the next responder, per the normal responder chain We used it in our example to pass our touches up.

If you want to change the normal order of the responder chain, you can do so by creating your own nextResponder function in a subclass This new function will over-ride its parent method, and thus will allow your program to take a different path up your own responder chain

exclusive-is an alternative way that we could have managed our eventreporter example, where

we didn’t want anything but the reportView to accept events) Meanwhile, TouchEnabled starts reporting of multi-touch events, which are otherwise ignored.UIAPPLICATION REGULATION

multiple-Finally we come to the UIApplication methods These lie outside of our normal archy of objects, and thus we can’t get to them from our view objects Instead we need

hier-to call them directly from the UIApplication object as shown here:

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];

As you may recall from chapter 11, sharedApplication is a UIApplication class method that provides us with a reference to the application object Typically, we’ve used its return as the receiver for the beginIgnoringInteractionEvents message Each of the three methods listed under UIApplication works as you’d expect once you know the secret to accessing them

14.3.2 Other event methods and properties

We’ve spent a lot of time on events, but at the same time we’ve only scratched the face We have mixed feelings on the subject

On the one hand, events give you low-level access to the unique user input allowed

by the iPhone Since much of this book is about how the iPhone is unique, we’d like to delve into it much further

On the other hand, you won’t be using events that much That’s because you usually won’t need this sort of low-level control over your user input Instead, you’ll use the iPhone’s many control objects (and thus actions) in order to accept almost all user input

As a result, this chapter has offered you a compromise: a solid look at how events work that should suffice for those times when you do need to descend to touch management,

Ngày đăng: 26/01/2014, 18:20

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm