Closed rupeshsaxena closed 8 years ago
Hi, the CosmosView
is simply a subclass of a UIView so you can use it in a table view cell and position with auto layout like any other view. I assume you know how to do it, if you don't I would suggest to learn that first. The demo app has "Performance" button that displays a screen with Cosmos rating controls in a table, so you can check how it is done there as an example.
To collect rating from the user and send it to your server you can use didFinishTouchingCosmos
property of cosmos view, there is example in the readme. You can assign a function to it after getting your cell view with dequeueReusableCellWithIdentifier
function.
Feel free to experiment with user input by playing with the demo app. The cosmos view in the demo app has the user input switched off so it only displays rating but does not react to touch. You can switch user input on by setting Update on touch
property to 'On' for the cosmos view in the storyboard.
Thanks for your prompt response, I made an another closure for didFinishTouchingCosmos to get the specific cosmosview from the cell and get it's rating according to number of cells having CosmosView.
Hi, Can you pls help me with the closure you wrote, to get the cell associated with the rating view? Am able to get the TableView display the cosmos rating and didTouchCosmos/didFinishTouchingCosmos are getting triggered as well. It displays the ratings, but am not sure how to find the cell associated with it. Hope am clear.
Hi @iosnewbie2016, good question. We can associate a UITableViewCell with the cosmos view touch event in the code that calls dequeueReusableCell
, as shown in the demo app's PerformanceTableViewController
:
Here we get a cell
object that is associated with the particular cell. We can then write a function or a property for the cell and assign it a unique identifier. When didFinishTouchingCosmos
is called, we can use this identifier. This way we will know in which cell the user touched the stars. Will it work for you?
Hi @evgenyneu , I added one more property in settings of Cosmos and use that to identify the cell row number. Then return that along with ratung in didFinishTouchingCosmos.
I have created cell in the code like you have shown, but am not clear how you are suggesting to get a cell where the user touches the stars. I use a Viewcontroller with a Table View, instead of a Tableviewcontroller. I dont think that will make any difference.
Yes, you can do this, but since you modified the library you will have to do this with each update of Cosmos. Alternatively, I think an easier approach would be to create a property in your UITableViewCell object. Since this object can contain an outlet for the Cosmos view, they are bundled together. Therefore, when your didFinishTouchingCosmos
is called you can access your UITableViewCell object and read this property that you added to the cell. Am I explaining it right?
Hi @evgenyneu , Yes. I did create a class which subclasses UITableViewcell and it has a property to hold the rating view. let cell = tableView.dequeueReusableCell(withIdentifier: "MenuRequestCell", for: indexPath) as! MenuTableViewCell
and I can access it via cell.ratingView.
But in didFinishTouchingCosmos (or didTouchCosmos), I only get rating
func didFinishTouchingCosmos(_ rating: Double) {}
So, am not sure how do I get the cell corrosponding to this. Hope am clear.
Yes, I agree with you that it is not recommended to manipulate Cosmos, so that future upgrades are easier to handle.
Sorry for not explaining it properly. Those Swift closures can be tricky to work with, but they allow to access the properties of the containing class through self
. As you can see in the example below we can access the id
property of the cell from the didFinishTouchingCosmos
closure. Let me know if further clarification is needed.
public class PerformanceTableViewCell: UITableViewCell {
@IBOutlet var cosmosView: CosmosView!
var id: Int = 0
func update(_ rating: Double, id: Int) {
cosmosView.rating = rating
self.id = id
cosmosView.didFinishTouchingCosmos = { [weak self] rating in
print(self?.id) // Access property here
}
}
}
A slight detail here is that we used weak self
in the closure to avoid memory leaks.
Hi @evgenyneu , Thanks for the update. I was trying to use the didFinishTouchingCosmos in the main ViewController (and in the table view cell). I understand the disconnect now. I will try this and let you know if I run into any trouble. Thanks again.
Hi @evgenyneu I know this thread is super old already but in 2020 I am still struggling with this.
I am using a tableview and have multiple cosmos ratings within this tableview. The user can rate the different items in the tableview itself. The screenshot shows the Rating TableViewController.
my two files look like this and I want to get the rating stored for each Item/ Row so I can upload the rating afterwards in Firebase. Maybe you can help me connecting the missing dots in this :)
`class RatingItem { var key: String?
var item: String
var rating: Int
init?(item: String, rating: Int) {
// Initialization should fail if there is no name or if the rating is negative.
// The name must not be empty
guard !item.isEmpty else {
return nil
}
// The rating must be between 0 and 5 inclusively
guard (rating >= 0) && (rating <= 7) else {
return nil
}
// Initialize stored properties.
self.item = item
self.rating = rating
}
var dictValue: [String: Any] {
let createdAgo = kSecAttrCreationDate
return ["Rating_Item" : item,
"Rating_rating": rating,
"created_ago": createdAgo]
}
init?(snapshot: DataSnapshot) {
guard let dict = snapshot.value as? [String: Any],
let item = dict["Rating_Item"] as? String,
let rating = dict["Rating_rating"] as? Int
else {return nil}
self.key = snapshot.key
self.item = item
self.rating = rating
}
}
// MARK: - Extension
extension TeamMemberRatingViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ratingItems.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let ratingItemT = ratingItems[indexPath.row]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Fetches the appropriate meal for the data source layout.
let ratingItemT = ratingItems[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "TeamMemberRatingTableViewCell", for: indexPath) as! TeamMemberRatingTableViewCell
cell.itemLabel.text = ratingItemT.item
return cell
}
} // MARK: - UITableViewDelegate
extension TeamMemberRatingViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 80
}
}
`
Hi @manuG420, it's hard for me to debug a code here. Have you looked at the Performance screen of the demo app? It shows how to show rating in a table view and store/update the individual ratings.
How can we use Cosmos Star on UITableViewCell , since my requirement is to get multiple rating stars to rate on specific cell index and send to server