2012-10-04 2 views
2

프로젝트에서 자동 테스트를 위해 UISpec을 사용하고 있습니다. Apple이 xCode 4.5를 iOS 6 SDK와 함께 출시 할 때까지는 아무 문제가 없었습니다. 이제는 UITouch 클래스의 오류 목록 때문에 UISpec 프로젝트를 컴파일 할 수 없습니다. 코드는 다음과 같습니다.프로그래밍 방식으로 xCode 4.5에서 UITouch 시뮬레이션 (0120) UICpec

// 
// TouchSynthesis.m 
// SelfTesting 
// 
// Created by Matt Gallagher on 23/11/08. 
// Copyright 2008 Matt Gallagher. All rights reserved. 
// 
// Permission is given to use this source code file, free of charge, in any 
// project, commercial or otherwise, entirely at your risk, with the condition 
// that any redistribution (in part or whole) of source code must retain 
// this copyright and permission notice. Attribution in compiled projects is 
// appreciated but not required. 
// 

@implementation UITouch (Synthesize) 

// 
// initInView:phase: 
// 
// Creats a UITouch, centered on the specified view, in the view's window. 
// Sets the phase as specified. 
// 
- (id)initInView:(UIView *)view 
{ 
    self = [super init]; 
    if (self != nil) 
    { 
     CGRect frameInWindow; 
     if ([view isKindOfClass:[UIWindow class]]) 
     { 
      frameInWindow = view.frame; 
     } 
     else 
     { 
      frameInWindow = 
      [view.window convertRect:view.frame fromView:view.superview]; 
     } 

     _tapCount = 1; 
     _locationInWindow = 
     CGPointMake(
        frameInWindow.origin.x + 0.5 * frameInWindow.size.width, 
        frameInWindow.origin.y + 0.5 * frameInWindow.size.height); 
     _previousLocationInWindow = _locationInWindow; 

     UIView *target = [view.window hitTest:_locationInWindow withEvent:nil]; 

     _window = [view.window retain]; 
     _view = [target retain]; 
     _phase = UITouchPhaseBegan; 
     _touchFlags._firstTouchForView = 1; 
     _touchFlags._isTap = 1; 
     _timestamp = [NSDate timeIntervalSinceReferenceDate]; 
    } 
    return self; 
} 

// 
// setPhase: 
// 
// Setter to allow access to the _phase member. 
// 
- (void)setPhase:(UITouchPhase)phase 
{ 
    _phase = phase; 
    _timestamp = [NSDate timeIntervalSinceReferenceDate]; 
} 

// 
// setPhase: 
// 
// Setter to allow access to the _locationInWindow member. 
// 
- (void)setLocationInWindow:(CGPoint)location 
{ 
    _previousLocationInWindow = _locationInWindow; 
    _locationInWindow = location; 
    _timestamp = [NSDate timeIntervalSinceReferenceDate]; 
} 

@end 

컴파일러에서 "_tapCount = 1;"과 같은 줄에 오류가 있습니다. 오류는 "Uknown type name"_tapCount "입니다 ...?"

내가 무슨 짓을했는지 :이 변수가 여전히 존재하는 경우

  1. 는 "class_copyIvarList"런타임 기능을 사용하여 UITouch 클래스의 인스턴스 변수의 목록을 얻을 확인. 그들이하다.
  2. 같은 런타임에 필요한 값을 변경하려고

    UINT uPhase = UITouchPhaseBegin; object_setInstanceVariable (self, "_phase", & uPhase);

또는 유효하지 않은 값이 "_phase"회원에 기록 된 두 경우 모두

Ivar var = class_getInstanceVariable([self class], "_phase"); 
object_setIvar(self, var, [NSNumber numberWithInt:UITouchPhaseBegin]); 

. 콘솔에 UITouch 인스턴스의 설명을 인쇄하여 확인했습니다. 그것은 "단계 : Uknown"이라고 썼다.

는 내가 키 - 값 코딩을 사용하기로 결정하고 다음과 같이 구현 :
[self setValue:[NSNumber numberWithInt:1] forKey:@"tapCount"]; 
[self setValue:[NSNumber numberWithInt:UITouchPhaseBegin] forKey:@"phase"]; 

지금이 어떤 결과를 주었다. 컴파일 오류가 제거되고 UITouch 인스턴스의 멤버 값은 변경되지만 아무 일도 일어나지 않습니다. 나는 적절한 UI 객체의 "touchesBegan : ..."및 "touchesEnded : ..."메소드에서 중단 점을 설정하고 (내 경우에는 UIButton이었습니다) 디버깅했습니다. 이러한 메서드는 호출되지만 아무 일도 일어나지 않습니다. 단추 처리기가 호출되지 않습니다.

또한 KVC 때문에 "setPhase"및 "setLocationInWindow"UITouch 범주의 주석을 달았습니다. 그렇지 않으면 끝없는 재귀가 발생합니다. 속성의 setter 자체를 호출합니다.

지금은 아이디어가 없습니다. 이 카테고리는 "Matt Gallagher가 23/11/08에 작성했습니다."라는 말은 UISpec의 제 3 자 코드임을 의미합니다. 그래서 나는 UISpec을 제외하고 다른 곳에서 사용되기를 바랍니다.

감사합니다.

P. 이 API는 비공개 API라는 것을 알고 있습니다. 프로젝트의 릴리스 구성에는 포함되지 않습니다. 자동 테스트에만 필요합니다.

답변

4

UIQuery.m 파일에서 아무 것도 변경할 필요가 없습니다. UIQuery.h 파일에 다음 코드 줄을 추가하십시오.

#ifdef __IPHONE_6_0 
@interface UITouch() { 
    NSTimeInterval _timestamp; 
    UITouchPhase _phase; 
    UITouchPhase _savedPhase; 
    NSUInteger _tapCount; 

    UIWindow *_window; 
    UIView *_view; 
    UIView *_gestureView; 
    UIView *_warpedIntoView; 
    NSMutableArray *_gestureRecognizers; 
    NSMutableArray *_forwardingRecord; 

    CGPoint _locationInWindow; 
    CGPoint _previousLocationInWindow; 
    UInt8 _pathIndex; 
    UInt8 _pathIdentity; 
    float _pathMajorRadius; 
    struct { 
     unsigned int _firstTouchForView:1; 
     unsigned int _isTap:1; 
     unsigned int _isDelayed:1; 
     unsigned int _sentTouchesEnded:1; 
     unsigned int _abandonForwardingRecord:1; 
    } _touchFlags; 
} 
@end 
#endif 

감사합니다.

+0

완벽하게 작동합니다. 고마워요! – alfared

관련 문제