暂停循环并等待 UIAlertView 交互

Posted

技术标签:

【中文标题】暂停循环并等待 UIAlertView 交互【英文标题】:Pausing a loop and waiting for UIAlertView interaction 【发布时间】:2014-01-02 15:52:59 【问题描述】:

我设置了一个循环来将文件复制到目录,但是,当目标位置已经存在文件时,会显示 UIAlertView 提示用户覆盖、跳过、取消等。我的问题是,我该如何暂停循环直到 UIAlertView 被关闭,此时将显示下一个(如果有)UIAlertView。

循环代码如下所示:

for (NSString *fileInArray in selectedFiles) 
    [self copyFile:fileInArray destination:[self.path stringByAppendingPathComponent:[fileInArray lastPathComponent]]];

路径作为 NSStrings 存储在 NSArray 中,NSArray 是在另一种方法(复制/移动)中创建的,这是粘贴方法。

这是粘贴文件的方法(用于复制功能)。

- (void) copyFile:(NSString *)input destination:(NSString *) output



    NSFileManager *copyManager = [NSFileManager defaultManager];
    NSError *error;
    if ([copyManager fileExistsAtPath:output])

            RIButtonItem *overwriteItem = [RIButtonItem itemWithLabel:@"Overwrite" action:^
                NSError *removeError;
                [copyManager removeItemAtPath:output error:&removeError];
                if (removeError)
                    [self displayError:[NSString stringWithFormat:@"There was a problem overwriting the file '%@'. %@", [output lastPathComponent], [removeError localizedDescription]]];
                
            ];
            RIButtonItem *cancelItem = [RIButtonItem itemWithLabel:@"Skip" action:^

            ];

            RIButtonItem *renameItem = [RIButtonItem itemWithLabel:@"Rename" action:^
            ];
            UIAlertView *fileExistsAlert = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"A file already exists at the destination matching this file." cancelButtonItem:cancelItem otherButtonItems:overwriteItem, renameItem, nil];
            [fileExistsAlert show];
    
    [copyManager copyItemAtPath:input toPath:output error:&error];
    if (error)
        [self displayError:[error localizedDescription]];
    

目前,第一个 UIAlertView 显示大约 1 秒钟然后被隐藏,此时界面变为灰色,好像它被禁用并且不再出现 UIAlertViews。使用最新的 ios SDK。

【问题讨论】:

您应该将方法更改为“异步”模式。例如,这可以通过使用selectedFiles 的全局索引来完成。如果文件存在,则中断循环并显示警报对话框。然后使用最后一个索引继续循环。 你有什么建议或例子可以看。我不确定我是否理解“打破循环然后继续使用最后一个索引”的意思。当然,除非您提议我更改“copyFile”方法以允许 NSArray 作为输入。因此,在检测到重复文件时,我可以中断循环,将当前索引分配给全局变量,处理重复文件,然后(以某种方式)从一种方法继续循环。我只是在寻找最有效/最安全的方法来做到这一点。 - (void) copyFile:(NSString *)input destination:(NSString *) output 更改为 - (void) copyFile:(NSString *)input destination:(NSString *) output atIndex:(NSInteger)index 并全局保存当前索引以供用户在 UIAlertView 的委托中选择后使用。 @Chris 听起来不错,但是,循环不会暂停而是继续运行,这将在第一个被解除之前继续创建多个 UIAlertViews。如果我要检查循环中是否已经存在重复文件,我将如何在中断处理 UIAlertView 后继续循环? 【参考方案1】:

对于这个模式,你可以做这样的事情。您可以传入下一个索引以复制到您的复制函数中,而不是基本循环。然后,复制函数将使用诸如 performSelector afterDelay 之类的方法调用自身,并带有下一个索引。如果要显示警报,它不会调用自身,并且会在警报解除时进行下一次调用。

【讨论】:

【参考方案2】:

线索是推进runloop。但是虽然这工作正常,但使用异步访问摆脱循环。

示例见:Make iOS blocks execute synchronously

【讨论】:

【参考方案3】:

当遇到类似问题时,我决定创建一个函数来检查发生了哪些错误,将错误编译到一个数组中,并使用一个 UIALERTVIEW 显示错误。您可以创建一个添加到包含有问题的文件/文件名的数组的函数,然后显示单个 UIALERT VIEW 说明哪些文件未能上传/或重复。如果您有很多文本要在 UIALERTVIEW 中显示,那么当 UIALERTVIEW 显示的文本超过它在 UIALERTVIEW 中可以放置的文本时,它就会变成可滚动的。

【讨论】:

以上是关于暂停循环并等待 UIAlertView 交互的主要内容,如果未能解决你的问题,请参考以下文章

在循环中暂停并重新启动 setTimeout

unity3d 中的能源效率 - 暂停应用程序等待用户交互

在 UIAlertView 中使用滑块?

如何在DispatcherTimer结束之前暂停for循环?

iOS UI 自动化 UIA Element.is Visible() 抛出过时的响应?

如何暂停循环几秒钟?