我正在尝试在自定义tableview中显示数据。想法是在ViewController中我将数据填充到Core Data实体中,在ViewController B中我成功地从Core Data实体检索数据并在表视图中显示它没有问题。这就是问题所在。如果我从ViewController B中的entity和tableview中删除数据,请返回ViewController A并再次向Core Data添加新项目,当我返回ViewController B时,它不会出现在tableview中。但如果我再次关闭并打开应用程序,该项目再次出现在那里。
所以问题是项目在删除项目并再次插入后出现在核心数据中,但没有出现在tableview中。也许我不得不以某种方式更新tableview,但我试过[self.tableview reloadData];它没有帮助。代码如下。任何想法???
ViewController A
#import "ListItem.h"
#import "ViewOrders.h"
#import "MainView.h"
#import "Order_list.h"
#import "AppDelegate.h"
@interface ListItem ()
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *results;
@property (nonatomic, strong) NSMutableArray *namesArray;
@property (nonatomic, strong) NSMutableArray *quantityArray;
@property (nonatomic, strong) NSMutableArray *priceArray;
@property (nonatomic, strong) NSMutableArray *imagesArray;
@end
@implementation ListItem
@synthesize managedObjectContext = _managedObjectContext;
@synthesize results = _results;
@synthesize imageView = _imageView;
@synthesize mainView = _mainView;
@synthesize nameField = _nameField;
@synthesize descField = _descField;
@synthesize priceField = _priceField;
@synthesize quantityField = _quantityField;
@synthesize quantityStepperOutlet = _quantityStepperOutlet;
@synthesize namesArray =_namesArray;
@synthesize quantityArray = _quantityArray;
@synthesize priceArray = _priceArray;
@synthesize imagesArray = _imagesArray;
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = delegate.managedObjectContext;
//self.navigationItem.hidesBackButton = YES;
self.namesArray = [[NSMutableArray alloc] init];
self.quantityArray = [[NSMutableArray alloc] init];
self.priceArray = [[NSMutableArray alloc] init];
self.imagesArray = [[NSMutableArray alloc] init];
UIGraphicsBeginImageContext(self.view.frame.size);
[[UIImage imageNamed:@"bella_italia_crop.png"] drawInRect:self.view.bounds];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.view.backgroundColor = [UIColor colorWithPatternImage:image];
UIGraphicsBeginImageContext(self.mainView.frame.size);
[[UIImage imageNamed:@"bella_italia_crop.png"] drawInRect:self.mainView.bounds];
UIImage *image2 = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.mainView.backgroundColor = [UIColor colorWithPatternImage:image2];
self.imageView.image = [UIImage imageNamed:self.thumbnail];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.nameField.text = self.name;
self.descField.text = self.description;
self.priceField.text = self.price;
self.descField.backgroundColor = [UIColor clearColor];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"viewAllOrdersSegue"])
{
ViewOrders *vo = segue.destinationViewController;
vo.namesArray = self.namesArray;
vo.quantityArray = self.quantityArray;
vo.priceArray = self.priceArray;
vo.tableNumber = @"1";
vo.imagesArray = self.imagesArray;
}
else if ([segue.identifier isEqualToString:@"unwindToMain"])
{
MainView *mv = segue.destinationViewController;
mv.namesArray = self.namesArray;
mv.quantityArray = self.quantityArray;
mv.priceArray = self.priceArray;
mv.imagesArray = self.imagesArray;
}
}
- (IBAction)quantityStepper:(UIStepper *)sender
{
int stepper = [sender value];
self.quantityField.text = [NSString stringWithFormat:@"%d", stepper];
}
- (IBAction)addOrderAction:(UIButton *)sender
{
NSLog(@"Add order action button pressed");
Order_list *newItem = [NSEntityDescription insertNewObjectForEntityForName:@"Order_list" inManagedObjectContext:self.managedObjectContext];
newItem.title = self.name;
newItem.quantity = @([self.quantityField.text floatValue]);
newItem.price = @([self.priceField.text floatValue]);
newItem.tableNumber = [NSNumber numberWithInt:1];
newItem.thumbnail = self.thumbnail;
newItem.id = [NSNumber numberWithInt:0];
NSError *error;
[self.managedObjectContext save:&error];
UIAlertView *successAlert = [[UIAlertView alloc] initWithTitle:@"Success!" message:@"Your order was successfully added to orders list! Press View Orders to finalize the order or go back to menu and choose something else." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
successAlert.alertViewStyle = UIAlertViewStyleDefault;
[successAlert show];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Order_list" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObjectContext *info in fetchedObjects) {
NSLog(@"Title: %@ %@", [info valueForKey:@"title"], [info valueForKey:@"quantity"]);
}
//[self.namesArray addObject:self.name];
//[self.quantityArray addObject:self.quantityField.text];
//int finalPrice = [self.quantityField.text intValue] * [self.price intValue];
//[self.priceArray addObject:[NSString stringWithFormat:@"%d", finalPrice]];
//[self.imagesArray addObject:self.thumbnail];
//NSLog(@"Names: %@, Quantities: %@, Prices: %@", self.namesArray, self.quantityArray, self.priceArray);
}
@end
ViewController B
#import "ViewOrders.h"
#import "AppDelegate.h"
#import "Order_list.h"
#import "ViewOrdersCell.h"
@interface ViewOrders ()
@property (nonatomic, strong) NSMutableData *requestData;
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSFetchedResultsController *results;
@property (nonatomic, strong) NSString* orderState;
@property (nonatomic, strong) UIAlertView *billAlert;
@end
@implementation ViewOrders
@synthesize managedObjectContext = _managedObjectContext;
@synthesize results = _results;
@synthesize confirmOrderButton = _confirmOrderButton;
@synthesize requestData = _requestData;
@synthesize orderState = _orderState;
@synthesize billAlert = _billAlert;
- (void)viewDidLoad
{
[super viewDidLoad];
self.billAlert = [[UIAlertView alloc] initWithTitle:@"Order Confirmed!" message:@"Your order list has been successfully confirmed and is sent to kitchen! Press Request Bill Now or Request Bill Later to Continue (You cannot make any new orders until you request a bill for current one! To trigger this screen again, press and hold on any order in pending orders page. Thanks!)" delegate:self cancelButtonTitle:@"Request Bill Later" otherButtonTitles:@"Request Bill Now", nil];
self.billAlert.tag = 2;
self.billAlert.alertViewStyle = UIAlertViewStyleDefault;
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = delegate.managedObjectContext;
self.namesArray = [[NSMutableArray alloc] init];
self.quantityArray = [[NSMutableArray alloc] init];
self.imagesArray = [[NSMutableArray alloc] init];
self.priceArray = [[NSMutableArray alloc] init];
NSFetchRequest *coreRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Order_list" inManagedObjectContext:self.managedObjectContext];
[coreRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
[coreRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[coreRequest setFetchBatchSize:20];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:coreRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
self.results = controller;
self.results.delegate = self;
NSError *error;
[self.results performFetch:&error];
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:coreRequest error:&error];
for (NSManagedObjectContext *info in fetchedObjects)
{
self.orderState = [NSString stringWithFormat:@"%@", [info valueForKey:@"id"]];
[self.namesArray addObject:[info valueForKey:@"title"]];
[self.quantityArray addObject:[info valueForKey:@"quantity"]];
[self.imagesArray addObject:[info valueForKey:@"thumbnail"]];
[self.priceArray addObject:[info valueForKey:@"price"]];
//NSLog(@"List: %@", [info valueForKey:@"title"]);
}
if ([self.orderState isEqualToString:@"1"])
{
self.confirmOrderButton.enabled = false;
}
//self.navigationController.navigationItem.backBarButtonItem.enabled = false;
//self.navigationItem.hidesBackButton = YES;
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id sectionInfo = [[self.results sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ordersCell" forIndexPath:indexPath];
ViewOrdersCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ordersCell" forIndexPath:indexPath];
cell.title.text = [self.namesArray objectAtIndex:indexPath.row];
cell.thumbnail.image = [UIImage imageNamed:[self.imagesArray objectAtIndex:indexPath.row]];
cell.status.text = @"Waiting to Confirm";
if ([self.orderState isEqualToString:@"0"])
{
cell.status.text = @"Waiting to Confirm";
cell.status.textColor = [UIColor redColor];
}
else
{
cell.status.textColor = [UIColor greenColor];
cell.status.text = @"Confirmed";
}
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onLongPress:)];
[cell addGestureRecognizer:longPressRecognizer];
//cell.textLabel.text = [self.namesArray objectAtIndex:indexPath.row];
//cell.imageView.image = [UIImage imageNamed:[self.imagesArray objectAtIndex:indexPath.row]];
//cell.backgroundColor = [UIColor clearColor];
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source
NSManagedObject *managedObject = [self.results objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:managedObject];
[self.managedObjectContext save:nil];
//[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
//[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
if (type == NSFetchedResultsChangeInsert)
{
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}
if (type == NSFetchedResultsChangeDelete)
{
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
if (type == NSFetchedResultsChangeUpdate)
{
}
if (type == NSFetchedResultsChangeMove)
{
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
if (type == NSFetchedResultsChangeInsert)
{
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
}
if (type == NSFetchedResultsChangeDelete)
{
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
}
}
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1 && alertView.tag == 1)
{
NSLog(@"Confirm Pressed");
//////Send Order to the Server//////
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Order_list"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id=0"];
fetchRequest.predicate = predicate;
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObjectContext *info in array)
{
NSNumber *temp = [[NSNumber alloc] initWithInt:1];
[info setValue:temp forKey:@"id"];
}
[self.managedObjectContext save:&error];
[self.tableView reloadData];
self.confirmOrderButton.enabled = false;
[self.billAlert show];
}
else if (buttonIndex == 1 && alertView.tag == 2)
{
self.confirmOrderButton.enabled = true;
UIAlertView *billRequest = [[UIAlertView alloc] initWithTitle:@"Bill Request Successful!" message:@"Your bill has been requested successfully! Waiter will deliver it to you as soon as possible! Thanks for visiting Bella Italia!" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
billRequest.alertViewStyle = UIAlertViewStyleDefault;
billRequest.tag = 3;
[billRequest show];
NSFetchRequest *fetchItems = [[NSFetchRequest alloc] init];
[fetchItems setEntity:[NSEntityDescription entityForName:@"Order_list" inManagedObjectContext:self.managedObjectContext]];
[fetchItems setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:fetchItems error:&error];
[self.results performFetch:&error];
//error handling goes here
for (NSManagedObject *item in array)
{
[self.managedObjectContext deleteObject:item];
}
NSError *saveError = nil;
[self.managedObjectContext save:&saveError];
}
else if (buttonIndex == 0 && alertView.tag == 2)
{
}
else if (buttonIndex == 0 && alertView.tag == 3)
{
[self.navigationController popToRootViewControllerAnimated:UITableViewRowAnimationFade];
}
}
- (IBAction)confirmOrder:(UIBarButtonItem *)sender
{
NSLog(@"Confirm Order");
UIAlertView *confOrder = [[UIAlertView alloc] initWithTitle:@"Confirm Order!" message:@"This will send your order to process. Once this is done, no more changes are available. Are you sure you want to confirm your order?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Confirm", nil];
confOrder.alertViewStyle = UIAlertViewStyleDefault;
confOrder.tag = 1;
[confOrder show];
}
-(void)onLongPress:(UILongPressGestureRecognizer*)pGesture
{
NSLog(@"Long Press");
[self.billAlert show];
}
@end
修改 忘了提到我正在使用Custom Cell。也许这会以某种方式影响局势? 我试图NSLog存储应该出现在tableview中的数据的变量。所有数据都已通过,但它没有出现在tableview中。逻辑上[view.WillAppear中的[self.tableView reloadData应该可以做到这一点,但它没有........
答案 0 :(得分:0)
我在一个应用程序中有类似的设置,我在ViewController中添加了一个观察者,其中包含要更新的表格;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reload) name:@"UpdatedCoreData" object:nil];
我清除了我在reload方法中使用的任何数组或字典并调用(在我的异步队列中);
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
然后当我完成更新我的其他VC中的核心数据时,我称之为
[[NSNotificationCenter defaultCenter] postNotificationName:@"UpdatedCoreData" object: nil];
这对我来说非常好,我不知道这对你是否会有所帮助。
修改强>
按照我的重载方法;
- (void)reload {
// Do any potential clean up if neccesary
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// Fetch core data & populate dictionaries/arrays
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
});
}