重新加载RootView控制器或重新启动应用程序

时间:2011-10-20 14:33:28

标签: iphone ios

我是IOS编程的新手但是,我有一个问题,我已经坚持了一天以上,我找不到解决方案。我有一个应用程序,在安装后第一次运行时需要下载一些内容。下载完成后,作为RootView控制器的View不会刷新视图的数据。我可以导航到正确填充的其他视图,但此视图不是。如果我关闭应用程序并重新打开它,数据就在那里。所以我需要一种方法来强制视图完全重新加载或重新启动应用程序。

#import <UIKit/UIKit.h>

#import <CoreData/CoreData.h>

@interface RootViewController : UIViewController <NSFetchedResultsControllerDelegate>{

}
@property (nonatomic, retain) IBOutlet UIImageView *bannerImageView;
@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
-(void)populateBannerImages;
-(void)getimage;

这是我的.m文件

@implementation RootViewController
@end
- (void)viewDidLoad
    {
    [super viewDidLoad];
    self.navigationItem.title=@"MyTitle";

 }
- (void)viewWillAppear:(BOOL)animated
{

    [super viewWillAppear:animated];

    }

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    }

    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    }

    - (void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
    }
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return [[self.fetchedResultsController sections] count];
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:                                          (NSInteger)section
    {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    }
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";  
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle         reuseIdentifier:CellIdentifier] autorelease];
        }
        [self configureCell:cell atIndexPath:indexPath];
        return cell;
        }

我在app delegate中运行下载功能的对话框,下面是代码示例。我知道问题是我从appDidFinishLAunching调用UIAlert,并且rootViewController已经加载了,但我不确定是否有更好的方法来执行此操作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:    (NSDictionary *)launchOptions
{
    BOOL hasRunBefore=[[NSUserDefaults standardUserDefaults] boolForKey:@"FirstRun"];
    if (hasRunBefore) {
    }else if(!hasRunBefore){
        UIAlertView *firstRunAlert =[[UIAlertView alloc]initWithTitle:@"Welcome" message:@"" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"DownLoad", nil];
       [firstRunAlert show];
        [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"FirstRun"];
    }
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    NSString *buttontitle = [alertView buttonTitleAtIndex:buttonIndex];
    if ([buttontitle isEqualToString:@"DownLoad"]) {
/download stuff here
    }
}

非常感谢任何建设性的想法或帮助

3 个答案:

答案 0 :(得分:1)

  • 创建重新加载机制:通过NSNotificationCenter分配NSNotification,所有视图控制器都注册该通知。 (然后你可以重新执行fetchedResultsController的获取请求并调用[self.tableView reloadData]
  • 重新加载根视图控制器:让你的App Delegate下载文件然后创建一个新的RootViewController并调用[self.window setRootViewController:newController]这会重置整个视图(=&gt;糟糕的用户体验)

答案 1 :(得分:1)

假设您的核心数据保存和获取正确完成,最好的方法是通过NSNotificationCenter。在AppDelegate类中,您需要在下载数据后将通知发布到通知中心。这应该仅在数据下载完成后发布。也许是这样的:

[[NSNotificationCenter defaultCenter] postNotificationName:@"DataFinishedDownloading" 
                                                    object:self];

然后在RootViewController类中,首先需要注册RootViewController类来监听该通知。也许在init方法中:

-(id)init
{
    self = [super init];
    if(self)
    {
         // We add this instance of RootViewController class as an observer of the "DataFinishedDowloading"
         // Once this notification is posted to the notification center from appDelegate
         // RootViewController will be notified and the method inside selector will be called
         [[NSNotificationCenter defaultCenter] addObserver:self 
                                                  selector:@selector(receivedDataFinishedDownloadingNotification:)
                                                      name:@"DataFinishedDownloading"
                                                    object:nil];
    }

    return self;
}

- (void)receivedDataFinishedDownloadingNotification:(NSNotification*)notification 
{
    // Once the images are done downloading, you just need to refresh the tableView.  It will
    // then display the newly acquired data in your table cells.
    [tableView reloadData];
}

可能出现的唯一其他问题(也可能不是)如果数据下载发生得足够快。偶尔,如果数据速度足够快并且viewController的viewDidAppear尚未发生,则通知方法将在viewDidAppear发生之前尝试重新加载数据。这可能会导致蓝色月亮一次崩溃。通常在viewDidAppear中设置一个布尔值并在调用reloadData之前进行检查是一个好主意。希望这会有所帮助。

答案 2 :(得分:0)

使用NSNotificationCenter可能有点矫枉过正。由于您有NSFetchedResultsController,我会考虑将您的视图控制器设置为其委托并实施NSFetchedResultsControllerDelegate#controllerDidChangeContent:方法。

对于您的情况,该方法的最简单实现只需调用[tableView reloadData]。有关详细信息,请参阅the protocol's docs