Table View: setEditing programmatically - objective-c

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.

Related

UITableView reloadData when editing and keep animations

I'm reloading a UITableView like this by overriding -setEditing:animated in my UITableViewController subclass when the user puts the table view into edit mode.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView reloadData];
}
This works but is there a way to keep the animations? Normally the red delete button and move button indicators slide into view.
I'm hiding section titles for empty sections but I want to show them when editing so the user can move a table view cell into an empty section which is why I'm doing a table reload when editing.
Try -reloadSections:withRowAnimation: instead.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
// specify appropriate sections you have.
[self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 1)] withRowAnimation:UITableViewRowAnimationAutomatic];
}

ios - reloadData TableView & Core Data

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];

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.

Trigger setEditing: animated: without using an edit button

I have a UITableView with some custom cells in it. In these custom cells I defined a UILongPressGestureRecognizer that triggers the edit mode of this table. So when someone presses and holds a cell for like 1.5 sec, the table goes into edit mode.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(startEditMode:)];
Which triggers:
- (void)startEditMode:(UISwipeGestureRecognizer *)recognizer {
if (self.allowEdit) {
UITableView *table = (UITableView *)self.superview;
[table setEditing:YES animated:YES];
}
}
But what I want to do is detect when the table goes into edit mode because I need to show/hide some additional buttons in this case. But for some reason in my viewcontroller this is never executed:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
NSLog(#"SET EDITING");
[super setEditing:editing animated:animated];
}
Any suggestion why? Is this just being called when using a proper Edit Button as provided by default in the UINavigationController?
Or how can I detect when my UITableView goes into Edit Mode?
You're sending the message (setEditing) to the table view, you should be sending it to the view controller (presumably a UITableViewController subclass?). It will then take care of the table view for you.
Ok so in case someone else walks into this thread with the same problem, I will show you how I solved this.
In my custom UITableViewCell I have this method now:
- (void)startEditMode:(UISwipeGestureRecognizer *)recognizer {
if (self.allowEdit) {
UITableView *table = (UITableView *)self.superview;
UITableViewController *control = (UITableViewController *)table.dataSource;
[control setEditing:YES animated:YES];
}
}

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