Ios show/hide views inside a tableview cell - ios

I have a tableview with a custom cell. Below image shows the view hierarchy of my tableview cell.
When adding rows to the tableview I'm hiding the 'check Image' imageview using below code.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "accountCell", for: indexPath) as! AccountsTableViewCell
cell.checkImage.isHidden = true
return cell
}
and when a row is clicked I'm showing the imageview again. Below is the code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "accountCell", for: indexPath) as! AccountsTableViewCell
cell.checkImage.isHidden = false
}
But the problem is when I click a row nothing happens. system execute the cell.checkImage.isHidden = false code line, but the imageview doesn't appear. It is still hidden. Could someone tell me what I'm doing wrong here?

You can't track cell checked status in your cell itself; the cell object is just a view onto your data and cells will be reused when the table view scrolls.
I suggest using a Set<IndexPath>. In your cellForRowAt you can check the contents of the set in order to determine whether the checkmark should be hidden:
var checked = Set<IndexPath>()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "accountCell", for: indexPath) as! AccountsTableViewCell
cell.checkImage.isHidden = self.checked.contains(indexPath)
return cell
}
in your didSelectRowAt you simply toggle the set membership and reload the row
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if self.checked.contains(indexPath) {
self.checked.remove(indexPath)
} else {
self.checked.insert(indexPath)
}
tableView.reloadRows(at:[indexPath], with:.fade)
}

You have to manage your array (datasource)! when you click your row, update your array for that index and reload your table view.
Example :
Your array should have some flag like isChecked toggle it's value from true to false or vice-versa.
In your cellForRowAtIndexPath check this flag and show or hide your image according to that flag!

first be sure your
tableview.delegate = self
second thing in did select row at index use that code
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! AccountsTableViewCell
cell.checkImage.isHidden = false
}

Related

tableview row is automatically deselected when I scroll down the tableview

when i scroll down the tableview and the selected row is out of view the selected row is deselected and the app crashes if I select another cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! DataCell
cell.titleLabel.textColor = UIColor.red
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! DataCell
cell.titleLable.textColor = UIColor.white
}
when a selected row highlighted in red is scrolled out of view it turns white.
Its because cells are getting recycle when you scrolling your tableview.Make sure all your cells properties assign in cellForRowAtIndexPath method . You can also print indexpath.row while scrolling tableview to find out what actually happening in background.

UITableView : Strange checkmark accessory type behavior

A gif to introduce my problem :
In my UITableView I set a checkmark accessory type but a white background appears instead of displaying the checkmark of the cell. The checkmark is here, but why do I have this white background ?
The tint color of my cell is set to white, changing it just change the color of the checkmark and the background is still here.
My code :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? CheckTableViewCell {
if cell.titleLabel.text != "" {
cell.accessoryType = .checkmark
}
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.cellForRow(at: indexPath)?.accessoryType = .none
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? CheckTableViewCell {
cell.setUp(withTitle: dataSource[indexPath.row].title)
return cell
}
return CheckTableViewCell()
}
func setUp(withTitle title : String){
self.titleLabel.text = title
}
Any idea ?
I had to set both cell content's View and UITableView background color to pink in StoryBoard to make it works.

How do I have a single select and a multiselect in my tableview?

in my cellForRowAt Im inflating my xib and setting its content:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: TableViewCell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! TableViewCell
cell.label.text = data[indexPath.row]
let tap = UIGestureRecognizer(target: self, action: #selector(tableCellTap(_:cell:)))
cell.addGestureRecognizer(tap)
cell.selectionStyle = .none
cell.checkBox.isUserInteractionEnabled = false
cell.checkBox.boxType = .circle
cell.checkBox.markType = .radio
cell.checkBox.cornerRadius = 0
cell.checkBox.stateChangeAnimation = .expand(.fill)
if (indexPath.row == selectedIndex){
cell.checkBox.checkState = .checked
}else{
cell.checkBox.checkState = .unchecked
}
return cell
}
Then Im setting my deselect and select values
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
cell.checkBox.checkState = .checked
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
cell.checkBox.checkState = .unchecked
}
I need a sense of direction in how i can make it select and deselect the same row and update my xib file checkbox?
m13checkbox is being used
when i click on the cell for the first time it selects it but when i click on the same cell again it does not call it and does nothing until a loop a completed in the checkboxes
you don't need didDeselectRowAt, you can achieve the same functionality by checking if the radio button is checked in your didSelectRowAt.
If the radio button is checked, simply uncheck it and vice versa.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
if(cell.checkBox.isChecked){
cell.checkBox.checkState = .unchecked
}else{
cell.checkBox.checkState = .checked
}
}
Apple has already given very good sample code for that on its website,
you can check at:https://developer.apple.com/library/content/samplecode/TableMultiSelect/Introduction/Intro.html

how to add Checkmark TableView Multiple Swift 3.0

I want to make the user multiple choice (years) or choose (all) and the rest of the cells disappear (checkmark).
I want the user can not cancel each (checkmark).
This My Code :-
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .checkmark
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! yearsCell
cell.years?.text = Years[indexPath.row]
return cell }
The way I do this is by storing the selectedindexPath's in an array, then reload the tableView to change the cells that were selected, this way you avoid problems with cell re-use, this might look like this (un-tested).
var selectedIndexPathArray = Array<NSIndexPath>()
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)
selectedIndexPathArray.append(indexPath)
tableView.reloadData()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! yearsCell
cell.years?.text = Years[indexPath.row]
cell.accessoryType = .none
for sip in selectedIndexPathArray {
if indexPath == sip {
cell.accessoryType = .checkmark
}
}
return cell
}
Like So:
SWIFT 3
// To checkmark the cell
let cell = tableView.cellForRow(at:indexPath.row)
cell.accessoryType = .checkmark
// To make it unselectable
Use the tableView:willSelectRowAtIndexPath: method and check if the indexPath.row is the row for the cell you just selected, and return false.
The cell is reusable. For example, the cell used to display 1st row might be used to display 10th row when scroll down. Therefore, you need a array store the checkmark status for each row, some code like:
didSelect: array[indexpath.row] = !array[indexpath.row]
cellForRow: setCheckmark(array[indexpath.row])
MORE: google how and why a cell is reused in tableview

How to set data from ViewController to UITableView custom Cell

I have been trying to pass data from Viewcontroller to UITableView custom cell using custom delegate.There are answers for passing data from Custom cell to ViewController but none for the viceversa .Can anyone suggest me with some idea or sample code.
I am not sure if this is what you mean, but you can set the data in function tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
For example:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ViewController.cellIdentifier, for: indexPath) as! CustomCell
cell.data = data
return cell
}

Resources