2010-05-15 48 views
1

我有一个UITabbBarController与UITableView。在某些情况下,当用户从另一个视图到达时,TabBarControllers数据集需要更新,例如,第一次调用TabBarController时的初始加载或设置更改时的初始加载。设置视图准备UIActivityIndi​​catorView

此数据集更新大约需要2秒钟,我想显示一个UIActivityIndi​​catorView。

问题是,当我从另一个视图进入时,我不知道将哪个视图附加到视图,因为tabbarController的加载是在viewWillAppear方法中执行的。

任何线索我可以怎么做呢?

回答

2

我已经在viewDidAppear方法中做了这样的事情。我的代码启动后台任务来加载来自url的数据。它还将后台任务交给一个方法的选择器,以便在完成时调用控制器。这样通知控制器数据已被下载并可刷新。

我不知道这是否是做到这一点的最好办法,但到目前为止,它的工作对我罚款:-)

为了让一些更多的细节,除了方法的选择调用当后台任务已经加载数据时,我也是它在控制器上执行加载的方法的选择器。这种方式后台任务管理正在发生的事情,但视图控制器提供数据特定的代码。

这里有viewDidAppear代码:

- (void) viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    if (reloadData) { 
     BackgroundTask *task = [[BackgroundTask alloc] initWithMethod:@selector(loadData) onObject:self]; 
     task.superView = self.view.superview; 
     task.notifyWhenFinishedMethod = @selector(loadFinished); 
     [task start]; 
     [task release]; 
    } 
} 

后台任务有一个可选的SuperView,因为这将增加一个新的UIView包含一个活动的指标了。

BackgroundTask.m看起来是这样的:

@implementation BackgroundTask 

@synthesize superView; 
@synthesize longRunningMethod; 
@synthesize notifyWhenFinishedMethod; 
@synthesize obj; 

- (BackgroundTask *) initWithMethod:(SEL)aLongRunningMethod onObject:(id)aObj { 
    self = [super init]; 
    if (self != nil) { 
     self.longRunningMethod = aLongRunningMethod; 
     self.obj = aObj; 
    } 
    return self; 
} 

- (void) start { 
    // Fire into the background. 
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(execute:)object:nil]; 
    thread.name = @"BackgroundTask thread"; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskFinished:) name:NSThreadWillExitNotification object:thread]; 
    [thread start]; 
    [thread release]; 
} 

- (void) execute:(id)anObject { 

    // New thread = new pool. 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    if (self.superView != nil) { 
     busyIndicatorView = [[BusyIndicator alloc] initWithSuperview:self.superView]; 
     [busyIndicatorView performSelectorOnMainThread:@selector(addToSuperView)withObject:nil waitUntilDone:YES]; 
    } 

    // Do the work on this thread. 
    [self.obj performSelector:self.longRunningMethod]; 

    if (self.superView != nil) { 
     [busyIndicatorView performSelectorOnMainThread:@selector(removeFromSuperView)withObject:nil waitUntilDone:YES]; 
    } 

    [pool release]; 

} 

- (void) taskFinished:(NSNotification *)notification { 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:NSThreadWillExitNotification object:notification.object]; 
    [self performSelectorOnMainThread:@selector(notifyObject)withObject:nil waitUntilDone:NO]; 
} 

- (void) notifyObject { 
    // Tell the main thread we are done. 
    if (self.notifyWhenFinishedMethod != nil) { 
     [self.obj performSelectorOnMainThread:self.notifyWhenFinishedMethod withObject:nil waitUntilDone:NO]; 
    } 
} 

- (void) dealloc { 
    self.notifyWhenFinishedMethod = nil; 
    self.superView = nil; 
    self.longRunningMethod = nil; 
    self.obj = nil; 
    [super dealloc]; 
} 

@end 

最后,我说,我提出了一个活动的指标。我有一个xib,其中包含50%透明的蓝色背景,中间有一个活动指示器。有一个控制器它有这个代码:

@implementation BusyIndicator 

@synthesize superView; 
@synthesize busy; 


- (BusyIndicator *) initWithSuperview:(UIView *)aSuperView { 
    self = [super initWithNibName:@"BusyIndicator" bundle:nil]; 
    if (self != nil) { 
     self.superView = aSuperView; 
    } 
    return self; 
} 

- (void) addToSuperView { 

    // Adjust view size to match the superview. 
    [self.superView addSubview:self.view]; 
    self.view.frame = CGRectMake(0,0, self.superView.frame.size.width, self.superView.frame.size.height); 

    //Set position of the indicator to the middle of the screen. 
    int top = (int)(self.view.frame.size.height - self.busy.frame.size.height)/2; 
self.busy.frame = CGRectMake(self.busy.frame.origin.x, top, self.busy.frame.size.width, self.busy.frame.size.height); 

    [self.busy startAnimating]; 
} 

- (void) removeFromSuperView { 
    [self.busy stopAnimating]; 
    [self.view removeFromSuperview]; 
} 

- (void) dealloc { 
    self.superView = nil; 
    [super dealloc]; 
} 

@end 

好的这有助于。

+0

嗨Derek,仍在玩你的解决方案,但必须能够在viewWillAppear方法中实现,因为我必须在执行[super viewWillAppear]之前加载tabledata。当我通过我的测试时会回来。 在此先感谢,iFloh – iFloh 2010-05-16 15:14:54

相关问题