control
A control is a type of view in a user interface that sends a message to another object when a user manipulates it in a certain way, such as tapping a button or dragging a slider. A control is the agent in the target-action model. A control (or, in OS X, the control’s cell) stores the information necessary for sending the message: a reference to the object to receive the message (the target) and a selector that identifies the method to invoke on the target (the action). When a user manipulates the control in a specific way, it sends a message to the application object, which then forwards the action message to the target
控制器对象是一种视图。当用户操作视图的时候,他将会把消息发送给另外一个对象,例如,点击一个按钮,滑动一个slider,控制器对象是 目标--动作 模型的代理。控制器对象保存啦发送消息所必要的信息(接收消息的对象和当动作触发后响应的方法)。When a user manipulates the control in a specific way, it sends a message to the application object, which then forwards the action message to the target (暂时不明白)
Touch
Objects Represent Fingers Touching a View
Fingers touching a view are represented by UITouch objects. Touch objects include information such as the view the finger is touching, the location of the finger in the view, a timestamp, and a phase. A touch object goes through several phases during a multi-touch sequence in a given order:
The Delivery of Touch Objects Follows a Defined Path
In the main event loop, the application object gets (raw) touch events in its event queue, packages them as UITouch objects in UIEvent objects, and sends them to the window of the view in which the touch occurred. The window object, in turn, sends these objects to this view, which is known as the hit-test view. If this view cannot handle the touch event (usually because it hasn’t implemented the requisite event-handling methods) the event travels up the responder chain until it is either handled or discarded.
在整个事件循环中,应用程序在事件队列中获取点击时间,把他们分装成许多uitouch对象,同事发送给触摸发生的视图的window.window,接着,把这些对象发送到发生的视图(名字是 hit-test view)。 如果点击的视图不能捕获这个点击事件(可能由于他没有实现捕获事件必要的方法),这个触摸时间在响应链中查找一遍,知道被捕获,或丢弃。如下图:
To Handle Events You Must Override Four Methods
Responder objects, which include custom views and view controllers, handle events by implementing four methods declared by the UIResponder class:
- touchesBegan:withEvent: is called for touch objects in the Began phase.
- touchesMoved:withEvent: is called for touch objects in the Moved phase.
- touchesEnded:withEvent: is called for touch objects in the Ended phase.
- touchesCancelled:withEvent: is called when some external event—for example, an incoming phone call—causes the operating system to cancel touch objects in a multitouch sequence.
The first argument of each method is a set of touch objects in the given phase. The second argument is a UIEvent object that tracks all touch objects in the current multitouch sequence.
By default, a view is able to receive multitouch events. Instances of some UIKit view classes, however, cannot receive multitouch events because theiruserInteractionEnabled property is set to NO. If you are subclassing these classes, and want to receive events, be sure to set this property to YES. Although custom views and view controllers should implement all four methods, subclasses of UIKit view classes need only implement the method corresponding to the phase or phases of interest; in this case, however, they must be sure to call the superclass implementation first.
小测验:
NDTfirstView *view = [[NDTfirstView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
NDTSecondView *secondView =[[NDTSecondView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
secondView.backgroundColor = [UIColor greenColor];
[view addSubview:secondView];
NDTThirdView *thirdView = [[NDTThirdView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
thirdView.backgroundColor = [UIColor blueColor];
[secondView addSubview:thirdView];
打印结果:
2014-03-04 16:37:51.454 TouchTest[4087:a0b] NDTviewControllview hitview <NDTThirdView: 0xa153c10; frame = (0 0; 100 100); layer = <CALayer: 0xa153cd0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 16:37:51.455 TouchTest[4087:a0b] firstView hitview <NDTThirdView: 0xa153c10; frame = (0 0; 100 100); layer = <CALayer: 0xa153cd0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 16:37:51.455 TouchTest[4087:a0b] secondview hitview <NDTThirdView: 0xa153c10; frame = (0 0; 100 100); layer = <CALayer: 0xa153cd0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 16:37:51.456 TouchTest[4087:a0b] thirdview hitview <NDTThirdView: 0xa153c10; frame = (0 0; 100 100); layer = <CALayer: 0xa153cd0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
结果分析:hitview :thirdview
父视图 --》子视图顺序排列:viewcontrollview --firstview- secondview--thirdview
事件响应顺序 viewControll -- firstview--secondview--thirdview 从下往上
上述代码结果基础上追加:
secondView.userInteractionEnabled = NO;
打印结果:
2014-03-04 16:40:45.159 TouchTest[4119:a0b] NDTviewControllview hitview <NDTfirstView: 0x8e47010; frame = (0 0; 300 300); layer = <CALayer: 0x8e470d0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 16:40:45.160 TouchTest[4119:a0b] firstView hitview <NDTfirstView: 0x8e47010; frame = (0 0; 300 300); layer = <CALayer: 0x8e470d0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
结果分析:
secondview 不接收点击事件,其上子视图都不接收点击事件
hitview <NDTfirstView>hitview变为接收事件的父视图
如果hitview为viewcontroller,则firstview没有点击事件,由此:事件由父视图---》子视图 传递
新测验:
NDTfirstView *view = [[NDTfirstView alloc] initWithFrame:CGRectMake(0, 0, 300, 300)];
view.backgroundColor = [UIColor redColor];
[self.view addSubview:view];
NDTSecondView *secondView =[[NDTSecondView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
secondView.backgroundColor = [UIColor greenColor];
[self.view addSubview:secondView];
NDTThirdView *thirdView = [[NDTThirdView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
thirdView.backgroundColor = [UIColor blueColor];
[self.view addSubview:thirdView];
视图1、2、3都添加在self.view上
+点击视图3
打印结果:
NDTviewControllview hitview <NDTThirdView: 0x981bd20; frame = (0 0; 100 100); layer = <CALayer: 0x981bde0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 17:58:55.813 TouchTest[4412:a0b] thirdview hitview <NDTThirdView: 0x981bd20; frame = (0 0; 100 100); layer = <CALayer: 0x981bde0>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+点击视图2打印结果:
NDTviewControllview hitview <NDTSecondView: 0x981b8b0; frame = (0 0; 200 200); layer = <CALayer: 0x981b970>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
2014-03-04 18:02:49.111 TouchTest[4412:a0b] secondview hitview <NDTSecondView: 0x981b8b0; frame = (0 0; 200 200); layer = <CALayer: 0x981b970>> touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
结果分析:传递顺序:由父视图到子视图中间的子视图响应,虽frame,与顺序叠加,但非子视图的视图不响应。
理论:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"hitTest: withEvent:%@",[superhitTest:pointwithEvent:event]);
return self;
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
return NO;
}
以上这两个方法作用等同于useinterfaceEnabled,经测试。在代码中也很少用++如果要重新处理touch事件的传递,写一个UIWindow子类,重写sendEvent方法,具体方法,见官方文档
++multipleTouchEnabled UIView的这个属性,默认为NO,当同时有多个触摸过来的时候,仅仅处理第一个,
带着好奇学习
Responder object
A responder is an object that can respond to events and handle them. All responder objects are instances of classes that ultimately inherit fromUIResponder (iOS) or NSResponder (OS X). These classes declare a programmatic interface for event handling and define a default behavior for responders. The visible objects of an app are almost always responders—for example, windows, views, and controls—and the app object is a responder as well. In iOS, view controllers (UIViewController objects) are also responder objects.
响应者是是可以对事件作出响应并处理事件的对象,所有的响应者对象最终都继承于UIResponder,这些类申明处理事件的接口,并且定义啦响应者默认的行为。一个app的可视的对象基本上都是响应者---例如:windows,views.controlls---app对象本身也是一个响应者。在ios中,viewcontrolls同样也是响应者对象。如下图所示:
要接受事件,每个响应者必须实现合适的处理事件的方法。在一些情况下,告诉应用程序,他可以激起第一响应。 (例如:uitextfield)
The First Responder Receives Some Events First
In an app, the responder object that first receives many kinds of events is known as the first responder. It receives key events, motion events, and action messages, among others. (Mouse events and multitouch events first go to the view that is under the mouse pointer or finger; that view might or might not be the first responder.) The first responder is typically the view in a window that an app deems best suited for handling an event. To receive an event, the responder must also indicate its willingness to become first responder; it does this in different ways for each platform:
In addition to receiving event messages, a responder can receive action messages that have no target specified. (Action messages are sent by controls such as buttons and controls when users manipulate them.
- (BOOL)canBecomeFirstResponder { return YES; }
在app中,第一个先接收多种事件的响应者被称为第一响应。他接收键盘事件,触摸事件和动作消息(鼠标事件,多点触摸事件,首先进入鼠标和手指下的视图,那个视图可能是也可能不是第一响应者)。第一响应者是app认为最适合处理事件的视图。为拉接收一个事件,响应者他愿意作为第一响应者。这个在不同的情况中有不同的处理方式
The Responder Chain Enables Cooperative Event Handling
If the first responder cannot handle an event or action message, it forwards it to the “next responder” in a linked series called the responder chain. The responder chain allows responder objects to transfer responsibility for handling an event or action message to other objects in the app. If an object in the responder chain cannot handle the event or action, it passes the message to the next responder in the chain. The message travels up the chain, toward higher-level objects, until it is handled. If it isn't handled, the app discards it.
如果第一响应者不能处理事件或者消息,他把事件传递给在响应者链中得下一个响应者。响应者链响应者对象交换处理事件的所有权。在app中,如果在响应者链中得响应者对象不能处理事件,他就会把事件传递给下一个响应者。消息在响应者链中传递,传递给等级高的响应者,知道他被处理。如果没有被处理,app将会把事件抛弃。
The path of an event. The general path of an event up the responder chain starts with a view—the first responder or the view under the mouse pointer or finger. From there, it proceeds up the view hierarchy to the window object and then to the global app object. However, the responder chain for events in iOS adds a variation to this path: If a view is managed by a view controller and if the view cannot handle an event, the view controller becomes the next responder.
事件的传递路径:响应者传递事件的一般路径,从鼠标或手指下的第一个视图开始。从view--window --app.然而,在ios中得事件响应者链增加增加啦一些变化。如果一个视图被viewcontroller管理同时,这个view不能处理事件,viewcontroller将作为第一响应者。从这个文档中,貌似,下面的小测验的推断是错误的,why?
小测验当中的是触摸发生的顺序,触摸从下到上告诉每一个视图,响应者,从外向内,一个一个判断是否接收响应事件。这两个并不冲突。
一直认为自己学完啦,仅仅弄清楚啦概念,才是冰上一角啊。。。。。