Event distribution for iOS

Source: Internet
Author: User

Development on the mobile platform focuses on data and data processing, event processing, and UI. Therefore, event distribution processing is a very important part, and it is also an important parameter for a platform. If the event distribution design is poor, some complex UI scenarios will become hard to write or even unable to write. From a function machine with no touch on a small screen to a smart machine with multiple touch points on a large screen, the basic idea of event distribution and processing is the same-chain (there is a mode in the design model that is the responsibility chain of responsibility), but the degree of complexity is different.

There are three types of events in iOS: Touch events (single point, multi point, gesture), sensor events (accelerometer), and remote control events. Here I will introduce the distribution and processing of the first event.

The figure above is from Apple's official website. Describes the Responder chain and the event processing sequence. Through these two images, we can find that:

1. The event is transmitted along the responder chain. If the link is not processed, it is passed to the next link. If it is not processed, it is returned to the UIApplication. If it is not processed, it will be discarded.

2. The next level of view is its viewController. If there is no viewController, it is its superView.

3. The next level of viewController is its view superView.

4. The view is followed by a window and is finally passed to the application. This iOS is simpler than OS X (the application is one, and the window is also one)

The transfer rule is as follows: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + ICAgICAgICA8aW1nIHNyYz0 = "http://www.2cto.com/uploadfile/Collfiles/20140126/2014012608582353.png" alt = "\">

In this way, the event will be transmitted step by step from the first responder until it is processed or discarded.


Due to the complexity of the UI, this responder chain needs to be calculated based on the event. For example, if I add two buttons to a view and click one Button first, the first responder must be the button that has been clicked, But I can click another button below, obviously, when a touch event occurs, the chain needs to re-calculate the update. The order of calculation is the order of event distribution, which is basically the opposite of distribution.

No matter what the event is, it is first obtained by the system itself. It is sent to the UIApplication by the iOS system, and the Application decides who to handle it. Therefore, if we want to intercept the event, it can be intercepted at the UIApplication level or UIWindow level.

How does UIView determine whether this event should be handled by itself? When the iOS system detects a touch operation, it will Package A UIEvent object and put it in the Application queue. The Application extracts the event from the queue and submits it to UIWindow for processing. UIWindow will use hitTest: withEvent: method to recursively find the view where the Operation's initial point is located. This process becomes hit-test view.

HitTest: withEvent: The process of the method is as follows: Call the pointInside: withEvent of the current view: method to determine whether the touch point is inside the current view. If NO is returned, hitTest: withEvent: returns nil. If YES is returned, hitTest: withEvent: message is sent to subViews in the current view. The traversal order of all subViews is to traverse forward from the end of the array, until a subView returns a non-empty object or the traversal is complete. If a subView returns a non-null object, the hitTest method returns this object. If each subView returns nil, it returns itself.

Let's take a look at the example:

Here, ViewA contains ViewB and ViewC, and ViewC continues to contain ViewD and ViewE. If we click the viewE area, the hit-test View determination process is as follows:

1. The touch is inside A, so check B and C

2. The touch is not inside B and inside C, so check D and E

3. The touch is not inside D, but inside E, because E is a leaf, it is determined that the end is now


We can run a piece of code to verify that, first inherit a class myView from UIView, override

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{    UIView *retView = nil;    NSLog(@"hitTest %@ Entry! event=%@", self.name, event);        retView = [super hitTest:point withEvent:event];    NSLog(@"hitTest %@ Exit! view = %@", self.name, retView);       return retView;}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{    BOOL ret = [super pointInside:point withEvent:event];//    if ([self.name isEqualToString:@"viewD"]) {//        ret = YES;//    }    if (ret) {        NSLog(@"pointInside %@ = YES", self.name);    } else {        NSLog(@"pointInside %@ = NO", self.name);    }        return ret;}
Manually add five views to the viewDidLoad method, all of which are myView instances.

- (void)viewDidLoad{    [super viewDidLoad];        _viewA = [[myView alloc] initWithFrame:CGRectMake(10, 10, 300, 200) Color:[UIColor blackColor] andName:@"viewA"];    [self.view addSubview:_viewA];    [_viewA release];        _viewB = [[myView alloc] initWithFrame:CGRectMake(10, 240, 300, 200) Color:[UIColor blackColor] andName:@"viewB"];    [self.view addSubview:_viewB];    [_viewB release];        _viewC = [[myView alloc] initWithFrame:CGRectMake(10, 10, 120, 180) Color:[UIColor blueColor] andName:@"viewC"];    [_viewB addSubview:_viewC];    [_viewC release];        _viewD = [[myView alloc] initWithFrame:CGRectMake(170, 10, 120, 180) Color:[UIColor blueColor] andName:@"viewD"];    [_viewB addSubview:_viewD];    [_viewD release];        _viewE = [[myView alloc] initWithFrame:CGRectMake(30, 40, 60, 100) Color:[UIColor redColor] andName:@"viewE"];    [_viewD addSubview:_viewE];    [_viewE release];}
The style is as follows:


When I click viewE, the following information is printed:

18:32:46. 538 eventDemo [1091: c07] hitTest viewB Entry! Event = Timestamp: 6671.26 touches :{(

)}

18:32:46. 538 eventDemo [1091: c07] pointInside viewB = YES

18:32:46. 539 eventDemo [1091: c07] hitTest viewD Entry! Event = Timestamp: 6671.26 touches :{(

)}

18:32:46. 539 eventDemo [1091: c07] pointInside viewD = YES

18:32:46. 539 eventDemo [1091: c07] hitTest viewE Entry! Event = Timestamp: 6671.26 touches :{(

)}

18:32:46. 540 eventDemo [1091: c07] pointInside viewE = YES

18:32:46. 540 eventDemo [1091: c07] hitTest viewE Exit! View = >

18:32:46. 540 eventDemo [1091: c07] hitTest viewD Exit! View = >

18:32:46. 541 eventDemo [1091: c07] hitTest viewB Exit! View = >

18:32:46. 541 eventDemo [1091: c07] touchesBegan viewE

18:32:46. 624 eventDemo [1091: c07] touchesEnded viewE

From the print information, we can see that viewB is judged first, then viewD, and finally viewE, but the event is directly transmitted to viewE.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.