how to select only one cell from the tableviewsection - ios

I have used UITableViewSection. So i have listed the data which i needed.
But problem in selecting the UITableViewCell.
This is my code while selecting the cell.
this is the screen shot
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Section \(indexPath.section), Row : \(indexPath.row)")
let model = questionViewModel.titleForHeaderInSection(atsection:indexPath.section)
print(model.question)
// reviewViewModel.question = model.id
print(model.id)
let value: Int = model.id
let string = String(describing: value)
//let x: Int? = Int(model.id)
questionViewModel.question_id = string
questionViewModel.question = model.question
let optiondatasourcemodel:NH_OptionDataSourceModel = NH_OptionDataSourceModel(array: questionViewModel.tableArray[indexPath.section] as? [String] )
print(optiondatasourcemodel.dataListArray?.count)
let optionviewmodel:NH_OptionViewModel = NH_OptionViewModel(withdatasource: optiondatasourcemodel)
let optionmodel = optionviewmodel.datafordisplay(atindex:indexPath)
let modele = questionViewModel.titleForHeaderInSection(atsection: indexPath.section)
print(modele.buttontype)
optionviewmodel.button = modele.buttontype
let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell
print(questionViewModel.questionlist)
print(questionViewModel.questions)
print(questionViewModel.answers)
questionViewModel.question(answer:questionViewModel.question_id!)
questionViewModel.answer(answer: optionmodel.values!)
questionViewModel.questionlist(answer: questionViewModel.question!)
if optionviewmodel.button == "1" {
cell?.imagebutton.setImage(UIImage(named: "checkbox_check.png"), for: .normal)
self.selected = 1
questionViewModel.imagename = "1"
}
else if optionviewmodel.button == "2" {
self.selected = 1
cell?.imagebutton.setImage(UIImage(named: "radio_check.png"), for: .normal)
questionViewModel.imagename = "2"
}
}
according to the screenshot there are two question and have two options.From that i need to select only one option .
EX:are u fine:-question
answer:-yes
just select only one cell.
Once i select yes and i select no option then the data should remove from the array.
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let optiondatasourcemodel:NH_OptionDataSourceModel = NH_OptionDataSourceModel(array: questionViewModel.tableArray[indexPath.section] as? [String] )
print(optiondatasourcemodel.dataListArray?.count)
let optionviewmodel:NH_OptionViewModel = NH_OptionViewModel(withdatasource: optiondatasourcemodel)
let optionmodel = optionviewmodel.datafordisplay(atindex:indexPath)
let modele = questionViewModel.titleForHeaderInSection(atsection: indexPath.section)
print(modele.buttontype)
optionviewmodel.button = modele.buttontype
let cell = tableview.cellForRow(at: indexPath) as? NH_QuestionListCell
print(optionmodel.values)
questionViewModel.removequestion(question:questionViewModel.question!)
questionViewModel.removeanswer(answer:optionmodel.values!)
questionViewModel.removequestionid(removequestionid:questionViewModel.question_id!)
let model = questionViewModel.titleForHeaderInSection(atsection:indexPath.section)
print(model.question)
// reviewViewModel.question = model.id
print(model.id)
let value: Int = model.id
let string = String(describing: value)
//let x: Int? = Int(model.id)
questionViewModel.question_id = string
questionViewModel.question = model.question
questionViewModel.answer = optionmodel.values
if optionviewmodel.button == "1" {
cell?.imagebutton.setImage(UIImage(named: "checkbox_uncheck.png"), for: .normal)
self.selected = 1
questionViewModel.imagename = "1"
}
else if optionviewmodel.button == "2" {
self.selected = 1
cell?.imagebutton.setImage(UIImage(named: "radio_uncheck.png"), for: .normal)
questionViewModel.imagename = "2"
}
}
this is the code .
But according to this some problem.
Problems:-
when i select the second section that means.....
question:-are u happy
for that i selected option as yes.At that time ,i already for first question i have choose one option as yes .And checkbox image will display as click.
But while i select for next question the checkbox image of first question cell is disappear.How to fix that issues.
while selecting the second question option data is not appending in the array.
it is appending when i deselect the same cell
So how to fix the problem?

Related

How to work with the Cosmo Raiting Library in table cells? (SWIFT)

I don't understand how to link the selection of a set of rating stars to each cell and save this value?
Cosmo lib: https://github.com/evgenyneu/Cosmos
My Code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCellTableViewCell
let currentNameItem = gameNameArray[indexPath.row]
cell.gameNameLabel?.text = currentNameItem["Name"] as? String
// MARK: - переменная из словаря - если true ставим галочку - если нет убираем
if (currentNameItem["isCompleted"] as? Bool) == true {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
let currentSubNameItem = gameSubNameArray[indexPath.row]
cell.subGameNameLabel?.text = currentSubNameItem["Name"] as? String
let currentScoreItem = gameScoreArray[indexPath.row]
cell.gameScoreValue?.text = currentScoreItem["Name"] as? String
let currentImageItem = gameImageArray[indexPath.row]
guard let url = URL(string: currentImageItem["Name"] as! String) else { return cell }
cell.gameImage.sd_setImage(with: url, completed: nil)
//I can set the rating value
cell.fiveStarRaiting.rating = 5
let currentRaitingItem = raitingArray[indexPath.row] //array where I would like to save the ratings
cell.fiveStarRaiting.rating = currentRaitingItem //here, the values from the rating array should be pulled up by the ide
//allows you to save the rating value at the end of the finger movement gesture
cell.fiveStarRaiting.didFinishTouchingCosmos = { [self] raiting in raitingArray.append(raitingStarValue)}
print(raitingArray.count)
//cell.testButton0.addTarget(self, action: #selector(testFuncButton(sender:)), for: .touchUpInside)
return cell
}
As you know, table view cells are reusable, so when you scrolls and when cells are disappeared then its values are also cleared that's how table view and collection view works.
So if you want to save those ratings then you can go with a local temporary dictionary.
e.g.
var ratingsArray = [Int:Float]()
store your indexpath as key in "ratingsArray" dictionary and set its value as cosmos ratings.
and set cosmos ratings values as prefill in "cellForRowAt" table view method,
if ratingsArray.keys.contains(indexPath.row) {
cell.fiveStarRaiting.rating = 5
}
else {
cell.fiveStarRaiting.rating = 0 // set starts default value here
}
cell.fiveStarRaiting.didFinishTouchingCosmos = { [self] rating in
ratingsArray[indexPath.row] = rating
}

var late don't woking

the text must be red when the variable beats == "true"
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! InstallmentTableViewCell
if self.switchInstallmentToPay == true {
if let installment = PaymentManager.paymentPlan?.unpaidInstallments![indexPath.row] {
if let id = installment.id, let paymentDue = installment.paymentDue, let description = installment.numberDescription, let method = installment.paymentMethodDescription, let expectedPayment = installment.expectedPayment, let actualPayment = installment.actualPayment, let payable = installment.payable, let late = installment.late {
cell.load(id: id, paymentDue: paymentDue, description: description, method: method, expectedPayment: expectedPayment, actualPayment: actualPayment, payable: payable, late: late)
if installment.payable! {
cell.accessoryType = .checkmark
cell.tintColor = UIColor.lighterGray
cell.isUserInteractionEnabled = true
if installment.late! {
cell.lbDescription.textColor = UIColor.danger // not working
}
}else{
cell.accessoryType = .none
//cell.tintColor = UIColor.lightGray
cell.isUserInteractionEnabled = false
}
}
}
}else{
if let installment = PaymentManager.paymentPlan?.paidInstallments![indexPath.row] {
if let id = installment.id, let paymentDue = installment.paymentDue, let description = installment.numberDescription, let method = installment.paymentMethodDescription, let expectedPayment = installment.expectedPayment, let actualPayment = installment.actualPayment, let payable = installment.payable, let late = installment.late {
cell.load(id: id, paymentDue: paymentDue, description: description, method: method, expectedPayment: expectedPayment, actualPayment: actualPayment, payable: payable, late: late)
cell.accessoryType = .none
cell.isUserInteractionEnabled = false
cell.lbDescription.textColor = UIColor.black // not working
cell.tintColor = UIColor.lighterGray
}
}
}
return cell
}
This code is difficult to read, and there's a lot of redundancy. If you're using a storyboard, I suggest making separate dynamic cells for the paid and unpaid installments. Both cells' class type can stay InstallmentTableViewCell, as you're just duplicating the cells' views, not their logic. The various elements' colors & styles can be set right in the storyboard's cell prototype, and then your tableView(_:cellForRowAt:indexPath) can be simplified to just
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellID = switchInstallmentToPay ? "unpaidCell" : "paidCell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! InstallmentTableViewCell
cell.load(...)
return cell
}
I would also recommend changing cell.load() to take an installment argument and setting the cells' properties there instead of cluttering the caller with multiple if lets.

Hiding button on a particular tableview cell

Background:
My code displays a list of food items in a tableview, and in a UITableViewCell there is a button to add the food items to cart as needed.
When a particular item is added to cart, the add button corresponding to that cell should be hidden and rest all which are not added should not be hidden.
Problem:
The problem is, when I add an item say which is at index: 0 to cart, it gets added successfully and button is hidden, but when I click on second button which is at index : 1, second item also gets added to cart but the first item button becomes unhidden, at a time only one button which is at the current index is getting hidden instead of all the item buttons which are added to cart.
func addToCart(_ button : UIButton) {
self.selectedIndex = button.tag
let foodItem : HCFoodItem = arrFoodItems?.object(at: self.selectedIndex) as! HCFoodItem
foodItem.isFoodAddedToCart = true
arrItemsAddedToCart?.add(foodItem)
let arrayCount = arrItemsAddedToCart?.count
let badgeCount : String = String(format: "%d", arrayCount!)
tabBarController?.tabBar.items?.last?.badgeValue = badgeCount
HCDataCache.sharedDataCacheInstance.cacheData(object: arrItemsAddedToCart, key: HC_CACHE_KEY_CART_ITEM)
self.foodItemsTableView?.reloadData()
}
// hide/unhide buttons here...
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellId: NSString = "LazyLoadTableViewCell"
var foodItems : HCFoodItem?
foodItems = arrFoodItems?.object(at: indexPath.row) as! HCFoodItem?
let cell: HCFoodItemTableViewCell = tableView.dequeueReusableCell(withIdentifier: cellId as String)! as! HCFoodItemTableViewCell
cell.imgFood?.downloadImageFrom(link: foodItems?.strFoodImage as! String, contentMode: UIViewContentMode.scaleAspectFill)
cell.btnAddDelete?.tag = indexPath.row
cell.btnAddDelete?.addTarget(self, action: #selector(HCHomeViewController.addToCart(_:)), for: UIControlEvents.touchUpInside)
let itemsAddedToCart : NSMutableArray? = HCDataCache.sharedDataCacheInstance.fetchCachedDataForKey(key: HC_CACHE_KEY_CART_ITEM)
if (itemsAddedToCart?.count)! > 0 {
for cardFoodItem in itemsAddedToCart!{
let foodItem : HCFoodItem = cardFoodItem as! HCFoodItem
if foodItem.strFoodName == foodItems?.strFoodName {
cell.btnAddDelete?.isHidden = true
}else{
cell.btnAddDelete?.isHidden = false
}
}
} else {
cell.btnAddDelete?.isHidden = false
}
cell.selectionStyle = .none
return cell
}

multiple rows gets selected while selecting a single row on tableView

am having this strange issue while am selecting any of the row from TableView another row is also get selected , say i have a tableView with multiple rows in my case its 11 and multiple selection with the accessory of tick mark is enabled (when i select a row a tick is marked on the selected row ) so when am selecting my first row , then row number 8 is also got selected (i can see the tick mark in the row number 8 but i selected only the row number 1 ) when i select another row number 2 my row number 9 is also get selected dont know why this is happening if anybody knows anything about this behaviour then please let me know it'll be so helpful for me , below is the code of didSelectRowAtIndexPath :
var selectedTextLabels = [NSIndexPath: String]()
var selectedTextLabelsName = [NSIndexPath: String]()
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let cell = tableView.cellForRowAtIndexPath(indexPath) as! UsersTableViewCell
if (cell.accessoryType == UITableViewCellAccessoryType.Checkmark){
cell.accessoryType = UITableViewCellAccessoryType.None;
selectedTextLabels[indexPath] = nil
selectedTextLabelsName[indexPath] = nil
}else{
cell.accessoryType = UITableViewCellAccessoryType.Checkmark;
if (cell.accessoryType == UITableViewCellAccessoryType.Checkmark){
if let Id = cell.channelIDLbl?.text {
selectedTextLabels[indexPath] = Id
}
if let channelName = cell.lblChannelname?.text{
selectedTextLabelsName[indexPath] = channelName
}
}
}
cellForRowAtIndexpath:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UsersTableViewCell
if isFavoritesTabActive == true {
let object : RChannels = self.favoritesArray.objectAtIndex(indexPath.row) as! RChannels
cell.lblChannelname.text = object.channelName
let favorite = object.isFavorite
if favorite == "true" {
cell.favIcon.image = UIImage(named: "Favourite")
return cell }
else {
let object : RChannels = self.noteObjects.objectAtIndex(indexPath.row) as! RChannels
cell.lblChannelname.text = object.channelName
let favorite = object.isFavorite
if favorite == "true" {
cell.favIcon.image = UIImage(named: "Favorite")
}else {
cell.favIcon.image = UIImage(named: "unFavorite") }
return cell
}
checking inside the channelIDLbl array for existence of the cell's id at cellforRowAtIndexPath did the job
if ((selectedTextLabels[indexPath]?.containsString("\(cell.channelIDLbl)")) != nil){
cell.accessoryType = .Checkmark
}else {
cell.accessoryType = .None
}
for more detail please check this same question

Why is my SearchController not displaying the correct cell prototype for the first cell?

As the title suggests, I am having trouble with my UISearchController displaying the wrong cell prototype for the first cell in the search results.
Background Information: I have two cell prototypes, one without an image (identifier: basicCell) and another with a UIImageView (identifier: imageCell). Cells work perfectly when not searching.
Detailed Description of the Problem: When I click on the search bar everything is fine until I start searching for something. When I do, the first cell always has the imageCell identifier (a gray empty image view is shown denoting the lack of an image), no matter what. NB: Before searching anything, the first cell in the tableview has a custom image... Maybe that's of note?
Anyway I have no idea what I am doing wrong. Would anyone mind helping?
Code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (self.resultSearchController.active) {
if hasImageAtIndexPath(indexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier(imageCellIdentifier, forIndexPath: indexPath) as! TimelineTableViewCellImage
let event = filteredTableData[indexPath.row]
cell.content.text = profile.content
cell.name.text = profile.name
//This is the image
cell.attachment.image = profile.image
cell.attachment.layer.cornerRadius = 1
cell.attachment.clipsToBounds = true
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier(basicCellIdentifier, forIndexPath: indexPath) as! TimelineTableViewCell
let event = filteredTableData[indexPath.row]
cell.content.text = profile.content
cell.name.text = profile.name
return cell
}
} else {
if hasImageAtIndexPath(indexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier(imageCellIdentifier, forIndexPath: indexPath) as! TimelineTableViewCellImage
let event = events[indexPath.row]
cell.content.text = profile.content
cell.name.text = profile.name
cell.attachement.image = profile.image
cell.attachment.layer.cornerRadius = 1
cell.attachment.clipsToBounds = true
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier(basicCellIdentifier, forIndexPath: indexPath) as! TimelineTableViewCell
let event = events[indexPath.row]
cell.content.text = profile.content
cell.name.text = profile.name
return cell
}
}
}
And this is my code that checks for an image:
func hasImageAtIndexPath(indexPath:NSIndexPath) -> Bool {
let event = events[indexPath.row]
let imageArray = [event.image]
for eventImage in imageArray {
if eventImage != nil {
return true
}
}
return false
}
You need to have an if-else clause in your hasImageAtIndexPath: function just like you have in your cellForRowAtIndexPath:. If the table view is the search table, then event needs to be defined the same way as you have in cellForRowAtIndexPath:,
func hasImageAtIndexPath(indexPath:NSIndexPath sender:UITableView) -> Bool
if (self.resultSearchController.active){
let event = filteredTableData[indexPath.row]
}else{
let event = events[indexPath.row]
}
let imageArray = [event.image]
for eventImage in imageArray {
if eventImage != nil {
return true
}
}
return false
}

Resources