very strange behavior with UITableView - ios

I have a simple tableView where the value in numberOfRowsInSection depends on the type of data I am displaying, ie, names or details, etc..
The table is first loaded with certain details where the row count is 6. I added an NSLog statement and indeed I am returning 6 rows.
I also have to set the row height and again, my log statements says it is being called 6 times. great. My problem is cellForRowAtIndexPath is only called 5 times. it's missing the last call.
Note: I have a toolBar that reloads the table with different options. When I select a new option then go back, the table populates properly. It has 6 rows as it should have.
Everything is connected properly: delegate, datasource and outlet as proven by the fact that the table is being partially loaded. Does anyone have any idea why this is happening or how to fix it?

If your last cell is not visible on the screen the method cellForRowAtIndexPath won't be called if you don't scroll and make the cell visible.

Related

For UITableView in UITableCellView method cellForRowAtIndexPath not called, but numberOfRowsInSection called

I am working on a existing project.
The project has one screen where details of an orders are displayed.
Every order has order items. So, naturally a table view is used to display order items. This works fine.
Now, the system has been extended in that way that every order item can have 0 or more toppings. If there are toppings for order item, they also need to shown in a list.
So, the approach I took is to try and implement a table view which will be responsible for showing order item toppings inside order item cell.
I've read about this approach and people say that it is possible.
The problem I have now is that for toppings table view in order item table view cell, the numberOfRowsInSection method is called, however the cellForRowAtIndexPath is not called at all.
I have read about this issue and the people say that is has to do with table view frame not being set correctly.
I've setup the order item with toppings cell in Interface Builder with AutoLayout.
I (think) all the constraints are in place in order for cell to render it's content and height correctly.
However, from the screenshots it can be seen that the toppings tableview is not rendered at all.
Anybody has an idea of what might cause the table with not to render?
Any help, thoughts, comments are appreciated. Thank you.
The problem seems to with your UITableViewDelegate and the way you want to achieve automatic height for your cells.
In heightForRowAtIndexPath you return UITableViewAutomaticDimension, which actually is equal to -1.0. If you look at that function's description in documentation you will see
Return Value
A nonnegative floating-point value that specifies the height (in points) that row should be.
Now, if each of your rows have negative height, then the table view has nothing to display - hence cellForRowAtIndexPath is never called.
TL,DR
You were almost there - UITableViewAutomaticDimension should be set to UITableView.rowHeight, not returned in heightForRowAtIndexPath
toppingsTableView.rowHeight = UITableViewAutomaticDimension
Also, remove the functions heightForRowAtIndexPath and estimatedHeightForRowAtIndexPath

App crash while remove object from TableView

I have multiple data in my UITableView and when I delete one record.
Don't use didEndDisplayingCell to manipulate the cell or the data source array by the passed index path.
It's just a notification that the specified cell was removed from the table
The documentation also states:
Use this method to detect when a cell is removed from a table view, as opposed to monitoring the view itself to see when it appears or disappears.
The solution is to move the entire code in this method to the location where the cell / data source item is removed and use it before removing anything
The app is crashing because even though you have deleted the object( so now array will have one less element) but you have not told the table view to reset itself according to new datasource. Even cellforRowAt will crash if you delete the last element. One solution is to reload the tableview by calling:
<tableViewName>.reloadData()
but it will produce unnecessary flicker if tableViews are quite large and complex. And the Second thing, You should'nt be using didEndDisplayingCell

Remove blank space under UITableView

I have regular UITableView with UISearchDisplayController in Navigation Controller. SizeToFit works on viewDidLoad normally, without any problems. But when i enter search a write some letters, it returns me items, that OK but size of tableview fails.
It is scrolling well, from the bottom to the top but when i reach last item, it stops in middle (it looks like 1 or 2 cells are missing but they are not) & HorizontalScrollIndicator also reach just the middle of tableview.
Any advice ?
It's possible that after you've provided some search parameters and manipulated your data source, you are missing a call for
[self.tableView reloadData];
Hard to tell without the code, but the tableView may be attempting to display rows that should not exist anymore - causing an error in cellForRowAtIndexPath

numberOfSectionsInTableView is requested in/after viewDidLoad ONLY if tableview is empty

A simple tableviewController, empty. A modal that can be launched from a button. No data in the data source for the tableview, and no rows displayed.
I open the modal, use it to add an item, and return to the tableview controller. The tableview updates itself automatically, and the new row is displayed.
I add a second item. The table view does NOT update automatically.
I can tell by logging inside numberOfSectionsInTableView that even if I go to add the first item and cancel, the tableview refreshes - it asks for the number of sections, rows, and the cell to display (if there is one). But not if there is one pre-existing row in the table.
I've scoured my code but can't find anything that would cause the tableview to know when the first item is added, but none afterwards.
Any ideas?
EDIT - I have further narrowed my issue so will close this shortly and have posted a more specific question at Why does an empty tableView check the number of sections but a non-empty one does not?
from Apple's documentation:
UITableView overrides the layoutSubviews method of UIView so that it
calls reloadData only when you create a new instance of UITableView or
when you assign a new data source.
maybe you are setting data source of table view after showing that modal? So at the second time data source does not changes and tableView does not update.
another key (I'm not sure about that) may be the showing of the modal first time. The method -addSubview for modal is causing -layoutSubviews.

UITableView initial row selection

Maybe I'm missing something obvious, but I'm have a hard time programmatically setting the row selection in a tableView. The goal is to simply have a tableView open with a row already selected. The problem appears to be that I have to wait until the tableView is fully loaded before I can modify the selection.
I've read various strategies such as calling reloadData for the tableView in the viewController's viewWillAppear method, then immediately calling selectRowAtIndexPath for the target row. But when I do that, I get a range exception because the tableView has zero rows at that point. The UITableViewDelegate methods (numberOfRowsInSection, etc.) don't appear to be called immediately in response to reloadData (which makes sense if the table rows are drawn "lazily").
The only way I've been able to get this to work is to call selectRowAtIndexPath after a short delay, but then you can see the tableView scroll the selected row into view.
Surely, there's a better way of doing this?
Well, you can use another strategy. You can create a hidden table view, configure how you want and than show to user. Use the tableview.hidden = YES.

Resources