启用和禁用应用程序中的所有用户输入

时间:2014-07-12 13:13:36

标签: ios objective-c scheduler user-interaction

我有一个响应用户输入的应用程序,但是有一些段我们不希望用户能够以任何方式中断动画效果。为了实现这一点,我有一个类,它与任何应该响应用户输入的对象/场景链接/实例化。在进行任何进一步处理之前,该类中的每个方法(开始,移动,结束)都会检查以下类级“allowInput”方法:

//  application-level flag indicating if user touch/click input is currently enabled...
static BOOL g_fAllowUserInput_ = YES;


//  these class-level methods can be called from multiple threads, so create a single-thread-only
//  lock for accessing the current mode...
#import <pthread.h>
static pthread_mutex_t _mutexSerializeCurrentModeAllowInput = PTHREAD_MUTEX_INITIALIZER;


//  global class methods to handle application-wide user touch/click input permissions...
@implementation TouchHandler ( Allow )


//  report if user touch/click input is allowed...
+ ( BOOL ) allowUserInput

{

    //  access the single-thread-only lock...
    pthread_mutex_lock( &_mutexSerializeCurrentModeAllowInput );

    //  get the current mode...
    BOOL const mode = g_fAllowUserInput_;

    //  release the single-thread-only lock...
    pthread_mutex_unlock( &_mutexSerializeCurrentModeAllowInput );

    //  return the current "touch enabled" status...
    return mode;

}  //  end TouchHandler ( Allow )::allowUserInput


//  enable/disable user touch/click input...
+ ( void ) setAllowUserInput: ( BOOL const ) allow

{

    //  access the single-thread-only lock...
    pthread_mutex_lock( &_mutexSerializeCurrentModeAllowInput );

    //  regardless of what the current status is, we need to unschedule the automatic "force allow input"
    //  method, if it's running, since the application is still functioning properly...
    [ [ [ CCDirector sharedDirector ] scheduler ] unscheduleSelector: @selector( forceAllowInput: )
                                                           forTarget: self
    ];

    //  set the new "input enabled" status...
    g_fAllowUserInput_ = allow;

    //  if user input is supposed to be suspended...
    if ( ! allow )

        {

        //  schedule the automatic "force allow input" method, to make sure that we don't block out the
        //  user if something gets "screwy" in the application...
        [ [ [ CCDirector sharedDirector ] scheduler ] scheduleSelector: @selector( forceAllowInput: )
                                                             forTarget: self
                                                              interval: 5.0f
                                                                paused: NO
        ];

        }  // end disable user input

    //  release the single-thread-only lock...
    pthread_mutex_unlock( &_mutexSerializeCurrentModeAllowInput );

    return;

}  //  end TouchHandler ( Allow )::setAllowUserInput


//  scheduled method to force-enable user input if it's been disabled for an unexpected duration...
+ ( void ) forceAllowInput: ( ccTime ) delta

{

    //  access the single-thread-only lock...
    pthread_mutex_lock( &_mutexSerializeCurrentModeAllowInput );

    //  remove this method from the scheduler, since it's only necessary to fire it once...
    [ [ [ CCDirector sharedDirector ] scheduler ] unscheduleSelector: @selector( forceAllowInput: )
                                                           forTarget: self
    ];

    //  set the new "input enabled" status to "enabled"...
    g_fAllowUserInput_ = YES;

    //  release the single-thread-only lock...
    pthread_mutex_unlock( &_mutexSerializeCurrentModeAllowInput );

    return;

}  //  end TouchHandler ( Allow )::forceAllowInput


@end  //  end @implementation TouchHandler ( Allow )

“setAllowUserInput”在应用程序的不同位置被调用,具体取决于我是否希望暂停用户交互。

我的问题是:在几乎应用程序范围内,是否有更有效的方法来处理它?我说“差不多”因为至少有一个控件,一个按钮,它捕获当前屏幕并将其作为电子邮件附件发送,并且该控件需要始终处于活动状态。预定的5秒延迟是我选择的任意值,但我讨厌这样做,所以我正在寻找一种方法让应用程序在出现问题时“感觉”并且用户交互已被禁用太长时间

感谢您提供任何帮助....

1 个答案:

答案 0 :(得分:3)

UIApplication有两种方法可以做到这一点:beginIgnoringInteractionEventsendIgnoringInteractionEvents

文档为here

如果您想禁用某些区域,这不是正确的方法。

为此,最简单的方法是添加一个视图,覆盖要阻止的部分,并启用/禁用该视图上的交互。一个简单,清晰的UIView与交互启用将吞下通往下方视图的所有触摸。关闭互动,触摸将通过。

如果按钮不适合漂亮的矩形,你可以看一下覆盖一些触摸处理方法(可能是hitTest:withEvent:),只允许在某些点触摸。