event handle

Regulating Touch Event Delivery

Turning off delivery of touch events By default, a view receives touch events, but you can set its  userInteractionEnabled   property  to  NO  to turn off delivery of touch events. A view also does not receive these events if it’s hidden or if it’s transparent. Turning on delivery of multiple touches . by setting the multipleTouchEnabled property of your view.

Restricting event delivery to a single viewa view’s exclusiveTouch property is set to NO

Restricting event delivery to subviews. A custom UIView class can override hitTest:withEvent: to restrict the delivery of multitouch events to its subviews. See “Hit-Testing” for a discussion of this technique.

Best Practices for Handling Multitouch Events

Always implement the event-cancellation methods.

If you handle events in a subclass of UIViewUIViewController, or (in rare cases) UIResponder,

  • You should implement all of the event-handling methods (even if it is a null implementation).

  • Do not call the superclass implementation of the methods.


If you handle events in a subclass of any other UIKit responder class,

  • You do not have to implement all of the event-handling methods.

  • But in the methods you do implement, be sure to call the superclass implementation. For example,

    [super touchesBegan:theTouches withEvent:theEvent];
Do not forward events to other responder objects of the UIKit framework.

  • Custom views that redraw themselves in response to events should only set drawing state in the event-handling methods and perform all of the drawing in the drawRect: method.

  • Do not explicitly send events up the responder (via nextResponder); instead, invoke the superclass implementation and let the UIKit handle responder-chain traversal.


Gesture recognizers may delay the delivery of touch objects to the view while they are recognizing gestures, and by default they cancel delivery of remaining touch objects to the view once they recognize their gesture.

Default Touch-Event Delivery

To clarify this behavior, consider a hypothetical gesture recognizer for a discrete gesture involving two touches (that is, two fingers). Touch objects enter a system and are passed from the UIApplication object to theUIWindow object for the hit-test view. The following sequence occurs when the gesture is recognized:

  1. The window sends two touch objects in the Began phase (UITouchPhaseBegan) to the gesture recognizer, which doesn’t recognize the gesture. The window sends these same touches to the view attached to the gesture recognizer.

  2. The window sends two touch objects in the Moved phase (UITouchPhaseMoved) to the gesture recognizer, and the recognizer still doesn’t detect its gesture. The window then sends these touches to the attached view.

  3. The window sends one touch object in the Ended phase (UITouchPhaseEnded) to the gesture recognizer. This touch object doesn’t yield enough information for the gesture, but the window withholds the object from the attached view.

  4. The window sends the other touch object in the Ended phase. The gesture recognizer now recognizes its gesture and so it sets its state to UIGestureRecognizerStateRecognized. Just before the first (or only) action message is sent, the view receives a touchesCancelled:withEvent: message to invalidate the touch objects previously sent (in the Began and Moved phases). The touches in the Ended phase are canceled.

Now assume that the gesture recognizer in the last step instead decides that this multitouch sequence it’s been analyzing is not its gesture. It sets its state to UIGestureRecognizerStateFailed. The window then sends the two touch objects in the Ended phase to the attached view in a touchesEnded:withEvent: message.


Shaking-Motion Events

- (BOOL)canBecomeFirstResponder {
    return YES;
}
 
- (void)viewDidAppear:(BOOL)animated {
    [self becomeFirstResponder];
}

Handling a motion event

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
}
 
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.5];
    self.view.transform = CGAffineTransformIdentity;
 
    for (UIView *subview in self.view.subviews) {
        subview.transform = CGAffineTransformIdentity;
    }
    [UIView commitAnimations];
 
    for (TransformGesture *gesture in [window allTransformGestures]) {
        [gesture resetTransform];
    }
}
 
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
}
If a shaking-motion event travels up the responder chain to the window without being handled and the applicationSupportsShakeToEdit  property of  UIApplication  is set to  YES , iOS displays a sheet with Undo and Redo commands. By default, this property is set to  YES .

Getting the Current Device Orientation

If you need to know only the general orientation of the device, and not the exact vector of orientation, you should use the methods of the UIDevice class to retrieve that information. Using the UIDevice interface is simple and does not require that you calculate the orientation vector yourself.

Before getting the current orientation, you must tell the UIDevice class to begin generating device orientationnotifications by calling the beginGeneratingDeviceOrientationNotifications method. Doing so turns on the accelerometer hardware (which may otherwise be off to conserve power).

Shortly after enabling orientation notifications, you can get the current orientation from the orientationproperty of the shared UIDevice object. You can also register to receiveUIDeviceOrientationDidChangeNotification notifications, which are posted whenever the general orientation changes. The device orientation is reported using the UIDeviceOrientation constants, which indicate whether the device is in landscape or portrait mode or whether the device is face up or face down. These constants indicate the physical orientation of the device and need not correspond to the orientation of your application’s user interface.

When you no longer need to know the orientation of the device, you should always disable orientation notifications by calling the endGeneratingDeviceOrientationNotifications method of UIDevice. Doing so gives the system the opportunity to disable the accelerometer hardware if it is not in use elsewhere.


Core Motion

 Core Motion defines a manager class, CMMotionManager, and three classes whose instances encapsulate measurements of motion data of various types:

  • CMAccelerometerData object encapsulates a data structure that records a measurement of device acceleration along the three spatial axes. This data derives from the accelerometer.

    CMGyroData object encapsulates a data structure that records a biased estimate of a device’s rate of rotation along the three spatial axes. This “raw” data derives from the gyroscope. (“Biased” in this context refers to an offset from the true rotation rate. Thus, if the device is not rotating, this estimate from the gyroscope will still give a non-zero value.)

  • CMDeviceMotion object encapsulates processed device-motion data that derives from both the accelerometer and the gyroscope. Core Motion’s sensor fusion algorithms process both accelerometer and gyroscope data and provide an application with highly accurate measurements of device attitude, the (unbiased) rotation rate of a device, the direction of gravity on a device, and the acceleration that the user is giving to a device. A CMAttitude object, which is contained in an CMDeviceMotion instance, contains properties giving different measurements of attitude, including the Euler angles indicated by roll, pitch, and yaw.

Figure 4-1  Core Motion classes

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值