pavankataria/SwiftDataTables

didTap on row

dneykov opened this issue Β· 25 comments

Hi,

is there a support for tapping of row and segue to another view controller? Thanks

Hah, that would seem like an obvious feature to implement, to be fair I built this for display purposes so it didn't come across my mind. This should be quick to implement, stay tuned. I'll add a quick delegate method for you. Stay tuned.

@pavankataria Any news on this feature ?

@hammood I have a pretty basic version of this working but it is no where near being worthy of a pull request. It could be at some point in the near future although I might not get it to that level as it almost already meets my needs. I would be happy to post my code if you still need it though!

Hey, I was working on this yesterday after I saw more comments on this thread.

I've implemented a method like this so far in the SwiftDataTableDelegate:

func didSelectItem(_ dataTable: SwiftDataTable, indexPath: IndexPath)

Would this be adequate? You'd be able to retrieve the data by querying your own datasource.

Does this work for you guys? @dneykov, @hammood, and @jwhitey2000.

I think that will do it. Thanks.

That is perfect, thank you!

fixed in my fork https://github.com/altagir/SwiftDataTables
and you cannot use indexPath, since it is sorted

I'd like to think you should return what was exactly selected. The datasource is driven by the developer's datasource, and so there should always be one source of truth.

This means referencing 0,1 even if the table is sorted should correctly point out to the datasource's data model correctly.

πŸŽ‰ πŸŽ‰ @dneykov, @hammood, @jwhitey2000, @altagir
This is now available as of version 0.7.0 πŸŽ‰ πŸŽ‰ https://github.com/pavankataria/SwiftDataTables/releases/tag/0.7.0

This is how the methods are defined in the SwiftDataTableDelegate interface:

    /// Fired when a cell is selected.
    ///
    /// - Parameters:
    ///   - dataTable: SwiftDataTable
    ///   - indexPath: the index path of the row selected
    @objc optional func didSelectItem(_ dataTable: SwiftDataTable, indexPath: IndexPath)

    /// Fired when a cell has been deselected
    ///
    /// - Parameters:
    ///   - dataTable: SwiftDataTable
    ///   - indexPath: the index path of the row deselected
    @objc optional func didDeselectItem(_ dataTable: SwiftDataTable, indexPath: IndexPath)

It's up to you to refer to the correct data from your datasource by using the indexpath as a correct reference for what the user precisely selected.

Let me know how it goes. πŸŽ‰

@pavankataria Thanks!

Looking forward to use it in my project. Of course that delegate should return IndexPath of selected row.

Uhm as stated earlier there is an issue with indexPath

  • when we fill the dataSource with our model (unsorted / independant)
  • then click on cell, return indexPath which refers to the sorted element (from DatableView view, which should remain independant from model)

to be able to use indexPath, you must put currentRowViewModels and stringRepresentation as public.
so at least we can get the actual content (and IDs) from your view.

else one would need to sort also our model, thus breaking the model view independance

public var currentRowViewModels: DataTableViewModelContent {...} public var stringRepresentation: String

Disclaimer: Typing on my phone atm.

I see your point. You’re right. It’s currently private and I sort it myself with the request to have a delegate either the data source is supplied how conventional layouts work but in this case The library does the leg work of sorting too.

One way of solving it from the top of my mind could be to change the data source as you mentioned to public. This way the method is more dynamic since the string representation could change in the future. I may have picture cells in there soon, heck even dynamic cells. That’ll be something to look forward to.

Or we could just add a method so you can access the content like so:
dataModel(for: indexPath)

Another option is to return the index path; expose the row view models and finally return the rowModel as an extra parameter to the didSelectItem delegate method.

I know some are keen to have the index path returned; but returning an index path without making the row models public seems pointless

I use :

public func didSelectItem(_ dataTable: SwiftDataTable, indexPath: IndexPath) {
        let selectedClaimID: String = dataTable.currentRowViewModels[indexPath.section][0].stringRepresentation
        print("select \(indexPath.section) - \(indexPath.row) " + selectedClaimID)
}

changed needed :

in SwiftDataTables.swift -> add public

public var currentRowViewModels

in DataCellViewModel.swift -> add

    public var stringRepresentation: String {
        get {
            return self.data.stringRepresentation
        }
    }

What are you trying to achieve with the string representation?

I need to get the original string... so i can find ID i put there and find it from my model

if let claim = claims.first(where: { $0.number == selectedClaimID }) {...}

You can get the tapped view model by using the index path and the what will soon be a public access to the row view models anything further than this would be too nichΓ©.

you know what's the next feature people are gonna scream after this ?
an optional highlight color for selected row.
since table acually act as select / deselect

can code that one in a pull request later this week if you want.
could be a color blending with the sorted column color or just override it
unsure about blending with customized cell color itself. would let the row selected color simply override it

what do you think all?

πŸŽ‰ πŸŽ‰ @dneykov, @hammood, @jwhitey2000, @altagir
Important update
There is a rows property you can access to get the rows of the datasource as is maintained by SwiftDataTable.

func didSelectItem(_ dataTable: SwiftDataTable, indexPath: IndexPath) {
    let dataValueType = dataTable.rows[indexPath.section][indexPath.row]
    let value = dataValueType.stringRepresentation
}

And to make things more convenient there is a method that you can use that will access the data value for you by passing in the index path like so:

let dataValueType = dataTable.data(for: indexPath)
...

This will give you the exact cell's value that was tapped.

This is now available as of version 0.7.2 πŸŽ‰ πŸŽ‰ https://github.com/pavankataria/SwiftDataTables/releases/tag/0.7.2

I hope this will serve you well.
Let me know what you think πŸŽ‰

πŸš€ SwiftDataTables (0.7.2) successfully published on πŸ“… March 7th, 22:58 GMT
πŸ‘ Share with your friends and colleagues!

let dataValueType = dataTable.rows[indexPath.section][indexPath.row]
let value = dataValueType.stringRepresentation

Value of type 'DataCellViewModel' has no member 'stringRepresentation'
as mentioned earlier, in DataCellViewModel.swift -> add

public var stringRepresentation: String {
    get {
        return self.data.stringRepresentation
    }
}

you didn't update master? podspec is still at 0.7.1 in master, and i don't see commit
https://github.com/pavankataria/SwiftDataTables/blob/master/SwiftDataTables.podspec

pod update did update to 0.7.2

master still not updated, so not available through pod update.
Please reopen bug until fixed

πŸ€” strange. Let me see what's going on

Does using this not achieve this?
dataTable.data(for: indexPath)).stringRepresentation?

master still not updated, so not available through pod update.

Not sure what you mean, everything is available through pod update.
The latest commit also is there.
Regardless the issue still stood related to the accessor issues.

This has now been resolved and now available as of version 0.7.3 πŸŽ‰ πŸŽ‰ https://github.com/pavankataria/SwiftDataTables/releases/tag/0.7.3

Hi Pavan
It happened because I directly pointed to your github entry in my Pod.
I also tested directly from a clone of your project :)
thanks for updating master