Inserting a new section to uitable view - iphone

I have table with multiple sections and at particular section I have a button in footer of that section. In that action it should write the code to add the new section below to it . but its not adding any new section below to it.
[self.tableView beginUpdates];
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];

On the click of that button, you will have to realod your table and then in the method numberOfSectionsInTableView: you will have to return the numberOfExistingSections + 1
Let me explain in detail.
First you store your initial number of sections in a variable in your class like:
numberOfExistingSections = 5;
Then when you click on a button, the method will look like this:
- (void) buttonClick {
// your code
numberOfExistingSections += 1;
[yourTable reloadData];
}
And your numberOfSectionsInTableView: will look like this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return numberOfExistingSections;
}
According to the number of sections and rows you are adding, also dont forget to add modify data inside the arrays or dictionaries you are using to fill data in your UITableView.

Kanan Vora is incorrect. Your problem is that you need to update your model to add the new section before you update the table view.
[self.tableView beginUpdates];
<- insert new section at index 'n' ->
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:n]
withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];

Related

Insert Dynamic Section Headers in UITableView

I have a UITableView in which i want to add the section headers dynamically as the user clicks add button. The user should also be able to delete the headers if they dont need it. Under each header the user should be able to add relevant list of items. And apart from that the user should be able to insert rows dynamically under selected section only. Please suggest some ideas to achieve this functionality. Thanks in advance.
You can achieve this by removing and then adding that section again, this will cause a call to tableView:titleForHeaderInSection:
Assume your section index is 0:
BOOL shouldShowHeader;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
shouldShowHeader ? #"Your Header" : nil;
}
- (IBAction)buttonAction:(id)sender
{
shouldShowHeader = !shouldShowHeader;
NSIndexSet *set = [NSIndexSet indexSetWithIndex:0];
[self.tableView beginUpdates];
[self.tableView deleteSections:set withRowAnimation:UITableViewRowAnimationNone];
[self.tableView insertSections:set withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
Footer works the same way.
I will tell for dynamic section header. Keep a flag and set to 0 initially. When User clickes on button in that buttonClick method set flag to 1 and reload tableView.
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if(flag)
return aView;//alloc init aView and return.
else
return nil.
}
Similarly for dynamic rows have a array and numberOfRows be array.count.
On click of button insert one more item in array and reload Table.
I hope this help.
When user clicks on button in this method set a flag and reload your tableview and then do it..
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if(flag)
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0,320, 30)];
return headerView;
}
else
return nil;
}
and you can delete header in table view like this......
If you want to remove the table's header view, just set the myTable.tableHeaderView property to nil. If what you have is actually a section header, then you need to return nil from the viewForHeaderInSection method and call [myTableView reloadData]
and i hope this will work fine.

Change an image in a UITableViewCell without reloading cell

I'm writing an iPhone app with a UITableView as the primary user interface. Each section consists of two rows, a header and the body. When the user clicks on the header, I remove the second row by changing the numberOfRowsInSection value:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
cbwComponent *comp = [_componentController objectInListAtIndex:section];
if([comp hasContentsView] && !comp.contentsHidden){
return 2;
}else
return 1;
}
When the user selects the header, I'm using the following code:
comp.contentsHidden = YES;
[self.tableView beginUpdates];
NSArray *deleteIndexPaths = [[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:1 inSection:indexPath.section], nil];
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
It's working great, with a nice smooth fade effect. The problem is, I'm trying to add an indicator in the header cell (row 0) that changes when it's clicked on. To change that image I have to refresh the top row as well as the second row, which makes the transition look bad (well, not nearly as smooth). Is there a way to change the image in a UITableViewCell without refreshing the cell?
Thanks
EDIT: I figured it out! You can maintain the smooth transition as long as you reload that first row before you make the change to the second row. It has to be called inside of [tableView beginUpdates];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[[NSArray alloc] initWithObjects:[NSIndexPath indexPathForRow:0 inSection:indexPath.section], nil] withRowAnimation:UITableViewRowAnimationNone];
...
[self.tableView endUpdates];
Did the trick.
You could also subclass a tableview cell and implement a view transition in it that can be called from your view controller. You could then call that without having to reload the cell.
[(YourCustomCell*)[tableView cellForRowAtIndexPath:indexPathOfYourCell] fadeInIndicator];

UITableView reload section

I want to reload only one section not the full table. Is there any method in UITableView.
[tableView reloadData] is used to load full table.
I want to know how to load only one section, as I have large number of rows in the table.
The reloadSections method bugs me -- as I have to construct a few objects. This is great if you need the flexibility, but sometimes I also just want the simplicity too. It goes like this:
NSRange range = NSMakeRange(0, 1);
NSIndexSet *section = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:section withRowAnimation:UITableViewRowAnimationNone];
This will reload the first section. I prefer to have a category on UITableView and just call this method:
[self.tableView reloadSectionDU:0 withRowAnimation:UITableViewRowAnimationNone];
My category method looks like this:
#implementation UITableView (DUExtensions)
- (void) reloadSectionDU:(NSInteger)section withRowAnimation:(UITableViewRowAnimation)rowAnimation {
NSRange range = NSMakeRange(section, 1);
NSIndexSet *sectionToReload = [NSIndexSet indexSetWithIndexesInRange:range];
[self reloadSections:sectionToReload withRowAnimation:rowAnimation];
}
Yes, there is:
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
But you can reload only sections which contain same number of rows (or you have to manually add or remove them). Otherwise you will get:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 2. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Which is not required when you use [tableView reloadData].
When you need to reload a section and you have changed number of rows inside it, you could use something like this:
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
[self beginUpdates];
[self deleteSections:indexSet withRowAnimation:rowAnimation];
[self insertSections:indexSet withRowAnimation:rowAnimation];
[self endUpdates];
If you put it in a category (like bandejapaisa shows) it could look like this:
- (void)reloadSection:(NSInteger)section withRowAnimation:(UITableViewRowAnimation)rowAnimation {
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];
[self beginUpdates];
[self deleteSections:indexSet withRowAnimation:rowAnimation];
[self insertSections:indexSet withRowAnimation:rowAnimation];
[self endUpdates];
}
For Swift 3, 4 and 5
let sectionToReload = 1
let indexSet: IndexSet = [sectionToReload]
self.tableView.reloadSections(indexSet, with: .automatic)
that the correct way:
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
Based on the accepted answer here, I made a function that will reload all sections in the table using an animation. This could probably be optimized by reloading only visible sections.
[self.tableView reloadData];
NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]);
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];
In my case, I had to force a reloadData before the section animation, because the underlying data for the table had changed. It animates properly however.
You need this... For Reload Row
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
or For Reload section
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
Here is the method, you can pass section details in different ways
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:1] withRowAnimation:NO];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];
Reloading particular sections improves performance for the table view as well some time it also avoid some issues like floating/moving custom headers-footers in your view. SO try to use reloadSection than relaodData whenever possible
Try to use
[self.tableView beginUpdates];
[self.tableView endUpdates];
Hope this will solve your issue.
But you can reload only sections which contain same number of rows (or you have to manually add or remove them). Otherwise you will get an NSInternalInconsistencyException.
Steps:
calculate which rows to remove and/or insert
generate an IndexPath array from these
call related tableView methods
now you can safely call reloadSections :) Reload section will call update for the rest of the indexes.
Or you can use a library like : https://github.com/onmyway133/DeepDiff
Swift pseodo code:
tableView.deleteRows(at: valueIndexesToRemove, with: .automatic)
tableView.insertRows(at: valueIndexesToInsert, with: .automatic)
tableView.reloadSections(IndexSet([section]), with: .automatic)
If you have custom section view you can add a weak reference to it in your view controller and update it whenever you want. Here is my code for reference:
#property (weak, nonatomic) UILabel *tableHeaderLabel;
....
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UITableViewHeaderFooterView *myHeader = [[UITableViewHeaderFooterView alloc] init];
UILabel *titleLabel = [[UILabel alloc] init];
[titleLabel setFrame:CGRectMake(20, 0, 280, 20)];
[titleLabel setTextAlignment:NSTextAlignmentRight];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setFont:[UIFont systemFontOfSize:12]];
[myHeader addSubview:titleLabel];
self.tableHeaderLabel = titleLabel; //save reference so we can update the header later
return myHeader;
}
Then later on you can update your section like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
self.tableHeaderLabel.text = [NSString stringWithFormat:#"Showing row: %ld", indexPath.row];
}

How to create a toolbar between UITableView rows

I am interested on how tweetbot does the following:
I would like to create the same thing with my app, where if you click on a row, it pops
an additional UIToolBar and pressing on any other row will dismiss this view with animations.
The logic I think is simple, you just need to add a subView to the UITableViewCell when pressed and shift the rest of the content up, but how do you actually dismiss it when I press the other row?
The best way to do this is to add a dummy cell below the cell that was tapped.
First you need to keep track of what cell is been tapped and act accordingly.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//if user tapped the same row twice let's start getting rid of the control cell
if([indexPath isEqual:self.tappedIndexPath]){
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
//update the indexpath if needed... I explain this below
indexPath = [self modelIndexPathforIndexPath:indexPath];
//pointer to delete the control cell
NSIndexPath *indexPathToDelete = self.controlRowIndexPath;
//if in fact I tapped the same row twice lets clear our tapping trackers
if([indexPath isEqual:self.tappedIndexPath]){
self.tappedIndexPath = nil;
self.controlRowIndexPath = nil;
}
//otherwise let's update them appropriately
else{
self.tappedIndexPath = indexPath; //the row the user just tapped.
//Now I set the location of where I need to add the dummy cell
self.controlRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
}
//all logic is done, lets start updating the table
[tableView beginUpdates];
//lets delete the control cell, either the user tapped the same row twice or tapped another row
if(indexPathToDelete){
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPathToDelete]
withRowAnimation:UITableViewRowAnimationNone];
}
//lets add the new control cell in the right place
if(self.controlRowIndexPath){
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:self.controlRowIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
//and we are done...
[tableView endUpdates];
}
Whenever you have that dummy cell present you have to make sure to send the correct count.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(self.controlRowIndexPath){
return modelArray.count + 1;
}
return self.modelArray.count;
}
Also, return the appropriate height for your ControlCell.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if([indexPath isEqual:self.controlRowIndexPath]){
return 45; //height for control cell
}
return 70; //height for every other cell
}
Lastly, remember the control cell is a dummy. Is not part of the model, thus you have to account for that. If the user taps a row that is above the last tapped row is ok but when the new tapped row is below that control cell you have to make sure you access the right row in your model. In other words, account for that fake cell in the middle of your view.
- (NSIndexPath *)modelIndexPathforIndexPath:(NSIndexPath *)indexPath
{
int whereIsTheControlRow = self.controlRowIndexPath.row;
if(self.controlRowIndexPath != nil && indexPath.row > whereIsTheControlRow)
return [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:0];
return indexPath;
}
I hope this helps.
In tableView:didSelectRowAtIndexPath:, you remove the tool view from the last selected cell. If there is no such view, you create a new one. Then you add this view to the newly selected cell. Save the indexPath of the selected row.
In tableView:heightForRowAtIndexPath:, you check if the indexPath is the same as the saved indexPath. If they are equal, you return a height that is the height of both views. If it is not equal, just return the height of the "real cell".
Put all your calls in didSelectRowAtIndexPath between [tableView beginUpdates] and [tableView endUpdates] to get animation for the height change.
rjgonzo's code works fine except for the case where you only have 1 row in the tableview. When there's only 1 row (and 1 object in the tableview datamodel) you'll get an NSRange exception when you call insertRowsatIndexPath(s). To fix this I checked to see if the datamodel has only 1 object and if so then I add the row to the current indexpath (instead of the controlindexpath) which results in the row logically being added above the first row and then I call moveRowAtIndexPath to interchange the rows after calling [self.tableView endUpdates]. The animation shows as expected with the control row appearing to slide down from the 1st row.
if(self.controlRowIndexPath){
//Check to see if the datamodel only has 1 object
if([self.objects count]==1){
//If so then insert the row above the row
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
else
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:self.controlRowIndexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView endUpdates];
//if the row was inserted above the 1st row then switch the rows
if([self.objects count]==1)
[self.tableView moveRowAtIndexPath:self.controlRowIndexPath toIndexPath:indexPath];
I would not add a subview to a UITableViewCell, I would add another row to the UITableView. That way, the UITableView will take care of the animation. (And I don't think that's possible to animated UITableViewCell height changes...)
Use simply
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
do add a row. And
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
to remove it.
#rjgonzo this works great but there is a minor issue on how you keep the indexPathToDelete. Since it's just another pointer to self.controlRowIndexPath, once you clear or reassign the self.controlRowIndexPath, indexPathToDelete will not be what you wanted, and tableView deleteRowsAtIndexPaths:withRowAnimation: call, you will get an SIGBART crash.
so, instead of
//pointer to delete the control cell
NSIndexPath *indexPathToDelete = self.controlRowIndexPath;
and
//lets delete the control cell, either the user tapped the same row twice or tapped another row
if(indexPathToDelete){
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPathToDelete]
withRowAnimation:UITableViewRowAnimationNone];
}
the following code should work fine:
//pointer to delete the control cell
NSIndexPath *indexPathToDelete = [NSIndexPath indexPathForRow:self.control_row_index_path.row inSection:self.control_row_index_path.section];
...
...
//lets delete the control cell, either the user tapped the same row twice or tapped another row
if(indexPathToDelete.row != 0){
NSLog(#"row to delete %d", indexPathToDelete.row);
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPathToDelete] withRowAnimation:UITableViewRowAnimationNone];
}
Here's what I'm doing to get the animation to be clean.
In addition to the strategy user fluchtpunkt suggests (that is, adding a subview to the cell, updating the cell height via heightForRowAtIndexPath, beginUpdates, and endUpdates), I'm finding the following measures to be helpful with the animation:
The tableviewcells have a background image. Otherwise, the added subview/toolbar is visible through the cell just before the tableview animates the height change.
The tableviewcell is 'behind' the view that is the cell below it, otherwise again the subview/toolbar will show too soon. I'm using [tableview sendSubviewToBack:cell]; and it's taking care of that.
This is clean for me, but not exactly like Tweetbot. Interestingly, Tweetbot's animation seems to pull the toolbar down as the bottom of the cell animates down. It seems like some additional animation must be taking place, or my conspiracy theory is that it is actually adding the subview to the top of the cell below the selected cell, and then performing the lengthening and animation on the cell below.

reloadRowsAtIndexPaths:withRowAnimation: crashes my app

I got a strange problem with my UITableView: I use reloadRowsAtIndexPaths:withRowAnimation: to reload some specific rows, but the app crashes with an seemingly unrelated exception: NSInternalInconsistencyException - Attempt to delete more rows than exist in section.
My code looks like follows:
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
When I replace that reloadRowsAtIndexPaths:withRowAnimation: message with a simple reloadData, it works perfectly.
Any ideas?
The problem is that you probably changed the number of items of your UITableView's data source. For example, you have added or removed some elements from/to the array or dictionary used in your implementation of the UITableViewDataSource protocol.
In that case, when you call reloadData, your UITableView is completely reloaded including the number of sections and the number of rows.
But when you call reloadRowsAtIndexPaths:withRowAnimation: these parameters are not reloaded. That causes the next problem: when you are trying to reload some cell, the UITableView checks the size of the datasource and sees that it has been changed. That results in a crash. This method can be used only when you want to reload the content view of the cell (for example, label has changed or you want to change its size).
Now if you want to remove/add cells from/to a UITableView you should use next approach:
Inform the UITableView that its size will be changed by calling method beginUpdates.
Inform about inserting new row(s) using method - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation.
Inform about removing row(s) using method - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation.
Inform the UITableView that its size has been changed by calling the method endUpdates.
I think the following code might work:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
I had this problem which was being caused by a block calling reloadRowsAtIndexPaths:withRowAnimation: and a parallel thread calling reloadData.
The crash was due to reloadRowsAtIndexPaths:withRowAnimation finding an empty table even though I'd sanity checked numberOfRowsInSection & numberOfSections.
I took the attitude that I don't really care if it causes an exception. A visual corruption I could live with as a user of the App than have the whole app crash out.
Here's my solution to this which I'm happy to share and would welcome constructive criticism. If there's a better solution I'm keen to hear it?
- (void) safeCellUpdate: (NSUInteger) section withRow : (NSUInteger) row {
// It's important to invoke reloadRowsAtIndexPaths implementation on main thread, as it wont work on non-UI thread
dispatch_async(dispatch_get_main_queue(), ^{
NSUInteger lastSection = [self.tableView numberOfSections];
if (lastSection == 0) {
return;
}
lastSection -= 1;
if (section > lastSection) {
return;
}
NSUInteger lastRowNumber = [self.tableView numberOfRowsInSection:section];
if (lastRowNumber == 0) {
return;
}
lastRowNumber -= 1;
if (row > lastRowNumber) {
return;
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
#try {
if ([[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] == NSNotFound) {
// Cells not visible can be ignored
return;
}
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
#catch ( NSException *e ) {
// Don't really care if it doesn't work.
// It's just to refresh the view and if an exception occurs it's most likely that that is what's happening in parallel.
// Nothing needs done
return;
}
});
}
After many try, I found "reloadRowsAtIndexPaths" can be only used in certain places if only change the cell content not insert or delete cells. Not any place can use it, even you wrap it in
[self beginUpdates];
//reloadRowsAtIndexPaths
[self endUpdates];
The places I found that can use it are:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (IBAction) unwindToMealList: (UIStoryboardSegue *) sender
Any try from other places like call it from "viewDidLoad" or "viewDidAppear", either will not take effect (For the cell already loaded I mean, reload will not take effect) or cause exception.
So try to use "reloadRowsAtIndexPaths" only in those places.
You should check cell visibility before reload. Here is Swift 3 code:
let indexPath = IndexPath(row: offset, section: 0)
let isVisible = tableView.indexPathsForVisibleRows?.contains{$0 == indexPath}
if let v = isVisible, v == true {
tableView.reloadRows(at: [indexPath], with: .automatic)
}
I had the same issue. In my case; it was happening only if another view controller pop/pushed over existing table view controller and then[self.tableView reloadRowsAtIndexPaths] function is called.
reloadRowsAtIndexPaths call was hiding/showing different rows in a table view which is having over 30, visually complex, rows. As i try to fix the issue i found that if i slightly scroll the table view app wasn't crashing. Also it wasn't crashing if i don't hide a cell (by returning 0 as height)
To resolve the issue, i simply changed the "(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath" function and returned at least 0.01 as row height.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
....
return rowModel.height + 0.01; // Add 0.01 to work around the crash issue.
}
it solved the issue for me.
THIS IS OLD. DO NOT USE.
I just bumped into this issue when I was calling reloadRowsAtIndexPaths... in order to change the cell to an editing cell containing a UITextField. The error told me I was deleting all of the rows in the table. To solve the problem, I removed:
[self.tableView beginUpdates];
NSArray *reloadIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]];
[self.tableView reloadRowsAtIndexPaths:reloadIndexPath withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
and replaced it with
[self.tableView reloadData];
The app crashes because you have made some changes to your tableView. Either you have added or deleted some rows to the tableView. Hence when the view controller asks your model controller class for data, there is a mismatch in the indexPaths. Since the indexPaths have changed after modification.
So either you simply remove the call
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
or replace it with
[self.tableView reloadData];
Calling reloadData checks your number of sections, number of rows in each section and then reloads the whole thing.
If data count changes completely, then use reloadData else, there is three functions to do it.
When data count changes we use insertRows / deleteRows and when data count still the same use reloadRows.
Important! don't forget call beginUpdates and endUpdates between insertRows/deleteRows/reloadRows calls.