我是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
}
}
非常感谢任何建设性的想法或帮助
答案 0 :(得分:1)
[self.tableView reloadData]
)[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。