UITextField键盘在加载时会阻止runloop吗?

时间:2012-01-14 13:58:52

标签: iphone objective-c ios cocoa-touch

因为我发现键盘的第一次加载时间很长(甚至使用iphone4S ios 5)这是一个恼人的问题,我正在尝试实现一个自定义的UITextField,它显示一个UIActivityIndi​​cator,如果键盘花了太长时间加载。但是,我发现在键盘加载时无法将UIActivityIndi​​cator添加到superview。如果设置较短的延迟,或者指示器显示方式太晚,当键盘出现时,活动指示器显示太快,当我设置稍长的延迟时(0.3毫秒,但实际上需要1秒以上) ,当键盘加载时。)

我已经尝试使用performSelector:withObject:afterDelay:inModes:在NSRunLoopCommonModes中设置我的活动指示器,但似乎键盘加载阻止了这种模式。我也试过使用GCD,但似乎我遇到了必须在与键盘加载和显示相同的调度队列中进行活动指示器设置的相同问题。如何在键盘加载时添加活动指示器视图?这是我的代码:

@interface CustomTextField : UITextField {
    UIActivityIndicatorView *spinner;
    CGPoint spinnerCenter;
    BOOL shouldShowSpinner;    
}
@property (assign) UIActivityIndicatorView *spinner;
@property (assign) CGPoint spinnerCenter;
@property (assign) BOOL shouldShowSpinner;
- (void)stopSpinner;
@end


@implementation CustomTextField

@synthesize spinner;
@synthesize spinnerCenter;
@synthesize shouldShowSpinner;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.spinnerCenter = self.frame.origin;
        self.spinner = nil;
        shouldShowSpinner = NO;
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(stopSpinner) 
                                                     name:UIKeyboardDidShowNotification 
                                                   object:nil];
    }
    return self;
}

- (void)stopSpinner
{
    shouldShowSpinner = NO;
    if (spinner != nil) {
        [spinner removeFromSuperview];
        spinner = nil;
    }
}


- (void)loadSpinner
{
    if (shouldShowSpinner) {
        CGRect rect = CGRectMake(spinnerCenter.x - 15, spinnerCenter.y - 15, 30, 30);
        self.spinner = [[[UIActivityIndicatorView alloc] initWithFrame:rect] autorelease];
        [spinner startAnimating];
        [theSuperview addSubview:spinner];
    }
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if ([self pointInside:point withEvent:event] && self.hidden == NO && self.isEditing == NO) {
        shouldShowSpinner = YES;

        // the GCD approach, have to be stuck on current dispatch queue?
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 300000000), dispatch_get_current_queue(), ^{
            if (shouldShowSpinner) {
                CGRect rect = CGRectMake(spinnerCenter.x - 15, spinnerCenter.y - 15, 30, 30);
                self.spinner = [[[UIActivityIndicatorView alloc] initWithFrame:rect] autorelease];
                [spinner startAnimating];
                [theSuperview addSubview:spinner];
            }
        });

        // The NSRunLoopApproach, NSRunLoopCommonModes blocked by keyboard loading?
        [self performSelector:@selector(loadSpinner) 
                   withObject:nil 
                   afterDelay:0.3 
                      inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
    }
    return [super hitTest:point withEvent:event];
}

0 个答案:

没有答案