2010-05-15 63 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

相關問題