SegmentControl duplicating Checkmarks on UITableviewCell - ios

Basically I am using the pod M13Checkbox which works great when I do not incorporate my UISegmentedControl. I have two todo lists separated into two segments. As soon as I check a box on the first segment it is repeated on the second segment.
I'm not sure if this is because of the cell being reused or not. Using print statements I have figured out I am able to see the data of the indexpath.row disregarding what segment is currently showing. Just the checkmarks I cannot control.
Please disregard any "Firebase notes".
class ToDoList: UITableViewController {
#IBOutlet weak var segment: UISegmentedControl!
var selectedRow: Int = 0
let seg1 = ["first","tab","Index"]
let seg2 = ["second","segment","akjdhfajd"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var returnValue = 0
switch(segment.selectedSegmentIndex) {
case 0: returnValue = seg1.count
case 1: returnValue = seg2.count
default: break
}
return returnValue
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoCell", for: indexPath) as! ToDoCell
switch (segment.selectedSegmentIndex) {
case 0:
segment.selectedSegmentIndex = 0
selectedRow = 0
cell.item.text = seg1[indexPath.row]
cell.box.tag = indexPath.row
case 1:
segment.selectedSegmentIndex = 1
selectedRow = 1
cell.item.text = seg2[indexPath.row]
cell.box.tag = indexPath.row
print(cell.box.tag)
default:
break
}
cell.box.addTarget(self, action: Selector(("checkboxPressed")), for: UIControlEvents.touchUpInside)
return cell
}
#IBAction func checkboxPressed(_ sender: M13Checkbox) {
let buttonRow = sender.tag
let listItem = [buttonRow]
let todoDict = ["\(buttonRow)": "True"]
//need to individually checkbox the cases .. at moment if i check one it checks the other also
if sender.checkState == .checked || sender.checkedValue == nil {
print("\(buttonRow)")
if selectedRow == 0 {
let listArrayItem = seg1[buttonRow]
sender.checkedValue = listArrayItem
print(listArrayItem)
} else {
print("we are on segment 2")
}
} else if sender.checkState == .unchecked {
// if its unchecked. then u want to remove it from the checked item in firebase.. we will only load checked items obviosuly..
//remove from completed list
}
}
}

Related

Cell touch action is not responding on short touches in TableView

I have a Scene in storyboard that contains HistoryTable with historyCell and own UserHistoryViewCell view. This cell and also table is set to User interaction Enabled in Traits and Interaction sections. Scrolling is disabled and Delay Touch Down is also disabled. This cell is not responding at didSelectRowAt func at short click (only when pressing longer than 5? secs). I have a Tap Gesture Recognizer in my Scene and also another table with same problem. I tried to disable Tap Gesture Recognizer, but it seems that it doesn't do anything special. I'm not sure where is problem, I have my tables delegated and using the code bellow. I also provide screenshots of Attributes inspector for the table and cell. Btw. My second table has sections, so its little bit messy.
Second Btw. I have delay touch down enabled at the screenshot, because it has no effect at all. Third Btw. I have historyButton in my historyTable which is for removing old records. It has no impact at the cell itself (I think) because same stuff happens to my second table without this button. Also it worked before I added sections to my second table.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var counter = 0
if tableView.tag == 1 {
counter = (UserDefaults.standard.stringArray(forKey: "HistoryArray") ?? [String]()).count
let base = 60
self.historyTableHeightConstraint.constant = CGFloat(base) + CGFloat(counter) * 40
} else {
switch section {
case 0:
counter = presenter.storelist?.count ?? 0
case 1:
counter = presenter.storelist?.count ?? 0
default:
counter = 0
notFoundLabel.isHidden = false
}
}
return counter
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == 1 {
let defaults = UserDefaults.standard
let userSearchHistory = defaults.stringArray(forKey: "HistoryArray") ?? [String]()
let cell = tableView.dequeueReusableCell(withIdentifier: "historyCell", for: indexPath) as! UserHistoryTableViewCell
cell.titleLabel.text = userSearchHistory.reversed()[indexPath.row]
cell.historyButton.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside)
cell.historyButton.tag = indexPath.row
if self.editable == true {
let newImage = UIImage(named: "RemoveIcon")
cell.historyButton.setImage(newImage, for: .normal)
cell.historyButton.isEnabled = true
} else {
let newImage = UIImage(named: "searchHistoryIcon")
cell.historyButton.setImage(newImage, for: .normal)
cell.historyButton.isEnabled = false
}
return cell
} else {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: "shopSearchCell", for: indexPath) as! ShopSearchTableViewCell
cell.shopLabel.text = presenter.storelist?[indexPath.row].storename
return cell
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: "SearchResultCell", for: indexPath) as! SearchResultCell
cell.SearchResultLabel.text = presenter.storelist?[indexPath.row].storename
return cell
default:
return UITableViewCell()
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(#function + "\(indexPath.row)")
}
func tableView(_ tableView: UITableView, titleForHeaderInSection
section: Int) -> String? {
if tableView.tag == 2 {
if section == 0 {
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return "Search shop"
} else {
return nil
}
} else {
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return "Search"
} else {
return nil
}
}
} else {
return nil
}
}
// Section数
func numberOfSections(in tableView: UITableView) -> Int {
if tableView.tag == 2 {
return 2
}
return 1
}

TableView cells becomes inactive

I am using a tableView to take some surveys.
Header I use for a question. Footer for «back» and «next» buttons. And tableView cells for answer options.
Now I started to have a problem, with some user interaction: when you simultaneously click on the “next” button and select an answer, the answer options cease to be active, nothing can be selected. Although the buttons remain active.
Tell me in what direction to look for the problem and how you can debug this problem in order to understand what's wrong.
It all started after fixing bugs, when the application crashed when simultaneously (or almost) pressing the "next" button and choosing an answer. Because the didSelectRowAt method worked after I changed the current array of answer options, and the selected index in the previous question turned out to be larger than the size of the array with the answers to the new question.
class AssessmentVC: UIViewController {
#IBOutlet weak var tableView: UITableView!
var footer: FooterTableView?
var header: UIView?
var arrayAssessmnet = [AssessmentDM]()
var assessment: AssessmentDM!
var question: QuestionDM!
var viewSeperationHeader = UIView()
var arrayOptions: [Option]?
var countAssessment = 0
var numberAssessment = 0
var numberQuestion = 0
var countQuestion = 0
var numberQusttionForLabel = 1
var arrayQuestion = [QuestionDM]()
var arrayAnswers = [AnswerDM]()
var arrayEvents = [EventDM]()
override func viewDidLoad() {
super.viewDidLoad()
settingAssessment()
}
//MARK: - settingAssessment()
private func settingAssessment() {
let id = self.assessment.serverId
arrayQuestion = QuestionDM.getQuestions(id: id)
assessmentName.text = assessment.name
countQuestion = arrayQuestion.count
let day = self.assessment.day
arrayAnswers = AnswerDM.getAnswers(idAssessment: id, day: day)
settingQuestion(eventType: .start)
}
//MARK: - settingQuestion()
private func settingQuestion(eventType: EventType? = nil) {
let prevQuestion = question
question = arrayQuestion[numberQuestion]
timeQuestion = 0
footer!.grayNextButton()
//first question
if numberQuestion == 0 && numberAssessment == 0 {
footer!.previousButton.isHidden = true
} else {
footer!.previousButton.isHidden = false
}
arrayOptions = [Option]()
let sortOption = question.options!.sorted {$0.numberOption < $1.numberOption}
for option in sortOption {
arrayOptions?.append(Option(label: option.label, value: option.value))
}
tableView.rowHeight = UITableView.automaticDimension
tableView.reloadData()
heightTableView()
tableView.setContentOffset(.zero, animated: false)
}
//MARK: - heightTableView()
func heightTableView() {
}
//MARK: - UITableViewDataSource
extension AssessmentVC: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
viewSeperationHeader.isHidden = false
footer?.viewSeperationFooter.isHidden = false
tableView.separatorStyle = .singleLine
return question.options?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath as IndexPath) as AnswerAssessmentCell
cell.initCell(text: arrayOptions![indexPath.row].label, value: arrayOptions![indexPath.row].value, arrayValue: arrayAnswers[numberQuestion].response, isCheckbox: true)
return cell
}
}
//MARK: - UITableViewDelegate
extension AssessmentVC: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
isChangAnswerInAssessment = true
if question.answerType == "Radio" || question.answerType == "Checkbox"{
selectRadioOrChekbox(indexPath: indexPath)
}
}
}
//MARK: - selectRadioOrChekbox
extension AssessmentVC {
private func selectRadioOrChekbox(indexPath: IndexPath) {
if question.answerType == "Radio" {
let cells = tableView.visibleCells as! Array<AnswerAssessmentCell>
for cell in cells {
cell.select = false
cell.isSelected = false
}
let cell = tableView.cellForRow(at: indexPath) as! AnswerAssessmentCell
cell.select = true
cell.isSelected = true
if arrayOptions?.count ?? 0 > indexPath.row {
arrayAnswers[numberQuestion].response = arrayOptions![indexPath.row].value
footer?.greenNextButton()
}
}
if question.answerType == "Checkbox" {
if arrayOptions?.count ?? 0 > indexPath.row {
//если нажато что-то, что должно сбросить "None"
// question.options![0].isSelect = false
let cells = tableView.visibleCells as! Array<AnswerAssessmentCell>
if cells[0].answerLabel.text == "None" {
cells[0].select = false
cells[0].isSelected = false
}
var array = arrayAnswers[numberQuestion].response?.components(separatedBy: ";")
array?.removeAll { $0 == "0"}
if array?.count == 0 {
arrayAnswers[numberQuestion].response = nil
} else {
arrayAnswers[numberQuestion].response = array?.joined(separator: ";")
}
let cell = tableView.cellForRow(at: indexPath) as! AnswerAssessmentCell
cell.select = !cell.select
cell.isSelected = cell.select
arrayAnswers[numberQuestion].response = array.joined(separator: ";")
if array.count == 0 {
arrayAnswers[numberQuestion].response = nil
footer?.grayNextButton()
} else {
footer?.greenNextButton()
}
}
}
}
}
//MARK: - Navigation between questions
extension AssessmentVC {
func nextQuestion() {
footer!.grayNextButton()
numberQuestion += 1
numberQusttionForLabel += 1
settingQuestion(eventType: .next)
} else {
}
func previousQuestion() {
numberQusttionForLabel -= 1
settingQuestion(eventType: .previous)
}
}
Some snippets that can help you :
// Answer type : use enum . Here the Strong/Codable is if you want to
// save using JSON encoding/decoding
enum AnswerType: String, Codable {
case checkBox = "CheckBox"
case radio = "Radio"
}
Setup of your cell :
class AnswerAssessmentCell: UITableViewCell {
...
// work with Option type
func initCell(option: Option, response: String?, answerType: AnswerType) {
// setup cell contents (labels)
// check for selected status
switch answerType {
case .checkBox:
// check if option is in response
// set isSelected according
break
case .radio:
// check if option is response
// set isSelected according
break
}
}
}
In table view data source :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AnswerAssessmentCell
// Use the option to init the cell
// this will also set the selected state
let optionNumber = indexPath.row
cell.initCell(option: arrayOptions![optionNumber], response: arrayAnswers[numberQuestion].response, answerType: question.answerType)
return cell
}
In Table view delegate :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
isChangAnswerInAssessment = true
let optionNumber = indexPath.row
switch question.answerType {
case .radio:
selectRadio(optionNumber: optionNumber)
case .checkBox:
selectCheckBox(optionNumber: optionNumber)
}
// Reload tableview to show changes
tableView.reloadData()
}
// Separate in 2 function for smaller functions
// in this function work only with model data, the reload data will do
// cell update
// only the footer view button cooler may need to be changed
private func selectRadio(optionNumber: Int) {
// Reset current response
// set response to optionNumber
// update footer button cooler if necessary
}
private func selectCheckBox(optionNumber: Int) {
// if option is in response
// remove option from response
// else
// add response to option
// update footer button cooler if necessary
}
Hope this can help you

Single and MultiSelection cells in same tableView | Swift

Before duplicating this question, please be known that I've spent days on this issue, working hours, and looking for all same sort of questions on SO, but there is something I am missing or doing wrong.
I have a tableView in which the data is being populated via API response. Below is the model I have.
struct Model : Codable {
let bugClassification : [Bug]?
}
struct Bug : Codable {
let selectable : String? //Telling wether cell is single/Multi selected
var options : [Options]?
}
struct Options : Codable, Equatable {
let title : String?
let id: Int
var isCellSelected: Bool = false
}
Scenario
I want to create multiple sections, each having different cell depending upon the type of selectable, either single or multi. I have achieved that, but the problem I am getting is that whenever I scroll, random cells are also selected. Now, I know this behaviour is because of tableView reusing the cells. But I am confused as how to handle all this. Also, I want to put the validation on the sections, that is, every section should have atleast one cell selected. Kindly guide me in the right direction, and any small help would be appreciated. Below is my code.
CellForRowAt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if bugClassification[indexPath.section].selectable?.lowercased() == "multi-select" {
//Multi-Selection
let cell = tableView.dequeueReusableCell(withIdentifier: multiSelectionCellID) as! MultiSelectionCell
let item = bugClassification[indexPath.section].options![indexPath.row]
cell.label.text = item.title
if item.isCellSelected {
cell.checkMarkImageView.alpha = 1
cell.checkMarkView.layer.borderColor = UIColor.white.cgColor
cell.checkMarkView.backgroundColor = .emerald
} else if item.isCellSelected {
cell.checkMarkImageView.alpha = 0
cell.checkMarkView.layer.borderColor = UIColor.veryLightBlue.cgColor
cell.checkMarkView.backgroundColor = .white
}
return cell
} else {
//Single-Selection
let cell = tableView.dequeueReusableCell(withIdentifier: singleSelectionCellID) as! SingleSelectionCell
let item = bugClassification[indexPath.section].options![indexPath.row]
cell.label.text = item.title
if item.isCellSelected {
cell.checkMarkImageView.alpha = 1
cell.checkMarkView.layer.borderColor = UIColor.emerald.cgColor
} else {
cell.checkMarkImageView.alpha = 0
cell.checkMarkView.layer.borderColor = UIColor.veryLightBlue.cgColor
}
return cell
}
}
DidSelectRow Method
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if bugClassification[indexPath.section].selectable?.lowercased() == "multi-select" {
var item = bugClassification[indexPath.section].options![indexPath.row]
item.isCellSelected = !item.isCellSelected
bugClassification[indexPath.section].options![indexPath.row] = item
self.tableView.reloadRows(at: [indexPath], with: .automatic)
} else {
let items = bugClassification[indexPath.section].options
if let selectedItemIndex = items!.indices.first(where: { items![$0].isCellSelected }) {
bugClassification[indexPath.section].options![selectedItemIndex].isCellSelected = false
if selectedItemIndex != indexPath.row {
bugClassification[indexPath.section].options![indexPath.row].isCellSelected = true
}
} else {
bugClassification[indexPath.section].options![indexPath.row].isCellSelected = true
}
self.tableView.reloadSections([indexPath.section], with: .automatic)
}
}
In cellForRowAt
if item.isCellSelected == true{
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
and update the model by every selection
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let item = bugClassification[indexPath.section].options![indexPath.row]
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .none
if indexPath.section == 0{
item.isCellSelected.isSelected = false
}else{
item.isCellSelected.isSelected = false
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = bugClassification[indexPath.section].options![indexPath.row]
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
if indexPath.section == 0{
item.isCellSelected.isSelected = true
}else{
item.isCellSelected.isSelected = true
}
}
}

Increase and Decrease values on Button click

I want to show value on UIlabel. when I press UIbutton to increase or decrease values on label. This is my code and when I am running my project but I didn't get any value on my uilabel.
#IBAction func btnIncreaseAction(_ sender: Any) {
var count = 0
count = (count + 1)
if let cell = (sender as? UIButton)?.superview?.superview?.superview as? ShoppingCell
{
//cell.lblForOnty.text = "\(cell.lblForOnty.text ?? 0 + 1)"
cell.lblForOnty.text = String(count)
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellRID") as! ShoppingCell
var someValue: Int = 0 {
didSet {
cell.lblForOnty.text = "\(count)"
}
}
return cell
}
}
This is the code which should be in your ViewController. I am assuming that numberOfSections is 1 and in numberOfRowsInSection you are passing then number of rows you want. Else you need to modify this line : let indexPath = IndexPath(row: sender.tag, section: 0).
var count = 0 // Count variable should be a global variable, you need it to decrease the value too.
#objc func increaseCounter(sender: UIButton) {
//increase logic here
count = (count + 1)
let indexPath = IndexPath(row: sender.tag, section: 0)
let cell = tableView.cellForRow(at: indexPath)
cell.lblForOnty.text = "\(count)"
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellRID") as! ShoppingCell
// Add tag and action to your button
cell.yourButton.tag = indexPath.row
cell.yourButton.addTarget(self, action: #selector(increaseCounter(sender:)), for: .touchUpInside)
return cell
}
superview?.superview?.superview is pretty weird. Don't do that. A callback is more reliable.
In the subclass ShoppingCell create a callback and the IBActions for in- and decrease . Connect the actions to the buttons
class ShoppingCell: UITableViewCell {
#IBOutlet weak var lblForOnty: UILabel!
var callback : ((Int)->())?
var counter = 0 {
didSet {
lblForOnty.text = "\(count)"
}
}
#IBAction func btnIncreaseAction(_ sender: UIButton) {
counter += 1
callback?(counter)
}
#IBAction func btnDecreaseAction(_ sender: UIButton) {
if counter > 0 { counter -= 1 }
callback?(counter)
}
}
In cellForRow pass the counter value to the cell and use the callback to update the model which is represented by dataSource and which is a custom struct or class containing a property counter.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellRID", for: indexPath) as! ShoppingCell
let item = dataSource[indexPath.row]
cell.counter = item.counter
cell.callback = ( newValue in
item.counter = newValue
}
return cell
}
No hassle with superviews and index paths.
Move you count variable outside of the function
Increment/decrement the count inside the function and reload the table or you can reload particular index as well.
PFB the code snipped
let indexPath = NSIndexPath(forRow: rowNumber, inSection: 0)
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Top)
Please follows these step:
Step 1 :
create object class
class QuantityBO : NSObject{
var quantity : Int?
}
step 2:
Create global array in your class
var arrQuantityList = [QuantityBO]()
step 3 :
Assign the value according to your number of cell
It may be change according to your api resonse
step 4:
In cellForRowAt method please write:
cell.lblQuantity.text = String(arrQuantityList[indexPath.row].quantity)
cell.yourBtnName.tag = indexPath.row
step 5:
On your button action
arrQuantityList[sender.tag].quantity = arrQuantityList[sender.tag].quantity + 1
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.none)
It may helps to you.hank you.

Increase/Decrease a value and display results in a Label inside a TableViewCell Swift Xcode

I have a ViewController with a TableView and a TableViewCell containing multiple sections and rows.
I have 2 button "plus" and "minus" and a label "totalLabel" in each row.
How can I get the value displayed in the label for each specific row when the user presses the + or - button?
for now when I run the app and press the + or - buttons only the totalLabel of the section 0/row 0 is working while random values just appear and disappear in the other sections/rows
my tableViewCell code :
import UIKit
protocol CommandeCellDelegate: class {
}
class CommandeCell: UITableViewCell {
weak var delegate : CommandeCellDelegate!
#IBOutlet weak var drinksLabel: UILabel!
#IBOutlet weak var priceLabel: UILabel!
#IBOutlet weak var totalLabel: UILabel!
#IBOutlet weak var plusButton: UIButton!
#IBOutlet weak var minusButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
here is my code for cellForRowAt :
class MenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CommandeCellDelegate {
var count : Int = 0
var countValue : String!
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommandeCell", for: indexPath) as! CommandeCell
cell.plusButton.tag = indexPath.section
cell.plusButton.tag = indexPath.row
cell.plusButton.addTarget(self, action: #selector(self.increaseValue), for: .touchUpInside)
cell.minusButton.tag = indexPath.section
cell.minusButton.tag = indexPath.row
cell.minusButton.addTarget(self, action: #selector(self.decreaseValue), for: .touchUpInside)
if indexPath.section == 0 {
let softInfo = softs[indexPath.row]
cell.drinksLabel?.text = softInfo.drinkName
cell.totalLabel?.text = // how to display countValue here?
let HappyHourStatus = partner!.barHHStatus
if case "0" = HappyHourStatus {
cell.priceLabel?.text = softInfo.drinkHHPrice
} else
if case "1" = HappyHourStatus {
cell.priceLabel?.text = softInfo.drinkPrice
}
}
else if indexPath.section == 1 {
let cocktailInfo = cocktails[indexPath.row]
cell.drinksLabel?.text = cocktailInfo.drinkName
cell.totalLabel?.text = // how to display countValue here?
let HappyHourStatus = partner!.barHHStatus
if case "0" = HappyHourStatus {
cell.priceLabel?.text = cocktailInfo.drinkHHPrice
} else
if case "1" = HappyHourStatus {
cell.priceLabel?.text = cocktailInfo.drinkPrice
}
}
return cell
}
and my funcs to increase or decrease the value :
func increaseValue(_ sender: UIButton) -> Int {
count = 1 + count
print(count)
countValue = "\(count)"
let rowToReload = IndexPath(row: sender.tag, section: sender.tag)
let rowsToReload: [Any] = [rowToReload]
tableView.reloadRows(at: rowsToReload as! [IndexPath], with: .automatic)
return count
}
func decreaseValue(_ sender: UIButton) -> Int {
if count == 0 {
print("Count zero")
} else {
count = count - 1
}
countValue = "\(count)"
let rowToReload = IndexPath(row: sender.tag, section: sender.tag)
let rowsToReload: [Any] = [rowToReload]
tableView.reloadRows(at: rowsToReload as! [IndexPath], with: .automatic)
return count
}
I have tried countless solutions but so far none is working - thank you for your help!
So your problem is this code
cell.plusButton.tag = indexPath.section
cell.plusButton.tag = indexPath.row
A tag can only store one value. So you are overriding the section with the row. So it is going to cause all sorts of weirdness. The better solution is to determine what cell you are targeting based on the button itself. Since you know what button was clicked you can convert the location of this button to a point on the table view. And then that point to a a particular index path.
So using your example code you can do something like below:
var softsCount: [Int] = []
var cocktailsCount: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
softsCount = Array(repeating: 0, count: softs.count) // Fill an array with 0
cocktailsCount = Array(repeating: 0, count: cocktails.count) // Fill an array with 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
if indexPath.section == 0 {
...
cell.totalLabel?.text = "\(softsCount[indexPath.row])"
...
} else if indexPath.section == 1 {
...
cell.totalLabel?.text = "\(cocktailsCount[indexPath.row])"
...
}
...
}
func increaseValue(_ sender: UIButton) {
let pointInTable = sender.convert(sender.bounds.origin, to: tableView)
if let indexPath = self.tableView.indexPathForRow(at: pointInTable), let cell = tableView.cellForRow(at: indexPath) {
if indexPath.section == 0 {
softsCount[indexPath.row] += 1
cell.totalLabel?.text = "\(softsCount[indexPath.row])"
} else if indexPath.section == 1 {
cocktailsCount[indexPath.row] += 1
cell.totalLabel?.text = "\(cocktailsCount[indexPath.row])"
}
}
}
No sure why you are returning count. I am sure this is just a partial implementation. But the button should take care of the entire action including updating the label with the new count. You don't normally return values from button presses.
So updated the example to update the label with the current count. Since I am unable to see what your drinks object I made an assumption that the drinks class has a count parameter that starts at 0. This way each individual drink has a count assigned to it.

Resources