[英]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.