reloadRowsAtIndexPaths don't work in another controller - ios

I have 2 viewControllers: in one controller i have tableView (that include 3 table view 2 popovers and one default on screen). i have 3 arrays to all tableview and in numberOfRowsInSection i return [array count];.
In second controller i have some tableview with another data. and if i select row i download some data and call method reloadRowsAtIndexPaths for tableView in first Controller.
If i was in first controller and then go to second it works. But if i at second Controller select row and it call reloadRowsAtIndexPaths i have an error:
Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2380.17/UITableView.m:862
-[ViewController updateCell:], attempt to delete row 0 from section 0 which only contains 0 rows before the update
And my tableView is empty in first controller. For first controller i have xib but all connected. I saw that numberOfRows return 0.
Any ideas??? What can i do?

I make a check
if([self.Model.arr count]==0)
{
return;
}
So now it's work fine. If array not empty it reload row at indexpath.Thanks Meera J Pai for help!

Related

Switch calls multiple cases one after another when checking table view tag

I have a collection view with three different cells. Each of the cells contains a table view. So, there are three table views. I've set tags for each of them (from 1 to 3).
Now, on my view controller (I set it as the table view's data source when I dequeue collection view's cells) I call table view's data source method for the number of rows. To distinguish table views I check each one's tag. Here is the code for that:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch tableView.tag {
case 1:
if unitItems1 != nil {
return unitItems1!.count
} else {
return 0
}
case 2:
if unitItems2 != nil {
return unitItems2!.count
} else {
return 4
}
case 3:
if unitItems3 != nil {
return unitItems3!.count
} else {
return 4
}
default:
return 0
}
}
The problem is, when the first cell of the collection view is shown (with the first table view) it works fine. But when I scroll to the second cell, BOTH case 2 and case 3 get executed. After that, the second table view shows data as expected, but when I scroll to the third one, the method doesn't get called.
I can't figure out why two case statements get called one after another, while everything works fine for the first cell. If you have any ideas why this happens (or maybe, you could suggested a better way of checking table view's), I would appreciate your help.
Actually, the solution is quite simple. The reason of the problem was that collectionView's data source method was dequeueing all the cells one after another, even when they weren't on the screen. Consequently, tableView's inside of each cell were getting set, too. So, their data source method was getting called, hence the problem.
UICollectionView has a property called isPrefetchingEnabled. According to the documentation it denotes whether cells and data prefetching is enabled.
The documentation says:
When true, the collection view requests cells in advance of when they will be displayed, spreading the rendering over multiple layout passes. When false, the cells are requested as they are needed for display, often with multiple cells being requested in the same render loop. Setting this property to false also disables data prefetching. The default value of this property is true.
So, to solve the problem, described in the question, I set it to false as soon as my collectionView gets set.

UITableView reloads data only on second attempt

I have two UITableView controllers, A and B. If the user clicks on cell one of table A, the user is redirected to table B with 10 cells. If the user clicks on cell two of table A, the user is redirected to table B with 1 cell.
Theory
Click 1: Table A, Row One ---> Table B with 10 cells (layout with associated URLs)
Click 2: Table A, Row Two ---> Table B with 1 cell (layout with associated URL)
The bug I am observing is this:
When first clicking on the first row of Table A, and clicking on the second row of Table A thereafter, table B is displayed with 10 cells. 9 of those cells are not clickable, and the first cell is identical with the only cell that should be displayed (but with the layout of the other 9 not clickable cells). Only when clicking the back button and clicking onto the second row of table A again the 1 cell is displayed properly in table B.
Practice
Click 1: Table A, Row One ---> Table B with 0 cells
Click 2: Table A, Row One ---> Table B with 10 cells (layout with
associated URLs)
Click 3: Table A, Row Two ---> Table B with 10 cells
(layout only; 1st cell with associated URL)
Click 4: Table A, Row Two ---> Table B with 1 cell (layout with associated URL)
I believe someone else experienced the same bug (UITableView only sending data to Detail View Controller on Second Try). However, the feedback is for Objective C so I don't understand what to do.
The code for my segue is:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "viewOverviewArticle" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let recentObject = self.fetchedResultsController.objectAtIndexPath(indexPath)
let controller = segue.destinationViewController as! ArticleAnalysis
controller.analysisItem = recentObject
}
}
}
Assuming that I indeed experience the same problem as UITableView only sending data to Detail View Controller on Second Try, my question boils down to this:
How can I make sure the segue that is triggered when clicking onto a row in my table has up-to-date data?
Moved the command for deleting the old saved data from viewWillAppear to viewWillDisappear - that fixed the bug.

NSInternalInconsistencyException when removing rows from a UITableView

I'm receiving an error indicating that I need to update the number of rows in my UITableView after I have deleted a row. I realise that It's because I've not updated the amount of rows in the UITableView, I'm just not sure how to make this change in the code I have below.
Any assistance is really appreciated.
!-- code
NSIndexPath[] rowsToReload = new NSIndexPath[] {
NSIndexPath.FromRowSection(1, 1)
};
dv.TableView.BeginUpdates ();
dv.TableView.DeleteRows(rowsToReload,UITableViewRowAnimation.Automatic);
dv.TableView.EndUpdates ();
!-- error
Name: NSInternalInconsistencyException Reason: Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3)
Your code above is OK. However, you need to call it after you have removed the corresponding items from your data source.
For example, if you are filling your table view from a List<string> (myList) and you wanted to remove the first row:
myList.RemoveAt(0); // remove the item from the list first
NSIndexPath[] rowsToDelete = new NSIndexPath[] {
NSIndexPath.FromRowSection(0, 0)
};
dv.TableView.DeleteRows(rowsToDelete, UITableViewRowAnimation.Automatic);
No need to wrap the DeleteRows call in a Begin/EndUpdates, as you only have one delete action to perform. That is used when you have multiple different actions (eg. DeleteRows + InsertRows) so that the animations are performed smoothly.
#Dimitris thanks for answering my question. I ended up solving the problem by:
calling the reload method on my UITableView
NSIndexPath[] rowsToReload = new NSIndexPath[] {
NSIndexPath.FromRowSection(1, 1)
};
dv.TableView.ReloadRows (rowsToReload,UITableViewRowAnimation.None);
in my UITableViewCell GetCell method
I removed the label, field and button that were included on the first load of the table. Since this screen in my app will be seen only once, when the user loads it for the first time.

MonoTouch, UITableViewController, How to insert a row in a section?

I designed a UITableViewController with static cells in XCode.
After click on a button I want to add a row in one of the sections with a result.
My code:
InvokeOnMainThread (() => {
List<NSIndexPath> indexPaths = new List<NSIndexPath>();
indexPaths.Add(NSIndexPath.FromRowSection(0, 2));
TableView.InsertRows(indexPaths.ToArray(), UITableViewRowAnimation.Fade);
});
didn't work :-)
I get this error message: * Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2380.17/UITableView.m:1070
Do you add data to your data source (IE a new row or section) after you insert the rows. You need to because inserting automatically does a myTable.reloadData, resulting in all the datasource methods being called again. If you explicitly told it to add a row at a specific index and it goes to reload and finds that index doesn't exists you get errors like this. Check cellForRow and numCellInSection

Showing/Hiding Rows in Sections of UITableView

I am trying to create a UITableView that is set up so that when I click on a section, it hides the rows from the previous section and shows the rows of the newly selected section. The tableView is set up with data from an array of arrays called menuItems. menuItems contains several other arrays including contactInfoArray, clientInfoArray, jacketArray, and shirtArray. In each of these arrays, the objectAtIndex:0 is the Section Title and effectively acts as the header.
So, for example when the app loads, it should first show all rows of the contactInfoArray, but then show the ObjectAtIndex:0 (the title) for each of the other arrays. When I then tap one of those section titles, for example: "Jacket", I need the table to hide the contactInfoArray objectsAtIndexes:1+, but not object 0, while at the same time (or with an acceptable delay) showing jacketArray objectsAtIndexes:1+.
I have achieved the desired result by calling reload data, but I want animation of the change and reloadData does not allow that. I can't find any tutorials or sample code that does this.
Can anybody help me?
Thanks to my good friend Darren for helping me solve this issue!
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section{
return (indexPath.section == currentSection) ? [[menuItems objectAtIndex: indexPath.section ] count] : 1;
}
All that I needed to do was set an immediate variable (in my case "currentSection" which is an int) and set its value in the didSelectRowAtIndexPath: method. Then I set up my table so that row 0 of the section acted as the section title.
Doing this made it so that when I clicked on the section header it would "collapse" the open section and "expand" the newly selected section.

Resources