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.
Related
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.
I'm moving and app I had on Parse to Firebase and I ran into an issue with a cell that needs to get resized.It contains a textview that recieves data, since the text varies in size, I am using this two methods:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
With Parse this worked perfectly because I would recieve the entire object that I had to pass to the DetailTableView in the MainTableView. With Firebase, I handle it differently, I retrieve what the MainTableView needs, then I just pass a reference to the DetailTableView and again retrieve whatever I need there. The problem seems to be that the size of the cell gets set before the async function can set the text. Any ideas on how to solve this?
Thanks in advance!
I think you can wrap the code setting the text on the cell with calls to tableView.beginUpdates()
tableView.endUpdates()
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
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!
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)