加载新页面时动画微调器

时间:2012-01-24 16:23:01

标签: objective-c ios xcode

我有一个来自外部RSS源的UITableView。

当你选择一行它使用navigationController并从右边滑入时,问题是RSS提要包含图像,因此它可能需要几秒钟才能加载,而且没有任何迹象表明你发生了什么,你可能会误认为对于应用程序崩溃。

我决定添加一个微调器,以便您知道正在加载新页面。

这是我的代码:

RootViewController.m

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Loading New Page");

[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailsViewController *detailViewController = [[DetailsViewController alloc] initWithNibName:@"DetailsViewController" bundle:nil];
detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
[self.view addSubview:spinner];
[spinner startAnimating];
[spinner release];

}

DetailsViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];

        NSString *imgURL = [item objectForKey:@"image"];
        NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imgURL]];
        item_photo.image = [[UIImage alloc] initWithData:mydata];

    item_title.text = [item objectForKey:@"title"];
    item_date.text = [NSString stringWithFormat:@"Date: %@",[item objectForKey:@"date"]];
    item_time.text = [NSString stringWithFormat:@"Time: %@",[item objectForKey:@"time"]];
    item_cost.text = [NSString stringWithFormat:@"Cost: £%@",[item objectForKey:@"cost"]];
    item_info.text = [item objectForKey:@"description"];
    self.navigationItem.title = @"Event Type";
}

此代码存在两个问题。

  1. 直到新页面加载后,Spinner才会激活。
  2. 一旦加载,Spinner就不会禁用。
  3. 如果有人能帮我解决这个问题,我将非常感激。

3 个答案:

答案 0 :(得分:24)

您正在将活动指示器视图添加到控制器的视图中,该控制器正在推动详细视图控制器,因此您无论如何都不会看到它

尝试将第二组代码移动到DetailsViewController的viewDidLoad方法,您可以在加载完成后在活动指示器上调用stopAnimating。要获得对UIActivityIndi​​cator的引用,您应该添加标记

e.g。在viewDidLoad

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
spinner.tag = 12;
[self.view addSubview:spinner];
[spinner startAnimating];
[spinner release];
在loadingFinished方法中(完成加载时调用的方法)

[[self.view viewWithTag:12] stopAnimating];

答案 1 :(得分:3)

您需要在后台线程中完成一些工作。如果以下行是花费时间的行:

detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)];

然后你可以在后台使用GCD执行此操作:

UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    // This is the operation that blocks the main thread, so we execute it in a background thread
    id item = [rssItems objectAtIndex:floor(indexPath.row/2)];

        // UIKit calls need to be made on the main thread, so re-dispatch there
        dispatch_async(dispatch_get_main_queue(), ^{
            detailViewController.item = item;
            [spinner stopAnimating];
        });
});

+1到@ wattson12 - 您需要将微调器添加到新视图中。或者,您可以将微调器添加到当前视图,而是将pushViewController调用放入GCD主队列块。

最后一点 - 一旦你停止动画制作,你就会想要从它的超级视图中删除微调器。或者,您可以拥有一个微调器实例,并将hidesWhenStopped设置为YES。

答案 2 :(得分:1)

这是一个在swift模糊视图上方的旋转轮:

func blurScence(){
    let blurEffect: UIBlurEffect = UIBlurEffect(style: .Dark)
    let blurView: UIVisualEffectView = UIVisualEffectView(effect: blurEffect)
    blurView.translatesAutoresizingMaskIntoConstraints = false
    blurView.frame = self.view.frame

    let spinner = UIActivityIndicatorView(activityIndicatorStyle:.White)
    spinner.center=blurView.center
    blurView.addSubview(spinner)
    spinner.startAnimating()

    self.view.addSubview(blurView)
}