When does heightForHeaderInSection gets called - swift

I am calling the following function to update the tableView. However, I am finding that heightForHeaderInSection gets called twice for each section there are in the table. So if I have 5 sections, the function gets called 10 times. Is that normal?
tableView.beginUpdates()
let sections = NSIndexSet(index:posts.count - 1)
tableView.insertSections(sections, withRowAnimation: .None)
tableView.endUpdates()

To answer youre question lets look at UITableViewDelegate. From Apple documentation :
The delegate of a UITableView object must adopt the
UITableViewDelegate protocol. Optional methods of the protocol allow
the delegate to manage selections, configure section headings and
footers, help to delete and reorder cells, and perform other actions.
So when UITableViewDelegate is get called in your'e case? Delegate is get called when you update tableView with insertSections. So heightForHeaderInSection is called after you insert new sections to tableView.
Amount of times that heightForHeaderInSection is get called depends on how you update tableView.
Also it is possible to highlight that Apple do not gives clear explanation how often UIKit would call you're delegate methods.

Related

Differentiate between tapping UITableView and selecting programmatically?

I'm looking to call different methods based on whether the user taps a UITableView cell or it's selected programmatically. I can't seem to separate them, however; the programmatic one runs everything in the didSelectRowAt indexPath. Is there a way to use these more independently?
Here's my programmatic code:
func selectTableViewRowProgrammatically() {
let indexPath = IndexPath(row: someVar, section: 0);
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableView.ScrollPosition.none)
self.tableView(self.tableView, didSelectRowAt: indexPath)
}
Thanks!
What do you want the app to do when you select the table cell manually vs. when you programmatically call it?
Currently your programmatically way calls the same method that is being called when you tap the cell, i.e. tableView(_:didSelectRowAt:).
So if you want to do any additional computations, just add it to your selectTableViewRowProgrammatically method before or after you call self.tableView(self.tableView, didSelectRowAt: indexPath).
To highlight a cell programmatically you can call selectRow(at:animated:scrollPosition:).
Note the Discussion part in the documentation:
Calling this method does not cause the delegate to receive a
tableView(:willSelectRowAt:) or tableView(:didSelectRowAt:) message,
nor does it send selectionDidChangeNotification notifications to
observers.

UITableViewController and prefetching

In my older Swift 3 app I have been using a UITableView and I implemented the function
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath])
Now I redesign the app and would like to use a UITableViewController instead and cant find a similar function to prefetch. Is there a similar function for the TableViewController?
I am using the table to show async downloaded images and pdf:s.
Simply have your controller adopt the UITableViewDataSourcePrefetching protocol. The function will then be available (and required).
As you point out in your comment, you also have to set the prefetchDataSource of the table view.

Which protocol method call after created UITableView

Sorry for asking this type of simple question here.
But I am new at iOS development :( also i am trying on google for find my answer but i don't get it.
My Question is that which protocol method of UITableView is call after created whole TableView ?
i mean when create UITableView then call UITableViewDataSource method such like ,
Configuring a Table View
– tableView:cellForRowAtIndexPath: required method
– numberOfSectionsInTableView:
– tableView:numberOfRowsInSection: required method
– sectionIndexTitlesForTableView:
– tableView:sectionForSectionIndexTitle:atIndex:
– tableView:titleForHeaderInSection:
– tableView:titleForFooterInSection:
etc...
But i want to know which method of UITableView call after creating whole TableView (OR call above methods) without any UITableView interaction ?
so, please help me
Since the order is not specified in Apple's documentation, you cannot safely assume that they will always be called in the same order and it is generally not a good idea to make such assumptions in your implementation.
For example, cellForRowAtIndexPath is not called for all rows. It is only called for visible rows and then called for additional rows as the user scrolls to them. Old rows are also destroyed as they go off the screen and it will request the cells again if the user scrolls back up.
But in general we can assume some Order of call:
– numberOfSectionsInTableView: (...Optional method...)
– sectionIndexTitlesForTableView: (...Optional method...)
– tableView:titleForHeaderInSection: (...Optional method...)
– tableView:titleForFooterInSection: (...Optional method...)
– tableView:numberOfRowsInSection: (...Compulsory method...)
– tableView:cellForRowAtIndexPath: (...Compulsory method...)
For creation of UITable all required method has to called. i.e.
– tableView:cellForRowAtIndexPath:
– tableView:numberOfRowsInSection:
Off course these are datasource method . But after creation of the table none of this method called until you reload the table.
If you want method that called after creation of the tableview you have to look for delegate methods like:
– tableView:willSelectRowAtIndexPath:
– tableView:didSelectRowAtIndexPath:
– tableView:willDeselectRowAtIndexPath:
– tableView:didDeselectRowAtIndexPath:

CellForRowAtIndexPath method not being called in storyboards

I am using storyboards for my app.In that I have a UITableViewController class.I am loading the UITableView from the data coming from the webservice. The issue is that the data is coming but is not geting populated in UITableView. On Decoding I found out that the cellForRowAtIndexPath method is not getting called.
Do we need to connect the datasource and delegate in storyboard as it was done in separate xibs before storyboard. And if so, where to connect the datasource and delegate methods as there is NO Filesowner in storyboard.
I am stuck up with this issue and any help would be appreciated.
Thanks
If you put a table view controller into a storyboard, it usually has the table view's dataSource and delegate already set up correctly. If yours turn out to be connected OK, the other possibility is that tableView:numberOfRowsInSection: is returning zero.
If you are using the UITableViewController, then you need to make the numberOfSections:tableView: data source method returns 1 instead of the default return of 0.
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1 // Default is 0, should be greater than 0
}

How to stop UITableView from loading until data has been fetched?

I understand that UITableView will call -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method to get each of the cells for the table view. Say I have my data source is fetched over the internet and I have to account for latency. What will be the best way of "stopping" this method from being called? Should it block on a boolean flag in the application? Should I just call cellForRowAtIndexPath again from within my application?
I am uncertain as to when the function gets called, ie, how often the UITableView "refreshes" itself. Any explanations will be helpful! Thanks!
If you don't have data, or you don't have the data for additional cells, then cellForRowAtIndex: will not be called as long as you don't tell the UTableView that you have rowCounts or new rowCounts. That value is being set in numberOfRowsInSection:.
In other words, don't report any new cells in numberOfRowsInSection:, until you actually have that data in hand, and then cellForRowAtIndexPath: won't be called prematurely.
When you do get the additional row data, then call reloadData to get the UITableView to ask for the number of rows and then call cellForRowAtIndex:.
If you've set UITableView datasource and delegate from IB then it will at least go for numberOfRowsInSection method when you push to the view, however if you're showing data from an NSArray, it'll return count ZERO if array is still empty, so table won't go for other methods to call.
In practice, I'm pulling data from web service to feed the table, so I am not setting up the datasource and delegate from IB instead once I get the data and status OK response I'd set the tableview.datasource = self and tableview.delegate = self and then call reloadData method to update table. This ensures that it won't go for numberOfRowsInSection method as you don't need to call it up without having the data.
What you should do is call reloadData on your table view when your data is done being fetched. That will force the table view to call it's delegate methods again for display. Those methods are called whenever the table view needs to re-display, so either when it comes into view, scrolling occurs, or you manually call reloadData.
When you invoke [tableView reloadData], the framework automatically invokes all the data source methods again for the table view cells that are visible currently (not for all the cells of the tableview). So the best approach would be to invoke reloadData every time you get data from the internet.