objective-c - 检测 NSUndoManager 警报 View 何时可见

标签 objective-c ios cocoa-touch nstimer nsundomanager

我将描述我一般要做什么(以防有更好的方法),然后是我遇到的绊脚石(以防我的方法是最好的方法)。

我想做什么 :我想向我的撤消管理器添加一个有时间限制的调用。如果在规定时间内没有触发撤消,则在设备晃动时撤消将不可用,因此不会发生任何事情。

我在做什么:我的方法是使用 NSUndoManagerNSTimer .当我将调用添加到撤消管理器时,我也会启动一个 5 秒计时器。当计时器触发时,它会检查 !self.undoManager.isUndoing如果它是真的,则继续并从撤消管理器中删除所有操作。在模拟器中测试它是有效的:摇动手势会在 5 秒前启动撤消,但不会在 5 秒后启动。

问题是,如果我在 5 秒限制内得到摇晃手势,撤消管理器会显示警报,但如果用户等到 5 秒限制后实际点击撤消按钮,则什么也不会发生:计时器很高兴地清除了堆栈,即使警报 View 可见。

有没有办法检查警报 View 是否可见?最好是如果我能弄清楚用户是否也点击了撤消或取消,并在按下取消按钮时清除撤消管理器的操作堆栈。

或者除了以这种方式使用计时器之外还有更好的方法吗?

谢谢!

编辑添加:我的另一个想法是自己捕获震动事件(通过 motionEnded:withEvent: 调用)并手动管理警报和撤消堆栈。与上述相比,对此的想法也是受欢迎的。

最佳答案

我最终按照我在编辑中的建议——使用 motionEnded:withEvent手动管理警报和撤消。这样做的缺点是您没有获得与 UIAlertView 风格略有不同的内置撤消警报。并以摇晃的 Action 进入屏幕。

好处是我现在有一个 10 秒后过期的撤消。下面是代码的一般结构,以防您需要相同的代码。

一、make sure your app can receive shake events并且你有一个 NSUndoManager你可以访问。你还需要一个计时器;我的代码设置了 NSTimer当可撤销事件发生并持续 10 秒时开始。确保在计时器启动的同一时间添加撤消目标,以便实际上可以撤消某些内容。

接下来,实现 motionEnded:withEvent像这样:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (motion == UIEventSubtypeMotionShake && [self.undoManager canUndo]) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Undo something?" message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Undo", nil];
        [alert show];
        undoAlertIsVisible_= YES;
    }
}

我正在使用名为 undoAlertIsVisible_ 的 ivar在这里跟踪我的警报是否在屏幕上。

在计时器的回调中,执行以下操作:
if (!self.undoManager.isUndoing && !undoAlertIsVisible_) {
    // Clear away the possible undo
    [self.undoManager removeAllActionsWithTarget:self];
}
undoTimer_ = nil;

在这里,我们检查以查看我们当前没有撤消并且警报不可见。如果是这样,请删除撤消操作并将计时器(另一个 ivar)设置为 nil。我将计时器设置为 nil,以便我可以检查它是否在我的警报回调中被触发,这里是:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex != alertView.cancelButtonIndex) {
        if (self.undoManager.canUndo) {
            [self.undoManager undo];
        }
    }
    else {
        if (!undoTimer_) {
            // Timer fired while we were staring at the alert
            [self.undoManager removeAllActionsWithTarget:self];
        }
    }
    undoAlertIsVisible_= NO;
}

在警报回调中,我们要么使撤消发生,要么在警报可见且警报被取消时触发计时器,我们清除可能的撤消操作。否则撤消操作将在取消后挂起而没有计时器来清除它。

希望这可以帮助某人!

关于objective-c - 检测 NSUndoManager 警报 View 何时可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9055116/

相关文章:

objective-c - 使用 [NSBundle mainBundle] 写入文件失败

ios - fatal error : unexpectedly found nil while unwrapping an Optional value - delegate

objective-c - UITableView 数据源和委托(delegate)不会连接到自定义类

cocoa-touch - 启用预览和分页的 UICollectionView

iphone - UITableViewCell,出队和自动释放?

ios - 如何通过第三级关系过滤核心数据获取请求

objective-c - 使用 ParseKit 语法来解析时间戳

objective-c - 在 TextView 中搜索字符串的出现

objective-c - iOS 设置与模型捆绑

ios - Safari IOS 中的 HTML5 视频尺寸