我最终按照我在编辑中的建议进行了操作——用于motionEnded:withEvent
手动管理警报和撤消。这样做的缺点是你没有得到内置的撤消警报,它的风格与 a 略有不同,UIAlertView
并以摇晃的动作进入屏幕。
好处是我现在有一个 10 秒后过期的撤消。以下是代码的一般结构,以防您想要相同的内容。
首先,确保您的应用可以接收震动事件并且您有一个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,以便我可以检查它是否在我的警报回调中被触发,这里是:
- (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;
}
在警报回调中,我们要么使撤消发生,要么,如果在警报可见并且警报被取消时触发计时器,我们清除可能的撤消操作。否则,撤消操作将在取消后挂起,没有计时器来清除它。
希望这对某人有帮助!