在准备好视图时设置 UIActivityIndi​​catorView [英] Setting UIActivityIndicatorView while view is prepared

查看:22
本文介绍了在准备好视图时设置 UIActivityIndi​​catorView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 UITableView 的 UITabbBarController.在某些情况下,当用户从另一个视图到达时,TabBarControllers 数据集需要更新,

I have a UITabbBarController with a UITableView. Under certain circumstances the TabBarControllers dataset requires updating when a user arrives from another view,

例如第一次调用 TabBarController 或更改设置时的初始加载.

e.g. the initial load when the TabBarController is called the first time, or when the settings are changed.

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

This dataset update takes about 2 seconds and I want to show an UIActivityIndicatorView.

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

Trouble is that when I enter from another view I don't know which view to attach it to, since the loading of the tabbarController is carried out in the viewWillAppear method.

有什么线索可以解决这个问题吗?

Any clues how I can go about this?

推荐答案

我在 viewDidAppear 方法中做过这样的事情.我的代码启动后台任务以从 url 加载数据.它还为后台任务提供一个方法选择器,以便在完成后在控制器上调用.这样控制器就会收到数据已经下载并且可以刷新的通知.

I've done this sort of thing in the viewDidAppear method. My code kicks off a background task to load the data from a url. It also hands the background task a selector of a method to call on the controller when it is done. That way the controller is notified that the data has been downloaded and can refresh.

我不知道这是否是最好的方法,但到目前为止它对我来说很好:-)

I don't know if this is the best way to do this, but so far it's working fine for me :-)

为了提供更多详细信息,除了后台任务加载数据时调用的方法的选择器之外,我还将它作为控制器上进行加载的方法的选择器.这样后台任务管理正在发生的事情,但视图控制器提供数据特定的代码.

To give some more details, in addition to the selector of the method to call when the background task has loaded the data, I also and it a selector of a method on the controller which does the loading. That way the background task manages whats going on, but the view controller provides the data specific code.

这是 viewDidAppear 代码:

Here's there viewDidAppear code:

- (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.

The background task has an optional superView because it will add a new UIView to it containing an activity indicator.

BackgroundTask.m 看起来像这样:

BackgroundTask.m looks like this:

@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% 透明的蓝色背景,中间有一个活动指示器.它有一个控制器,其中包含以下代码:

Finally as I said I put up a activity indicator. I have a xib which contains a 50% transparent blue background with an activity indicator in the middle. There is a controller for it which has this code:

@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

希望这会有所帮助.

这篇关于在准备好视图时设置 UIActivityIndi​​catorView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆