So I am just getting into the whole tableView thing but I came across a curious observations and have a question:
Why is it that overriding this function in my UITableViewController class
override func numberOfSections(in tableView: UITableView) -> Int
has a descriptive name but the number of rows in the section is determined this way
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
I find the former much more logical and wonder why it is not used consequently for other tableView parameters.
Why are different versions of the function tableView called for most tableView properties, instead of different functions with descriptive names?
I am sure there is a very good reason and would be thankful if someone wiser than me could shed some light on the issue.
So to put it frankly: Compatibility with Objective-C seems to be the reason for this inconsistency.
Related
I am using MultivaluedSection with an option .Reorder to reorder my cells, for which I need to know the exact order.
I tried with section.allRows, form.allRows, form.values() but seems like they all do not keep the information about order, even though they return an Array.
Note: I was trying to catch this data in overridden:
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
Actually I realized that after overriding that method I was "killing" that update, of course.
Still, I don't know how to "catch" when a change happens.
Using Swift 3, the UITableView's func tableView(_ tableView: UITableView, cellForRowAt indexPath: #autoclosure #escaping IndexPath) -> UITableViewCell is being called. I want to track who's calling this function. As far as I know, this will only be called if there's a need for a cell to display. However, in stacktrace override internal func tableView(_ tableView: UITableView, numberOfRowsInSection section: #autoclosure #escaping Int) -> Int is not called and there is no stacktrace. Could someone advice to where to start digging up? Thanks!
See attached screenshot
By default, you only see the stack trace that contains debug symbols. So you won't see many framework internals here.
To see everything, there is a small button at the bottom of the stack trace window, third position from the right, that will enable also methods without debug symbols:
(In fact, it depends on your Xcode version; in older versions there is some sort of slider which will display more or less details in the stack trace).
As #AndreasOetjen mentioned, this is a normal behavior because the method get's called from a UIKit Framework class. The call-stack in this Framework is hidden by default and can be opt-io by the mentioned buttons.
Something really weird is going on after our Swift 3 migration.
We have two view controllers, both of them implement UITableViewDelegate and both of them implement public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
However only in one of them the actual method is called.
If I change in the one that doesn't work public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) to public func tableView(_ tableView: UITableView, didSelectRowAtIndexPath: IndexPath) (notice the Swift 2.2 signature) then they both work.
Both view controllers are Swift classes, so I am not sure what the heck is going on.
I am pretty sure it might be a Objective-C vs Swift interoperability issue, but our whole project is written in Swift, so that's why it's hard to figure out what is causing this.
Any help is appreciated.
Thank you.
for Swift 3.0, use
override func tableView(_ tableView: UITableView, didSelectRowAt
indexPath: IndexPath){
//your code...
}
I encountered a similar problem. My problem was caused by having a superclass that adopted the UITableViewDelegate and UITableViewDataSource protocols, and then implementing the actual methods in a subclass.
What I gather is that because UITableViewDelegate and UITableViewDataSource are objective-c protocols, they must be adopted directly by the class implementing these functions. Otherwise the Swift function signatures will not be properly mapped to the objective-c function signatures (not sure why this is the case).
In Swift versions prior to 3.0, the underlying objective-c function signatures matched the signatures in the Swift UITableViewDelegate and UITableViewDataSource protocols. Therefore prior to 3.0 it seems to have worked fine to have a superclass adopt these protocols. However as of Swift 3.0 these signatures are no longer a match. It seems that to have the new-style signature properly mapped to the underlying objective-c signature, your class must directly adopt the UITableViewDelegate and UITableViewDataSource protocols.
Therefore in Swift 3.0 and later, if you do not directly adopt the UITableViewDelegate and UITableViewDataSource protocols then your function signatures must match the old-style underlying objective-c signatures in order for your functions to be called correctly.
I am stuck...
I have a collectionView (let's call it masterCollectionView). Each cell of the collectionView holds a list of data.
In each of these collectionView cells in the masterCollectionView, I have a tableView which holds all the records themselves in each row, grouped into tableView sections based on certain criteria within the dataset.
The data is stored in a multi-dimensional array which I download from the cloud, and this provides the list title to the masterCollectionView cell, as well as the # of sections, # of records (i.e. rows) in each list for the respective tableView.
My problem is that I can't tell which masterCollectionView cell I'm in when I'm populating the tableView. For example:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
}
The above function doesn't allow me to identify the masterCollectionView cell I'm currently building the tableView in and therefore I don't know which records in the data array to load.
At the moment I have all of the above built as one storyboard in interface builder along with one corresponding viewController but can easily change based on recommendations.
Please help. I'm pulling my hair out.
You probably want to have a separate instance of your table view data source for each collection view cell.
You could create a new NSObject subclass implementing UITableViewDataSource whose purpose is only to act as the data source for one cell. This object can be configured with the data for that cell only.
You would then have an array of these instances, one for each collection view cell. When the cell is loaded in cellForItemAtIndexPath, set that cell's table view delegate to the correct data source from the array.
Ok I will first give you the quickest solution to your problem, although its easy to implement it is not the 'right' way to do it I will explain later.
So the quickest way to do it is using view tags. Each UIView has a tag member which is an Integer. So where ever you are setting your tables, you can do this
I dont have your code so I am assuming you setting your table in
func collectionView(_ collectionView: UICollectionView,
cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
function of your UICollectionView, so in there you do something like this
myTableView.tag = indexPath.row
This should set tag to the TableView, when you are creating them which would be index in the array. and in your UITableView datasource you can do this
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourDataArray[tableView.tag].count;
}
This is the short and quick way the correct way would be to break up your data properly, may your UICollectionView cells as datasources for the included UITableView and then load the data when needed.
I am trying to get used to swift language so as usual after learning some basics about it I have started with storyboard and table view.I have dragged table view controller to storyboard
and created class for it and attached to view controller also.
As soon as I uncomment cellForRowAtIndexPath method I get following swift compiler error
Overriding method with selector 'tableView:cellForRowAtIndexPath:' has incompatible type '(UITableView!, NSIndexPath!) -> UITableViewCell!'
I also have included numberOfSectionInTableView and numberOfRowInSection delegate methods.
I don't know what I am doing wrong here.
so can anybody please help me resolve this issue.
Thanks in advance.
replace your function with this :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
}
This will solve your problem.
EDIT:
If you want to use existing function then you can remove all ! from function and your error will gone.