2012-01-29 60 views
2

我將描述我通常要做的事情(以防有更好的方法),然後是我遇到的絆腳石(如果我的方式是最好的辦法)。檢測NSUndoManager的警報視圖是否可見

我想做什麼:我想添加一個調用到我的撤消管理器有時間限制。如果在時間限制內沒有觸發撤銷,當設備震動時它將不可用,因此不會發生任何事情。

我在做什麼:我的方法是使用NSUndoManagerNSTimer。當我將調用添加到撤消管理器時,我也啓動了5秒鐘的定時器。當計時器觸發時,它會檢查!self.undoManager.isUndoing,如果它是真的,則繼續執行,並從撤消管理器中刪除所有操作。在模擬器中測試它的工作原理:一個搖擺手勢在5秒之前開始撤消,但不能在之後。

的問題是,如果我在5秒極限擺動姿態,撤消管理器將顯示警報,但如果用戶等待直到5秒的限制後,實際挖掘撤銷按鈕,沒有任何反應:在即使警報視圖可見,計時器也很高興地清除堆棧。

有沒有辦法檢查並查看警報視圖是否可見?最好的辦法是,如果我能確定用戶是否還擊或取消了撤消按鈕,則清除撤消管理器的操作堆棧。

或者除了以這種方式使用計時器還有更好的方法嗎?

謝謝!

編輯補充:我的其他想法是捕捉到抖動事件自己(通過motionEnded:withEvent:調用)和手動管理警報,並撤消堆棧。與此相比的思考也是受歡迎的。

+1

我認爲使用motionEnded:withEvent方法是要走的路。 UIAlertView中基本上是一個UIWindow,說不定什麼時候讓你知道撤消警報視圖被駁回你的主應用程序的窗口再次成爲關鍵,你可以檢查。 – 2012-01-29 17:29:25

+0

嗯,好點。我想我會和motionEnded一起去的。如果有效,我會在這裏回答。謝謝! – kevboh 2012-01-30 16:52:43

回答

0

我完成了我在編輯中建議的操作 - 使用motionEnded:withEvent手動管理警報和撤消。缺點是你沒有得到與UIAlertView風格略有不同的內置撤消警報,並以搖動的動作進入屏幕。

好處是我現在有一個撤銷,在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_這裏伊娃跟蹤,如果我的警告是在屏幕上。

在你的計時器的回調,這樣做:

if (!self.undoManager.isUndoing && !undoAlertIsVisible_) { 
    // Clear away the possible undo 
    [self.undoManager removeAllActionsWithTarget:self]; 
} 
undoTimer_ = 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; 
} 

在警報回調,我們要麼使撤消發生,或者,如果計時器所觸發,而警報可見並且警報已取消,我們清除可能的撤消操作。否則,取消操作將在取消後沒有定時器來清除它。

希望這可以幫助別人!