簡體   English   中英

如何以編程方式模擬滑動手勢?

[英]How can I simulate a swipe gesture programmatically?

我正在嘗試使用frank (反過來UISpec )為我們的新iOS應用程序編寫一些驗收測試。 雖然框架支持觸摸作為與視圖交互的基本方式,但它目前不支持任何更多涉及的手勢(例如,捏合,滑動等)。 我需要添加對滑動的支持,至少因為這是我們應用程序功能的核心,沒有它我們的測試將毫無用處。

如果我能找到一種模擬Cocoa事件的方法,那么實現它應該相當簡單。 如果您使用Apple的UIAutomation框架( 請參閱此處 ),則可以發送滑動手勢,因此這是一個在外部生成這些事件的示例。 我在網上搜索過,但沒有找到任何人這樣做的例子(雖然有一個帖子 ,有人在此之前要求類似的東西......)。

非常感謝您的幫助/想法......

我昨天花的時間試圖讓這個工作最終解決各種問題。 我對此並不完全滿意,但這是我現在能做的最好的事情 - 如果有人能提出任何改進建議或工作替代方案,我會歡迎他們......

無論如何,對於其他試圖做類似事情的人。 我根據我對中詳述的API解決方案這篇文章 -我記錄的事件,我想模擬序列,然后發揮他們回來。 唯一的障礙是我無法使內置播放API工作(我在底部提到的評論中提到了同樣的崩潰)。 經過一段時間在ASM土地上挖掘,我最終編寫了自己的版本。

@implementation UIApplication (EventReplay)

///
/// - replayEventsFromFile:
///
- (void)replayEventsFromFile:(NSString *)filename 
{
  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
  NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:filename];
  NSArray* eventList = [[NSArray arrayWithContentsOfFile:filePath] retain];
  [self replayEvents:eventList];
}

///
/// - replayEvents:
///
- (void)replayEvents:(NSArray *)events
{
  if (!events.count)
    return;

  NSDictionary *eventDict = [events objectAtIndex:0U];
  GSEventRef thisEvent = GSEventCreateWithPlist((CFDictionaryRef)eventDict);

  uint64_t eventTime = thisEvent->record.timestamp;
  thisEvent->record.timestamp = mach_absolute_time();

  mach_port_t appPort = GSCopyPurpleNamedPort([[[NSBundle mainBundle] bundleIdentifier] UTF8String]);
  GSSendEvent(&thisEvent->record, appPort);
  mach_port_deallocate(mach_task_self(), appPort); 

  if (events.count <= 1)
    return;

  NSIndexSet *remainderIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, events.count - 1)];
  NSArray *remainingEvents = [events objectsAtIndexes:remainderIndexes];

  GSEventRef nextEvent = GSEventCreateWithPlist((CFDictionaryRef)[remainingEvents objectAtIndex:0U]);
  NSTimeInterval nextEventDelay = GetTimeDelta(nextEvent->record.timestamp, eventTime);

  if (nextEventDelay > 0.05)
    [self performSelector:@selector(replayEvents:) withObject:remainingEvents afterDelay:nextEventDelay];
  else
    [self replayEvents:remainingEvents];

  CFRelease(nextEvent);
  CFRelease(thisEvent);
}

@end

上面的代碼段顯示了我如何回放事件。 我的實現相當苛刻 - 你會看到我不得不捏造這樣一個事實:如果我盲目地使用計時器來安排下一個事件,有時它不會發射 - 似乎是在延遲太小時。 你看到的可怕黑客似乎讓事情變得正常

無論如何,希望這能以某種方式幫助別人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM