2011-08-18 92 views
1

當用戶點擊一個按鈕時,一個動作開始,但如果用戶快速點擊10次按鈕,它將執行10次。我想禁用不會生效,直到控制從事件返回。禁止重複按鈕點擊緩衝

- (IBAction)btnQuickCheckClick:(id)sender { 
    @try { 
    self.btnQuickCheck.enabled = NO ; 
    // Next line takes about 3 seconds to execute: 
    [self pollRouter] ; 
    } 
    @finally { 
    self.btnQuickCheck.enabled = YES ; 
    }  
} 
+0

你自己回答了這個問題。您正在同步進行輪詢,所以UI從來沒有機會更新以禁用按鈕。 – Flyingdiver

回答

1

您可以通過查詢之前禁用按鈕後,運行運行的循環更新UI:

- (IBAction)btnQuickCheckClick:(id)sender { 
    self.btnQuickCheck.enabled = NO; 
    // give some time for the update to take place 
    [self performSelector:@selector(pollRouterMethod) withObject:nil afterDelay:0.1]; 
} 
- (void)pollRouterMethod { 
    @try { 
     [self pollRouter]; 
    } @catch (NSException * e) { } 
    // re-enable the button 
    self.btnQuickCheck.enabled = YES; 
} 

當然,這種方法適用於運行時間密集的任務在另一個線程的替代品。對於長期任務,多線程幾乎總是要走的路。

+0

有一個麻煩的是,它基本上是「菊花鏈」,所以如果我有一個接口後,我不想在pollRouterMethod它,我必須做更多的技巧。儘管如此。 –

+0

我重新安排了一點程序結構並使用了這種方法。因爲我不想調整「pollRouterMethod」中的接口(如上所述),我使用了3種方法:1 buttonClickMethod禁用按鈕並執行performSelector技巧,它指向: 2 updateRouterMethod直接調用pollRouterMethod然後重新調用 - 啓用按鈕。 –

+0

我重新安排了一點程序結構並使用了這種方法。因爲我不想訪問「pollRouterMethod」中的按鈕界面(如上所述),所以我使用了3種方法: *** 1 *** buttonClickMethod禁用按鈕並執行performSelector技巧,該技巧指向: ** * 2 *** updateRouterMethod直接調用*** 3 *** pollRouterMethod然後控制返回到*** 2 ***,這將重新啓用按鈕。 ///謝謝 –

1

另一種方式來做到這一點是塊:

大優點:你不需要創建一個額外的方法:)

- (IBAction)btnQuickCheckClick:(id)sender { 
    //UI changes must be done in the main thread 
    self.btnQuickCheck.enabled = NO; 

    //do your thing in a background thread 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT ,0); 
    dispatch_async(queue, ^(){ 
     @try { 
      //do your thing here 
      [self pollRouter]; 

     } @catch (NSException * e) { 
      //handle the exception, if needed 

     } @finally { 
      //change to the main thread again and re-enable the UI 
      dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
      dispatch_async(mainQueue, ^(){ 
       self.btnQuickCheck.enabled = YES; 
      }); 
     } 
    }); 
} 

這將運行在後臺線程pollRouter。所以如果你沒有修改用戶界面或其他非線程安全的東西在那裏,你想使用這種方法:)否則去@亞歷克斯的方法

+0

謝謝 - 很好的例子。然而,在這種情況下,該應用程序是一個單用途的路由器輪詢應用程序,所以我希望在輪詢發生的幾秒鐘內鎖定它。 –

+0

我再仔細看看...... –

+0

這不會鎖定任何東西。事實上,在執行'pollRouter'時不會鎖定事物。 'pollRouter'是在另一個線程中完成的,所以即使你正在做大量的或耗時的工作,它也不會影響用戶界面。 – nacho4d