タッチを挿入するエンタープライズ アプリを開発しています。私が使用する方法は、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:「タッチダウン」のコードブロックが正しくありませんでした