2011-08-18 69 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