CheckBox UITableView with Different Sections
Example using a UIButton
with checked / unchecked background images with an on/off state:
//
// TableWithCheckTableViewController.swift
// SWTemp2
//
// Created by Don Mag on 6/6/17.
// Copyright © 2017 DonMag. All rights reserved.
//
import UIKit
class MyCheckTableViewCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myCheckButton: UIButton!
var checkedImage = UIImage(named: "Checked")
var unCheckedImage = UIImage(named: "UnChecked")
var isOn: Bool = false {
didSet {
myCheckButton.setBackgroundImage(self.isOn ? checkedImage : unCheckedImage, for: .normal)
}
}
var checkTapAction : ((Bool)->Void)?
@IBAction func buttonTapped(_ sender: Any) {
self.isOn = !self.isOn
checkTapAction?(self.isOn)
}
}
// simple data object
class MyCheckObject: NSObject {
var theTitle = ""
var theCheckState = false
init(_ title: String) {
theTitle = title
}
}
class TableWithCheckTableViewController: UITableViewController {
// array of MyObjects
var myData = [MyCheckObject]()
override func viewDidLoad() {
super.viewDidLoad()
// just to make it a little easier to see the rows scroll
tableView.rowHeight = 60
// create 40 data objects for the table
for i in 1...40 {
let d = MyCheckObject("Data Item: \(i)")
myData.append(d)
}
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCheckTableViewCell", for: indexPath) as! MyCheckTableViewCell
// Configure the cell...
let d = myData[indexPath.row]
cell.myLabel.text = d.theTitle
cell.isOn = d.theCheckState
// set a "Callback Closure" in the cell
cell.checkTapAction = {
(isOn) in
// update our Data Array to the new state of the switch in the cell
self.myData[indexPath.row].theCheckState = isOn
}
return cell
}
}
Tableview multiple sections button action for radio btn and checkbox in swift
Use this library for radio buttons and update your code with this and try
var radioButtonController = SSRadioButtonsController()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CustomiseTableViewCell = tableView.dequeueReusableCell(withIdentifier: "Customise") as! CustomiseTableViewCell
cell.name.text?=table_data[indexPath.section].menu_name[indexPath.row]
print(table_data[indexPath.section].customize[indexPath.row])
radioButtonController.addButton(cell.radioBtn)
switch Int(table_data[indexPath.section].customize[indexPath.row]) {
case 1:
cell.radioBtn.isHidden = true
cell.checkBoxBtn.isHidden = false
break
case 2:
cell.radioBtn.isHidden = false
cell.checkBoxBtn.isHidden = true
break
default:
print("Invalid choose")
}
cell.radioBtn.addTarget(self, action: #selector(ViewController.radioBtnaction), for: .touchUpInside)
cell.checkBoxBtn.addTarget(self, action: #selector(ViewController.checkBoxBtnaction), for: .touchUpInside)
return cell
}
EDIT:
var radioControllerChoice : SSRadioButtonsController = SSRadioButtonsController()
var radioControllerDip : SSRadioButtonsController = SSRadioButtonsController()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:CustomiseTableViewCell = tableView.dequeueReusableCell(withIdentifier: "Customise") as! CustomiseTableViewCell
cell.name.text?=table_data[indexPath.section].menu_name[indexPath.row]
print(table_data[indexPath.section].customize[indexPath.row])
switch indexPath.section {
case 1:
radioControllerChoice.addButton(cell.radioBtn)
case 2:
radioControllerDip.addButton(cell.radioBtn)
default:
print("no case found")
}
switch Int(table_data[indexPath.section].customize[indexPath.row]) {
case 1:
cell.radioBtn.isHidden = true
cell.checkBoxBtn.isHidden = false
break
case 2:
cell.radioBtn.isHidden = false
cell.checkBoxBtn.isHidden = true
break
default:
print("Invalid choose")
}
cell.radioBtn.addTarget(self, action: #selector(ViewController.radioBtnaction), for: .touchUpInside)
cell.checkBoxBtn.addTarget(self, action: #selector(ViewController.checkBoxBtnaction), for: .touchUpInside)
return cell
}
How can I keep the tableview sections in a condition?
Button tags only let you pass an Int
which is not enough for someone who wants both rows and sections (like your case).
In your cell's class define a closure:
var action : (() -> Void)? = nil
Then create an action func for your checkBox
button (or whatever it is) in the cell's class:
@IBAction func btnAction(sender: M13Checkbox)
{
switch sender!.checkState {
case .checked:
if let act = self.action
{
act()
}
break
case .unchecked:
print("adres kaldırıldı bile...")
break
case .mixed:
//empty...
break
}
}
Then in cellForRow
func pass the closure:
cell.action = {
//here you have access to indexPath.section and indexPath.row
let adresso = self.userAdressDict[indexPath.row] // teslimde calismaz suanda..
print("\(adresso.userIlce!)" + " / " + "\(adresso.userMahalle!)" + " / " + "\(adresso.userSokak!)" + " / " + "\(adresso.userApartman!)" + " / No: " + "\(adresso.userNumara!)" + " / Kat: " + "\(adresso.userKat!)")
let adresAlim = ("\(adresso.userMahalle!)" + " / " + "\(adresso.userSokak!)" + " / " + "\(adresso.userApartman!)")
secilenAdresForAlim = adresAlim
let deadlineTime = DispatchTime.now() + .milliseconds(500)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
if self.keys[0] == 0 {
self.keys[0] = 1
}else{
self.keys[0] = 0
self.buttonLabel = "Değiştir"
self.headerTitleForSecZero = self.secilenAdresForAlim
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
This is way more appropriate than determining the cell by tag. Now when you're passing the closure you have access to both indexPath.row
and indexPath.section
within the closure.
UiTableViewCell single selected checkmark for each section in the tableview
First of all, implement UITableViewDelegate's
tableView(_:willSelectRowAt:)
method like so,
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let selectedIndexPathsInSection = tableView.indexPathsForSelectedRows?.filter({ $0.section == indexPath.section }), !selectedIndexPathsInSection.isEmpty {
selectedIndexPathsInSection.forEach({ tableView.deselectRow(at: $0, animated: false) })
}
return indexPath
}
Next, in both MakePaymentTableViewCell
and MakePaymentTableViewCell2
cells, override setSelected(_:animated:)
method, i.e.
class MakePaymentTableViewCell: UITableViewCell {
//rest of the code...
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.accessoryType = selected ? .checkmark : .none
self.checkBox.isChecked = selected
}
}
There is no need to implement didSelectRowAt
and didDeselectRowAt
methods.
Why my checkbox in custom cell shows different behaviour while selecting and scrolling in swift?
This is happening because you are reusing the TableViewCell
, To solve your problem you can try something like this, first create an array of Int that give you selected row and use that array inside cellForRowAtIndexPath
method.
var selectedItems = [Int]()
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:CustomOneCell = AddO nTableView.dequeueReusableCellWithIdentifier("addoncell") as! CustomOneCell
let item: AddOnItems = ADDONITEMS[indexPath.row]
cell.addOnName.text = item.name
cell.addOnPrice.text = "£\(item.price!)"
cell.checkBoxBtn.tag = indexPath.row
if (selectedItems.contains(indexPath.row)) {
cell.checkBoxBtn.setImage(UIImage(named:"checkbox untick.png"), forState: .Normal)
}
else {
cell.checkBoxBtn.setImage(UIImage(named: "checkboxredtick.png"), forState: .Normal)
}
cell.checkBoxBtn.addTarget(self, action:#selector(self.buttonClicked(_:)), forControlEvents: UIControlEvents.TouchUpInside)
return cell
}
func buttonClicked(sender: UIButton) {
if (self.selectedItems.contains(sender.tag)) {
let index = self.selectedItems.indexOf(sender.tag)
self.selectedItems.removeAtIndex(index)
}
else {
self.selectedItems.append(sender.tag)
}
self.tableView.reloadData()
}
Set button tag for different sections of UITableView
I added the following code which solved my issue
NSInteger rowNumber = 0;
for(NSInteger i = 0; i < indexPath.section ; i++)
{
rowNumber += [self tableView:self.tableViewContact numberOfRowsInSection:i];
}
rowNumber += indexPath.row;
[checkBox setTag:rowNumber]; //checkBox is UIButton in cellForRowAtIndexPath
Related Topics
How to Change Uinavigationbar Per View Controller
How to Handle Usernotifications Actions in iOS 10
Swift3 - How to Protect Secret Key
iOS Swift Flood Fill Algorithm
Swift3 Random Extension Method
Swiftui Animation and Subsequent Reverse Animation to Original State
Dyld: Symbol Not Found: _Tmpdcss12Anygenerator
Swift Link Image from Parse Array Using Segues to Secondviewcontroller
iOS Development App Startup Crash
Could Not Cast Value of Type 'Nsnull' (0X10Aa1B600) to 'Nsstring' (0X10B4Dab48)
iOS 10.3 - How to Change App Icon Programmatically
Save Video to a Custom Album Using Photos Framework in iOS
Swift: How to Change Detailview Depending on Sidebar Selection State with Swiftui 4