How to save the state of UITableViewCell accessory checkmark in Swift 3 - swift

I have a table view and I would like the user to select only one item from the table view, then I want to add a checkmark to the cell. At the same time, I also want the checkmark on other cells to disappear so the. user can only select one at a time. Then I want to save the data (preferably using UserDefaults). How do I do that?

Create a class variable of type IndexPath. In your cellForRowAt method set .checkmark accessory type only if index path matches the class variable and .none otherwise. In didSelectRowAt method update the indexPath of selected variable and just reload the tableview

you should Use in this way
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let sgp : UITableViewCell = tableView.cellForRow(at: indexPath)!
sgp.accessoryType = .checkmark
}

Related

How to pin Cell on select in Tableview?

I would like the selected cell to be pinned to the Tableview top and stay there while scrolling like section header when .plain style is used but for cell.
I don't know how to approach the problem. I know that the code should be placed at didSelectRowAt.
If your tableView cells are static, and you want the selected cell to be displayed at the top, You should try:
optional func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedRow = tableView.cellForRow(at: indexPath) as! yourTableViewCell // this wont apply if your cells are static
let firstVisibleIndexPath = tableView.indexPathsForVisibleRows.first
tableView.moveRow(at: indexPath, to: firstVisibleIndexPath)
}

Swift - Clicked button inside tableview cell does not call the did select row at function of that cell

I creating a tableview programatically and each tableview cell have buttons associated to them.
If I click the row I can work out the tag associated with the buttons on that row and then able to edit the title when applying some other functions.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
TmpActionConnectorTag = indexPath.row + 700 //Tag associated to button
}
When the button is clicked , I have this code which changes the other button on that row
let tag = TmpActionConnectorTag
let tmpButton = self.view.viewWithTag(tag) as? UIButton
The issue is if I directly click on the button in the tableview cell, the did select row does not get call and no tag value is given. To do it I have to click within the cell first and then the button to be able to know the tag associated with the row.
Is there a way to workout the index row when the button is clicked so I don't have to click the actual cell?
above is how the cell looks normally and below shows how the cell has to be selected to be able to get the index value.
Button action won't call the didSelectRowAt. You should go for delegate method. If not aware about delegate means refer this
The cell's button will not trigger func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) instead you need to add a target to your button which is typically done within cellForItemAt.
Add target to button within cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = MyTableViewCell()
cell.button.tag = indexPath.row
cell.button.addTarget(self, action: #selector(didTapCellButton(sender:)), for: .touchUpInside)
}
Handle button action
#objc func didTapCellButton(sender: UIButton) {
guard viewModels.indices.contains(sender.tag) else { return } // check element exist in tableview datasource
//Configure selected button or update model
}
Disabling the button's control worked for me.
Programmatically:
editButton.isEnabled = false
~OR~
IB:
Uncheck the Enabled box in the Control section.

Xcode static cells with dynamic backgroundColor

Is there a possibility to set a dynamic backgroundColor with static cells in a UITableView?
For example the user pressed a button in a UITableView and then all cells in the same view change to a specific color.
I already figured out how to set a backgroundColor when the view shows up:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor.black
}
Now I want to achieve the same when the view has already loaded. Any suggestions?
You can access the currently visible cells (the ones that have passed over the willDisplay milestone) via the visibleCells property. You can iterate over this array and do whatever you need:
for cell in tableView.visibleCells {
cell.backgroundColor = UIColor.black
}
Alternatively you can call reloadData() on the tableView, this will result in all cells being re-created and re-displayed.
You can use a delegate method called DidSelect this method works when a user tap on a cell in the tableView or inside an element, and returns the index path of selected Cell you can use that to edit background color or anything.
The code should be something like this optional func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath) inside this function you can get the cell using cellForRowAtIndexPath and pass it the selected path and cast it as the cell type you have and then edit it or do whatever.
The full code would look something like this
optional func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath){
let cell = tableView.cellForRow(at: indexPath)
//use the cell object and do what you want
}

create drop down in UITableView swift

I have gotten to the point where I have a selectable list of options, which are all loaded into the same .xib files. I am trying to make it so upon the click on a cell a different .xib file is populated below, and all of the other cells shift down. However, I am unsure of how to have 2 different xib's as TableViewCells in swift.
There's two ways I can think of to accomplish what you are trying to do:
Single xib file: You should use a single xib file that hides the lower section that contains the options until the cell is tapped. When tapped, a property on the UITableCell class could be set, e.g. isExpanded. When isExpanded is set, your cell could unhide the options (by changing constraints).
Multiple xibs: When tapped, you could insert a new item into your datasource. In your cellForRow, you could check for some identifier and load either the regular cell or the options cell using something like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == optionsRow {
let cell = tableView.dequeueReusableCell(withIdentifier: OptionsCellIdentifier, for: indexPath) as! OptionsCell
//Configure cell here
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: NormalCellIdentifier, for: indexPath) as! NormalCell
//Configure cell here
return cell
}
}

can't set custom cell class's variable

I created a table view and cell is custom style, I did hook up the cell with custom class and cell's id in dequeueReusableCell(withIdentifier: , for:)function.
I added an image view in the cell, and add it as IBOutlet into custom cell class. In custom cell class, I created get and set variable called tableImage to change the image in the image view.
But in
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
I still can't set tableImage. The error shows Value of type UITableViewCell has no member tableImage.
Have you add as! yourCustomTableViewCell after the dequeueReusableCell function?
yourTableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! yourCustomTableViewCell