2

タッチを挿入するエンタープライズ アプリを開発しています。私が使用する方法は、KIF フレームワークで見られるものと同じです ( https://github.com/square/KIF/tree/master/Additionsを参照)。

この方法が機能しないケースが少なくとも 1 つあります。

ユーザーがデバイスをタップすると、 scrollviews に対してインジェクションが機能しなくなります。移動するタッチイベントを挿入すると、スクロールしなくなりました。ユーザー自身がデバイスをスクロールすると、インジェクションは再び機能します。KIFsメソッドでは状態が設定されていないようですが、実際のタッチが発生したときにiOSによって設定されます。

誰かそれについてもっと知っていますか?たぶん、それがどの状態になるか考えがありますか?適切に聞こえるいくつかのプライベート API 呼び出しを既に試しましたが、どれも機能しませんでした。

以下は、私が使用した方法を説明するコードです。

タッチダウン:

UITouch *touch = [[[UITouch alloc] initAtLocation:point inWindow:hitView.window] autorelease];
[touch setPhase:UITouchPhaseBegan];

UIEvent *newEvent = [hitView _eventWithTouch:touch];
[_activeTouchEvents addObject:touch];

[[UIApplication sharedApplication] sendEvent:newEvent];

タッチ移動 UITouch* touch = _activeTouchEvent;

[touch setPhase:UITouchPhaseMoved];
[touch setLocationInWindow:point];

UIEvent *newEvent = [hitView _eventWithTouch:touch];
[[UIApplication sharedApplication] sendEvent:newEvent];

タッチアップ

UITouch* touch = _activeTouchEvent;
[touch setPhase:UITouchPhaseEnded];
[touch setLocationInWindow:point];

UIEvent *newEvent = [hitView _eventWithTouch:touch];
[[UIApplication sharedApplication] sendEvent:newEvent];
[_activeTouchEvent release];
_activeTouchEvent = nil;

UIView(拡張)

- (UIEvent *)_eventWithTouch:(UITouch *)touch;
{
    UIEvent *event = [[UIApplication sharedApplication] performSelector:@selector(_touchesEvent)];

    CGPoint location = [touch locationInView:touch.window];
    KIFEventProxy *eventProxy = [[KIFEventProxy alloc] init];
    eventProxy->x1 = location.x;
    eventProxy->y1 = location.y;
    eventProxy->x2 = location.x;
    eventProxy->y2 = location.y;
    eventProxy->x3 = location.x;
    eventProxy->y3 = location.y;
    eventProxy->sizeX = 1.0;
    eventProxy->sizeY = 1.0;
    eventProxy->flags = ([touch phase] == UITouchPhaseEnded) ? 0x1010180 : 0x3010180;
    eventProxy->type = 3001;

    NSSet *allTouches = [event allTouches];
    [event _clearTouches];
    [allTouches makeObjectsPerformSelector:@selector(autorelease)];
    [event _setGSEvent:(struct __GSEvent *)eventProxy];
    [event _addTouch:touch forDelayedDelivery:NO];

    [eventProxy release];
    return event;
}

UITouch (拡張)

- (id)initAtLocation:(CGPoint)point inWindow:(UIWindow *)window
{
    self = [super init];
    if (self == nil) {
        return nil;
    }

    // Create a fake tap touch
    _tapCount = 1;
    _locationInWindow = point;
    _previousLocationInWindow = _locationInWindow;

    UIView *hitTestView = [window hitTest:_locationInWindow withEvent:nil];

    _window = [window retain];
    _view = [hitTestView retain];
    _gestureView = [hitTestView retain];
    _gestureRecognizers = [[NSMutableArray arrayWithArray:[hitTestView gestureRecognizers]] retain];
    _phase = UITouchPhaseBegan;
    _touchFlags._firstTouchForView = 1;
    _touchFlags._isTap = 1;
    _timestamp = [[NSProcessInfo processInfo] systemUptime];

    return self;
}

- (void)setPhase:(UITouchPhase)phase;
{
    _phase = phase;
    _timestamp = [[NSProcessInfo processInfo] systemUptime];
}

編集1:「タッチダウン」のコードブロックが正しくありませんでした

4

0 に答える 0