delay the loading of tableview - ios

Hi I am getting the information from the server in view did load. Since this is web service the data retrieval is in another thread making the main thread continue and call:
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
before the data is populated. Is there a way to make the main thread wait for the results or to load the table once the data is retrieved?
Thanks

Related

UITableViewDataSource Functions?

I'm a newbie in swift, I stumbuled upon these two functions that must be used when calling UiTableViewDataSource:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I can see what each function do, but I can't understand their structures. Like what about the parameter that each one takes? Why don't we give any values of these parameters? How does it determine that what indexpath really is?
UITableView is the one responsible for calling them and picking the right index path according to what the table view needs or is visible at that time on the screen. Your only responsibility on the first one is to return the amount of elements that are in a given section and for the second one to dequeue the right cell and configure it with the data that corresponds to the index path that was passed in.

Swift 3: Understand syntax change for UITableViewDataSource method

I have some questions with Swift 3 function calling. Below is an example.
Old Swift:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell
Swift 3:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
That's fine with the above syntax. But now Xcode shows me an error and asks me to do like below:
#objc(tableView:cellForRowAtIndexPath:) func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I do not understand why I have to declare #objc(tableView:cellForRowAtIndexPath:).
This is happening only when I am trying to implement table view datasource methods under an extension. Also this is not happening for numberOfRowsInSection or viewForHeaderInSection.
Can anyone help me to understand why this is happening?
While I am not sure what triggers the #objc, I can suggest the following approach:
Store the tableView variable somewhere in the viewDidLoad:
let tv = tableView!
Then hover over the tableView variable and press the command button in conjunction with a click.
This should take you to the interface of a UITableView.
Then, hover over either UITableViewDelegate or UITableViewDataSource and press the command button in conjunction with a click.
Now you can see the new signatures.
A lot has changed...Happy upgrade!
Swift compiler forced to write Objc(funcName) before function if you are using this function from Objective c. According to app doc
Use the #objc(name) attribute to provide Objective-C names for
properties and methods when necessary. For example, you can mark a
property called enabled to have a getter named isEnabled in
Objective-C like this:
var enabled: Bool {
#objc(isEnabled) get {
// ...
}
}
To void this, use extension to write TableView Datasource and delegate
extension YourViewControllerName:UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCell() as SplitAddContactCell
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80.0
}
}

Changing index of a cell

I'm starting to work with UITableViews and can't seem to find out how to change the position of a cell with code. Changing the position in the storyboard is straightforward enough but I need to be able to do it in swift.
TLDR;
Update your data. i.e. swap(&arr[2], &arr[3]).
Call the tableView's reloadData() method to reflect the changes to your data.
Long answer
An instance of UITableView works by checking its data source (UITableViewDataSource) for the information it needs. This includes the number of sections and rows, as well as the instance of UITableViewCell that the table view is to use. These are defined by the following UITableViewDataSource delegate methods:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int;
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int;
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell;
Usually, you would base the former two on some data you have, likely an Array or similar container. For example, if your tableView displayed data from an Array named fruitArray (which contained names of different fruit - a list of strings), then you might have something like the following:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Our array is one dimensional, so only need one section.
// If you have an array of arrays for example, you could set this using the number of elements of your child arrays
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Number of fruits in our array
return fruitArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("yourCellId") // Set this in Interface Builder
cell.textLabel?.text = fruitArray[indexPath.row]
return cell
}
Then, you can see that the answer to your question becomes simple! Since the contents of a given cell are based upon fruitArray, all you need to do is update your array. But how do you get the tableView to "recheck" its dataSource? Well, you use the reloadData method, like so:
swap(&fruitArray[2], &fruitArray[3])
tableView.reloadData()
This then triggers the tableView to "recheck" its dataSource, hence causing your data swap to appear on the screen!
If you'd like the user to be able to swap the positions of the cells, you can use the following UITableViewDelegate (not UITableViewDataSource) delegate method:
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool
Have a look at this article for more info. You can also view Apple's documentation on UITableView, UITableViewDataSource, and UITableViewDelegate for further detail.
Hope this helps!

ios, tableview cellForRowAtIndexPath not called

func tableView(tableView: UITableView, numberOfRowsInSection section: Int)
is getting called and returning non zero value.
but the following code isn't getting called.. why?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
tableView is initially 0 size, and supposed to grow dynamically, would it be the cause of this?
cellForRowAtIndexPath will not be called if tableView's size is zero!
And you must not keep any logical part in that method. You must use that method only for updating the ui, no more.

Swift UITableViewController didSelectRow first called when second cell selected [duplicate]

This question already has answers here:
UITableView didSelectRowAtIndexPath: not being called on first tap
(16 answers)
Closed 7 years ago.
So here's my strange problem.
I have a small app which uses storyboard.
I have 1 UITabBarController which has 2 tabs:
- 1 UITableViewController(subclassed)
- 1 UIViewController(just has a UILabel and does nothing till now)
The UITableViewController is subclassed and i provided:
- numberOfSectionsInTableView(tableView: UITableView) -> Int
- tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
- tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)
- tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
The tableview has 2 sections (7 and 1 row).
The rows in section 1 are custom cells and should do nothing when selected.
The row in section 2 is a standard UITableViewCell and should start a download.
But When i selecting any cell tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath)isn't even called, only after selecting another cell(not the same again), the didSelect will be called with the first cell i selected.
Another example; (x,x) is representing the selected indexPath
(1,0), does nothing -> (0,6), (1,0) is selected -> (0,2), (0,6) is selected -> (1,0), (0,2) is selected
Additions:
- The highlighting is working as it should. Just the call of tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) isn't.
- tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? is called appropriate.
Solution:
Was a little typo in the delegate method. I implemented didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath
You are calling didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath.
You should use this method :
tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
Please check your delegate method, it should be;
tableView(tableView: UITableView, selectRowAtIndexPath indexPath: NSIndexPath)

Resources