我有一个响应用户输入的应用程序,但是有一些段我们不希望用户能够以任何方式中断动画效果。为了实现这一点,我有一个类,它与任何应该响应用户输入的对象/场景链接/实例化。在进行任何进一步处理之前,该类中的每个方法(开始,移动,结束)都会检查以下类级“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秒延迟是我选择的任意值,但我讨厌这样做,所以我正在寻找一种方法让应用程序在出现问题时“感觉”并且用户交互已被禁用太长时间
感谢您提供任何帮助....
答案 0 :(得分:3)
UIApplication有两种方法可以做到这一点:beginIgnoringInteractionEvents
和endIgnoringInteractionEvents
。
文档为here
如果您想禁用某些区域,这不是正确的方法。
为此,最简单的方法是添加一个视图,覆盖要阻止的部分,并启用/禁用该视图上的交互。一个简单,清晰的UIView与交互启用将吞下通往下方视图的所有触摸。关闭互动,触摸将通过。
如果按钮不适合漂亮的矩形,你可以看一下覆盖一些触摸处理方法(可能是hitTest:withEvent:
),只允许在某些点触摸。