ios - reloadData TableView & Core Data - objective-c

I am having a bit of trouble with reloading my tableView which is set in a UIViewController.
It is populated with CoreData (This works)
It is also got a custom TableViewCell for some design purposes
Now normally what I would use is this : [_mainTableView reloadData];
That does not work this time.
Is this because of the custom Cell or is Core Data's FetchRequest which loads fine initially and shows the data when I relaunch the app??
I have seen several questions and tutorials on SO and Google, but none of them seem to work in my case.
I have also explored these methods:
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
}
found here: beignUpdates
Any advice is appreciated.

Have you synthesized your table view? Please try this:
[self.mainTableView reloadData];
Hope, it'll work. And, since you reload it at viewWillAppear, please sure that neither it allocate new times nor it's delegate/datasource assign again, if it is then, first time, do something like that:
_mainTableView.delegate = nil;
_mainTableView.delegate = self;//similarly, for datasource...
And, you need to explicitly call your viewWillAppear(I suppose you're already doing this.)
Please let me know in any concern.
Thanks.

Thank you for the input, I finally got it sorted.
Instead of calling the [_mainTableView reloadData] I had to call the fetchmethod again.
if (_managedObjectContext == nil)
{
_managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSLog(#"After _managedObjectContext: %#", _managedObjectContext);
}
[self setupFetchedResultsController];

Related

tableView numberOfRowsInSection calls tableView viewForHeaderInSection on iOS4

I got a big app containing a lot of dependencies. For this case I implemented a class called RootTableViewController to handle all the stuff that has to be done everytime a table view controller is required.
Now I discovered an endless loop and I dont know how to fix it. I got the following code in RootTableViewController:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
int numbersOfRowInSection = [self.tableView numberOfRowsInSection:section];
if (numbersOfRowInSection > 0)
{
// ...
}
else
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 28.0f)];
return view;
}
}
This works perfect on iOS 5 and iOS 6, but on iOS4 it causes an endless loop, because [tableView numberOfRowsInSection] is calling [tableView viewForHeaderInSection]. How can I fix this using the table view api? Its no solution for me to work with the [ count] of internal data arrays because I got a lot of table view controllers extending this RootTableViewController with different data sources.
This is simply not good style. You are supposed to subclass or rahter implement the related delegate method but you shoudl not call UITableView.numberofRowsInSection:
However, you have certainly implemented tableView:numberOfRowsInSection. Move all of its functionality to the new method myNumberOfRowsInSection: In there do the same. It is mainly a copy of your current numberOfRowsInSection.
Then here in your code sniplet call [self myNumberOfRowsInSection:...];
And within tableView:numberOfRowsInSection:section just do:
return [self myNumberOfRowsInSection:section];
Apply the same pattern to all delegate methods that you may want to call yourself. Move all its business logic into your own method and then only call your own method from the delegate method and from your own code.
If you want to get the number of rows in a section of the data source without accessing the internal data array, you could query the dataSource delegate for it, something like
int numbersOfRowInSection = [self.tableView.dataSource tableView:self.tableView numberOfRowsInSection:section];
(not compiler checked)

Table View: setEditing programmatically

NSMutableArray *objects holds some objects which I use to display the content of my table view cells. If objects.count is 0 I would like to enable the editing mode of my table view when viewDidLoad:
- (void)viewDidLoad {
// If there is no content to present enable editing mode
if (self.objects.count == 0) [self setEditing:YES animated:YES];
}
This toggles the self.editButtonItem and inserts a new row (stating "Tap here to add a new element") into my table view:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:animated];
if (self.editing) {
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[self.objects count] inSection:0]]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
else {
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:[self.objects count] inSection:0]]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Unfortunately this setup results in a crash:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-1914.85/UITableView.m:833
Is it not possible to toggle the editing mode programmatically? If the user touches the self.editButtonItem everything works fine – and as far as I know, this editButton does the same I'm doing in viewDidLoad.
What am I doing wrong?
i think there are 2 different questions here.
one, it is possible to perform setEditing:animated: programmatically.
but i don't think that's what you really want to try to do here. the editing mode is for the user to manually edit the table, and present the little red button on the left, and possibly the little movement indicator on the right if you have those settings set.
the better thing to do is when you find your objects has changed, perform a [self.tableView reloadData];, and just make sure that your UITableViewDataSource protocol methods implemented do the right thing. this will include the implementation of tableView:numberOfRowsInSection: (and possibly also numberOfSections) and also tableView:cellForRowAtIndexPath: . this will cause the items to appear in the tableView as objects changes.

reloadData doesn't call cellforrowatindexpath

Maybe it's a similar beginning, but it's true.
first of all sorry if this isn't formatted correctly, first time doing this. I've been using stackoverflow to find help for a long time now and it's been very helpful (thank you all), but this is the first time I've posted a question of my own. This question has been asked many times, but when I call [self.tableView reloadTable] the methods numberOfSectionsInTableView and numberOfRowsInSection are called but not cellForRowAtIndexPath.
Every answer I've seen when searching has been a variation of:
The tableView is nil
numberOfRowsInSection is 0
tableView's delegate/data source not set. None of these are the case for me so I'm wondering what else could be wrong.
But I'm not sure 4. calling reloadTable on the wrong uiTableView. Or it's about some other false.
Now my APP is similar to dropbox,
first when we log into it, we get a file list(include directories) in the TableView.also, I added a toolbar in the bottom of the view by [self.navigationController.view addSubview:toolBar], when I touch the button item "refresh", it calls [self.tableView reloadData] and works well.
Second when we select a directory we will get a new file list table which is pushViewController by self.navigationController, but this time when we touch the "refresh", the statement [self.tableView reloadData] calls numberOfSections, numberOfRows, not cellForRowAtIndexPath
Any ideas as to why cellForRow's not being called the Second time? Thanks in advance.
FileListViewController.h
#interface FileListViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
FileListViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (isDir) {
FileListViewController *fileListViewController = [[FileListViewController alloc] init];
[self.navigationController pushViewController:fileListViewController animated:YES];
}
}
- (void)refresh
{
[Utilities refresh];//Utilities is my custom class.
[self viewDidLoad];
[self.tableView reloadData];
}
My return number of section and row in table view is not 0.
When I added NSLog(#"Calling reloadData on %#", self.tableView); into "refresh":
- (void)refresh
{
[Utilities refresh];//Utilities is my custom class.
[self viewDidLoad];
NSLog(#"Calling reloadData on %#", self.tableView);
[self.tableView reloadData];
}
Then it returns Calling reloadData on ; contentOffset: {0, 0}>. Delegate: FileListViewController, DataSource: FileListViewController
You should not manually call [self viewDidLoad]. This method is designed to be overridden, and is automatically called. For more information, please read this documentation.

How to update a cell in a UITableView?

I'm using Delegate methods to get data from child view and want to dynamically edit my table in the root view.
So I would like to do something like this in my viewWillAppear method :
[myTable setCell:newCell atIndex:i];
What should I do ? Thanks a lot
put your code in between:
[myTable beginUpdates];
//your code
[myTable setCell:newCell atIndex:i];
//your code end
[myTable endUpdates];
Well, finally I made it using :
[cellules beginUpdates];
[cellules reloadData];
[cellules endUpdates];
I used reloadData because it's a little TableView (3 cells), for big TableViews this should be better :
– reloadRowsAtIndexPaths:withRowAnimation:
Thanks anyway !

deselectRowAtIndexPath has no effect on a grouped UITableView

Grouped UITableViews don't appear to automatically animate the deselection of a row in the same way that plain UITableViews do, for example when a UITableViewController appears again after a detail view controller is pushed and subsequently popped. The iPhone Settings app does appear to implement this behaviour however.
I have tried to implement the behaviour in the viewWillAppear method of my grouped UITableViewController class but it simply has no effect:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//If returning from an edit then animate the deselection of the previously selected row
if ([self currentIndexPath] != nil)
{
[[self tableView] deselectRowAtIndexPath:[self currentIndexPath] animated:YES];
[self setCurrentIndexPath:nil];
}
...
The row and section properties of [self currentIndexPath] are always correct and valid according to my UITableView but the row deselection still does not animate. I've also tried deselecting the row using the following, again without success:
[[self tableView] deselectRowAtIndexPath:[[self tableView] indexPathForSelectedRow] animated:YES];
Please could someone help to shed some light on how this behaviour is implemented?
Is your indexpath correct?
I've absolutely no problems with this. Did you connect your TableView with self.tableview (if using an outlet connection)?
Best,
Christian