5. 터치 이벤트

3088 단어

콘셉트


UIEvent:


하나의 터치 이벤트(첫 손가락부터 화면을 터치하기 시작해서 마지막 손가락이 화면을 떠나기까지)를 나타낸다. 하나의 UIevent는 여러 개의 UItouch 대상으로 구성되어 있고 몇 개의 손가락이 있으면 몇 개의 터치 대상이 있다.
속성:UIEventType
UIEventTypeTouches,// 
UIEventTypeMotion,// 
UIEventTypeRemoteControl,// 
UIEventTypePresses NS_ENUM_AVAILABLE_IOS(9_0),// 

속성: 모든 UITOuch의 객체 컬렉션을 나타내는 allTouchs

UITouch


한 손가락의 클릭 이벤트를 나타낸다. 현재 손가락의 클릭 위치, 상태(터치, 이동, 떠나기)를 나타낼 수 있다.
- (CGPoint)locationInView:(nullable UIView *)view;// view 
- (CGPoint)previousLocationInView:(nullable UIView *)view// view 

UIResponder


iOS에서 해당 이벤트를 수행할 수 있는 객체는 UIresponder 하위 클래스 객체입니다.UIResponder는 사용자가 리셋을 클릭할 수 있는 네 가지 방법(시작, 이동, 끝, 취소)을 제공했는데 그 중에서 프로그램이 강제로 종료되고 전화가 오는 등 의외의 상황이 중단될 때만'취소'이벤트를 호출할 수 있다.
- (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event;
- (void)touchesEstimatedPropertiesUpdated:(NSSet *)touches NS_AVAILABLE_IOS(9_1);

UIResponder에서 상술한 방법을 다시 써서 리셋 감청을 할 수 있습니다.

여러 개의 보기가 중첩되고 제스처가 서로 충돌할 때 어느 View가 어느 시간을 처리하는지 어떻게 판단합니까?


현재 응답 체인의 생성과 처리가 관련되어 있습니다.

응답 체인


응답 체인은 현재 보기에서 터치 이벤트를 실행하거나 응답할 수 있는 UIresponder로 구성된 트리 구조입니다
  • 응답 체인의 형성: appdelegate->UIApplication-->UIWindow-->RootViewController-->RootViewController.view ......
  • 응답 이벤트의 분배는 첫 번째 UIWindow 대상부터 UIWindow의 합격 여부를 판단한 다음에 클릭 위치가 이 Window 안에 있는지 판단하고 없으면 nil로 돌아가면 다음 UIWindow로 바꾼다.만약 있다면, UI Window에subView가 없으면, 모든 과정이 끝납니다.만약 UIWindow에subViews가 있다면, 뷰를 찾을 때까지 뒤에서 앞으로subViews 전체를 옮겨다니며, UIWindow와 비슷한 일을 하십시오.못 찾으면 전달 안 해.(합격이란 컨트롤이 수신 시간을 허용한다는 뜻이다. 1. 숨길 수 없다. 2. 알파의 값은 0.01 3보다 크고 isUserInterface는 YES이며 UIlabel과 UIImageView는 기본적으로 NO이다)
  • 응답 이벤트의 판단: 찾은 뷰를 나누어 호출- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;해서 어느 뷰가 처리되었는지 판단합니다.
  • // 
    - (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event {
      // 
        if (!self.hidden && self.alpha > 0.01 && self.isUserInteractionEnabled) {
            // 
            if ([self pointInside: point withEvent:event]) {
                UIView *attachedView;
                for (int i = self.subviews.count - 1; i >= 0; i--) {
                    UIView *view  = self.subviews[i];
                    // view hitTest
                    attachedView =  [view hitTest:point withEvent:event];
                    if (attachedView)
                        break;
                }
                if (attachedView)  {
                    return attachedView;
                } else {
                    return self;
                }
            }
        }
        returnnil;
    }
    

    더 좋은 글http://www.jianshu.com/p/cb0314b72883

    좋은 웹페이지 즐겨찾기