在没有延迟的情况下进行同步时显示的加载屏幕

时间:2013-06-10 15:52:07

标签: ios objective-c cocoa-touch

如果时间花在我身上,我会花很多时间找不到完美的解决方案。

我正在制作一个包含大量项目的表格视图的应用程序。如果单击某个项目,则会打开一个带有网页的Webview控制器,此视图中有一个后退按钮。

我通过我制作的API获取这些项目的数据。这可能需要一些时间,因此我需要一个加载屏幕,同时从API加载项目。但是,当项目同步并且上次同步时间不超过X时间时,它不应该执行API调用,而只是从Core Data(在API调用之后存储它)中获取它。

现在我正在加载屏幕。一些要求:

  • 如果需要同步数据,则应直接显示加载屏幕:
    • 应用程序启动时,或
    • 单击Webview中的后退按钮或
    • 将应用程序放在后台并显示回前景,并将“表视图”作为活动视图
  • 如果不需要同步数据,则表视图应直接显示在与上一点相同的情况中
  • 从加载屏幕到表格视图的过渡动画应该是Cross Dissolve。
  • 我打算让加载屏幕上有一张带有一些照片的滑块,所以它不能只是一个叠加图像

    我首先尝试过这样:

Loading screen as push segue

此处加载屏幕是导航控制器之后的第一个视图。如果数据已同步,我将segue调用表视图(在viewWillAppear中)。如果数据未同步,它将等待直到它同步。在Table View Controller的viewWillAppear方法中,我还检查是否需要完成同步(如果你从Webview回来,或者App到达前台),如果是,我打电话给[self.navigationController popViewControllerAnimated:NO](所以它会回到加载屏幕。)

这很好用,从Webview到加载屏幕的动画变得流畅,我没有看到它们之间的表视图。但我无法修改动画,因为它是推动。所以我不能拥有溶解动画。

所以我尝试了另一种方法:

Loading screen with modal segues

在这里我做了Modal segues。在从表视图到加载屏幕的那个上,我禁用了动画,并且从加载屏幕到导航控制器的一个我给了交叉解析转换。它需要返回导航控制器,否则我在表视图中没有导航控制器。

在表格视图中,我再次检查数据是否需要同步,如果是,则转到加载屏幕。但是,这次我需要在viewDidAppear中执行此操作,因为viewWillAppear中尚未显示加载屏幕,当您将应用程序置于后台时会发出警告,等待直到X时间已经传递(所以它将同步)并再次将应用程序放到前台。这是我得到的警告:

Warning: Attempt to present <BWLoadingScreenViewController: 0x829e2b0> on <UINavigationController: 0x856a6b0> whose view is not in the window hierarchy!

所以我使用viewDidAppear并且我没有警告,但是,这种方法也有缺点:

  • 当我从Webview返回并且X时间已经过去(因此它会同步)时,我看到推送动画首先进入表视图,然后它闪烁到加载屏幕,非常难看...

现在我当然可以在整个地方使用手动分段,并且在每次segue检查之前是否需要同步数据,如果是这样,则加载屏幕而不是另一个,但这对于这么简单的事情来说会变得非常复杂,我也希望有一个通用位置来检查是否需要同步,并显示加载屏幕。

有没有人有任何想法如何以一种干净整洁的方式解决这个难题?建议非常欢迎。我仍然是iOS开发的新手,所以也许你可以给我一些新的见解。如果您想了解有关我的设置的更多信息,请问我。

2 个答案:

答案 0 :(得分:0)

您可以直接将加载屏幕(例如UIImageView)添加到您的MasterViewController(需要成为UIViewController而不是UITableViewController)并且只需执行以下操作:

myImageView.hidden = NO;

myImageView.hidden = YES;

取决于您是否从API获取数据。您还可以执行多个对象(例如,添加UIActivityIndicatorView

答案 1 :(得分:0)

好的,我找到了办法。

我发现你可以在推动时自定义segue动画。在这篇小文章的帮助下: http://blog.jambura.com/2012/07/05/custom-segue-animation-left-to-right-using-catransition/

基本上你做了一个自定义的segue类:

头:

#import <UIKit/UIKit.h>

@interface BWLoadingScreenSegue : UIStoryboardSegue

@end

实现:

#import "BWLoadingScreenSegue.h"
#import "QuartzCore/QuartzCore.h"

@implementation BWLoadingScreenSegue

- (void)perform
{

    UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
    UIViewController *destinationController = (UIViewController*)[self destinationViewController];

    CATransition* transition = [CATransition animation];
    transition.duration = .25;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionFade;

    [sourceViewController.navigationController.view.layer addAnimation:transition forKey:kCATransition];
    [sourceViewController.navigationController pushViewController:destinationController animated:NO];

}

@end

您需要将QuartzCore框架添加到链接的框架中才能使其工作。然后你可以选择segue,选择'Style'='Custom'和'Segue Class'=你的segue类名(带上面的代码)。现在,由于方法pushViewController,它仍然是一个推动,并且由于transition.type = kCATransitionFade;它将是一个淡入淡出过渡。很好。

您可以选择更多转场,例如:

kCATransitionMoveIn
kCATransitionPush
kCATransitionReveal
kCATransitionFade