swift 3.0 multiple selection with Select All option - ios

i have added data in table view and i have manually added "select all" option in to list at first position now when user select first option which is select all then all item in to list should be selected and deselected when choose same. i have tried code below but its not working so can any one help me to solve this
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = ObjTableview.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SelectUserCell
for i in 0 ..< self.getStudentName.count {
cell.btnCheckbox.setImage(UIImage(named: "selectedItem"), for: .normal)
print (i) //i will increment up one with each iteration of the for loop
}
}
var unchecked = true
#IBAction func btnCheckBoxClick(_ sender: Any) {
if unchecked == true {
//(sender as AnyObject).setImage(UIImage(named: "selectedItem"), for: .normal)
cell?.btnCheckbox.setImage(UIImage(named: "selectedItem"), for: .normal)
//unchecked = false
let cello = ObjTableview.cellForRow(at: indexPath!)
print(cello!)
ObjTableview.reloadData()
}else
{
//(sender as AnyObject).setImage(UIImage(named: "unSelectedItem"), for: .normal)
cell?.btnCheckbox.setImage(UIImage(named: "unSelectedItem"), for: .normal)
// unchecked = true
}
}

Jayprakash, You are almost there. You need to modify some lines -
Here is your modified code snippet
var unchecked:Bool = true
#IBAction func btnCheckBoxClick(_ sender: Any) {
if(unchecked){
unchecked = false
}
else{
unchecked = true
}
ObjTableview.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if(indexPath.row == 0){
btnCheckBoxClick(sender: UIButton())
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell : SelectUserCell!
cell = tableView .dequeueReusableCell(withIdentifier: "SelectUserCell", for: indexPath) as! SelectUserCell
cell.selectionStyle = UITableViewCellSelectionStyle.none
if(unchecked){
cell.btnCheckbox.setImage(UIImage(named: "unSelectedItem"), for: .normal)
}
else{
cell.btnCheckbox.setImage(UIImage(named: "selectedItem"), for: .normal)
}
// Do your stuff here
return cell
}
Hop it will simplify your code structure.

Related

Check box check and unchecked not persisting in my table view

My task I am trying to show tableView with check box button inside the popup viewcontroller.
Whenever user click the button it is changing check and uncheck but I need to do when I click done button I have to keep user checked and if click cancel it should uncheck(which is user checked before click cancel). I need to understand and fix this task.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:MyCustomCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as! MyCustomCell
cell.myCellLabel.text = self.animals[indexPath.row]
if selectedRows.contains(indexPath)
{
cell.checkBox.setImage(UIImage(named:"check.png"), for: .normal)
}else{
cell.checkBox.setImage(UIImage(named:"uncheck.png"), for: .normal)
}
cell.checkBox.tag = indexPath.row
cell.checkBox.addTarget(self, action: #selector(checkBoxSelection(_:)), for: .touchUpInside)
return cell
}
// method to run when table view cell is tapped
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) as? MyCustomCell else {
return
}
if self.selectedRows.contains(indexPath) {
self.selectedRows.remove(at: self.selectedRows.index(of: indexPath)!)
cell.checkBox.setImage(UIImage(named:"uncheck.png"), for: .normal)
} else {
self.selectedRows.append(indexPath)
cell.checkBox.setImage(UIImage(named:"check.png"), for: .normal)
let indexPath = tableView.indexPathForSelectedRow //optional, to get from any UIButton for example
let currentCell = tableView.cellForRow(at: indexPath!) as! MyCustomCell
}
}
#IBAction func cancelPopup(_ sender: Any) {
self.removeAnimate()
}
#IBAction func donePopUp(_ sender: AnyObject) {
self.removeAnimate()
}
You may consider using basic taleview cell with setting acessoryType . Putting checkbox and labels all at the left seems giving poor UX
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DefectCell", for: indexPath)
let category = defectSet [indexPath.section]
let item = category.items[indexPath.row]
cell.textLabel?.text = item.name
cell.selectionStyle = .none
let isFound = User.shared.selectedDefect.filter{ $0.id == item.id }.count > 0
if (isFound)
{
cell.accessoryType = .checkmark
}
else
{
cell.accessoryType = .none
}
return cell
}

Prevent button in reused cells to appear again

#objc func addinterestserver(_ sender: UIButton) {
sender.backgroundColor = UIColor.white
sender.setTitleColor(UIColor.black, for: .normal)
sender.setTitle(NSLocalizedString("Added", comment: ""), for: .normal)
sender.isEnabled = false
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SearchInterestsCustom
let release = arrayOfRels[(indexPath as NSIndexPath).row]
cell.user.text = release.title
cell.match.text = release.count + NSLocalizedString(" people added", comment: "")
cell.addbutton.tag = release.eventID
cell.addbutton.addTarget(self, action: #selector(SearchInterests.addinterestserver), for: .touchUpInside)
cell.addbutton.layer.cornerRadius = 20
return cell
}
After user tapped the button, It affects also other cell's button, clearly I see same modified buttons several times upon scroll.
How to avoid this?
You can avoid this by
var allSelected = [Int]()
//
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SearchInterestsCustom
if allSelected.contains(release.eventID) {
cell.addbutton.backgroundColor = UIColor.white
cell.addbutton.setTitleColor(UIColor.black, for: .normal)
cell.addbutton.setTitle(NSLocalizedString("Added", comment: ""), for: .normal)
cell.addbutton.isEnabled = false
}
else {
// set default values
}
}
//
#objc func addinterestserver(_ sender: UIButton) {
sender.backgroundColor = UIColor.white
sender.setTitleColor(UIColor.black, for: .normal)
sender.setTitle(NSLocalizedString("Added", comment: ""), for: .normal)
sender.isEnabled = false
allSelected.append(sender.tag) // store it here
}

Swift UitableViewcell with button

I have a strange behavior in the UITABLEVIEW.
I have a TableView with Button, what I wanted to do is when I clicked to a button in the tableView, I want the color border to change to red.
The problem is that the color is changing not only for the clicked button, but also for others row in the tableview:
Here is my implementation
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! chooseProductTVC
cell.Btn_AddProduct.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
return cell
}
#objc func btnAction(_ sender: MyButton) {
sender.BorderColor = UIColor.red
let point = sender.convert(CGPoint.zero, to: tbl_View_ChooseProduct as UIView)
let indexPath: IndexPath! = self.tbl_View_ChooseProduct.indexPathForRow(at: point)
let object = self.fetchedResultsController.object(at: indexPath)
print (object.produit_name)
print("row is = \(indexPath.row) && section is = \(indexPath.section)")
}
As you can see in the picture below I have only clicked on the first button (Abricot) ==> other button has also automatically changed the border (Avocat) and many others.
This is because of cell dequeuing try to re set when you load the table , suppose here default is blue
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
cell.Btn_AddProduct.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
if selected
cell.Btn_AddProduct.BorderColor = UIColor.red
else
cell.Btn_AddProduct.BorderColor = UIColor.blue
return cell
}
Since we reuse the cell for displaying, we have to modify the color every time after dequeing.
Add new property selected to product model.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! chooseProductTVC
cell.Btn_AddProduct.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
let object = self.resultArray(at: indexPath.row)
if object.selected
cell.Btn_AddProduct.BorderColor = .red
else
cell.Btn_AddProduct.BorderColor = .blue
return cell
}
#objc func btnAction(_ sender: MyButton) {
sender.BorderColor = UIColor.red
let point = sender.convert(CGPoint.zero, to: tbl_View_ChooseProduct as UIView)
let indexPath: IndexPath! = self.tbl_View_ChooseProduct.indexPathForRow(at: point)
let object = self.fetchedResultsController.object(at: indexPath)
object.selected = true
print (object.produit_name)
print("row is = \(indexPath.row) && section is = \(indexPath.section)")
}
Tip: You could use tableChooseProduct(iOS) instead of tbl_View_ChooseProduct.(android). This link may helpful.
You have to store default Colors in Dictionary.
var orderColor = [Int : UIColor]()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...29 // TotaL number of rows
{
orderColor[i] = UIColor.blue // DEFAULT color of the Button
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 30
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! chooseProductTVC
cell.Btn_AddProduct.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
cell.Btn_AddProduct.BorderColor = orderColor[indexPath.row]
cell.selectionStyle = .none
return cell
}
#objc func btnAction(_ sender: MyButton) {
let point = sender.convert(CGPoint.zero, to: tbl_View_ChooseProduct as UIView)
let indexPath: IndexPath! = self.tbl_View_ChooseProduct.indexPathForRow(at: point)
orderColor[indexPath.row] = UIColor.red
tbl_View_ChooseProduct.reloadData()
}

Table view check box not accepting action for index 0

I have a table view, in which I have the items with check boxes. Users can select any items (multiselection also) and they can press the Proceed button to pay.
I was using a button as a check box. So if the user presses the button, or they select a table row, both cases are handled the function.
So now, my proceed buton starts as disabled. Whenever the user presses any items using the didSelectRowAt method or check box button action, only then the Proceed button will be enabled.
But now, whenever I press the first item or the first check box button, my proceed button is not getting enabled. If I press the second item or the second check box, it works. I don't know why.
Here is my code of didSelectRowAt and my check box button action code:
#Updated:
var selectedIndexPathArray = Array<NSIndexPath>()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "itemcell", for: indexPath) as! itemTableViewCell
cell.checkboxBtn.isUserInteractionEnabled = false
if selectedIndexPathArray.contains(indexPath as NSIndexPath) {
cell.checkboxBtn.setImage(UIImage(named: "enabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = true
} else {
cell.checkboxBtn.setImage(UIImage(named: "disabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = false
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedIndexPathArray.contains(indexPath as NSIndexPath) {
let index = selectedIndexPathArray.index(of: indexPath as NSIndexPath)
selectedIndexPathArray.remove(at: index!)
} else {
selectedIndexPathArray.append(indexPath as NSIndexPath)
}
tableView.reloadData()
}
Thanks in advance!
Yes because first time if you click on button then proceedbutton will be called and at that time selectedIndexPathArray will have no any value means nil.
So first time your else part will be executed.
.
.
.
else {
selectedIndexPathArray.append(indexPath! as NSIndexPath)
cell?.checkboxBtn.setImage(UIImage(named: "disabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = false
}
And when you press agin then your if condition will be true so it will be enable
Try this on your if-else condition on your proceed() function.
if selectedIndexPathArray.contains(indexPath! as NSIndexPath) {
electedIndexPathArray.remove(at: index!)
cell?.checkboxBtn.setImage(UIImage(named: "disabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = false
}
else {
selectedIndexPathArray.append(at: index!)
cell?.checkboxBtn.setImage(UIImage(named: "enabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = true
}
Remove selector for button in cell and default set userInteraction for button is false.No need to set it everytime. Perform everything on didSelectRow.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: itemscell, for: indexPath) as! itemsTableViewCell
cell?.checkboxBtn.isUserInteractionEnabled = false
if selectedIndexArray.contains(indexPath.row) {
cell.checkboxBtn.setImage(UIImage(named: "enabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = true
} else {
cell.checkboxBtn.setImage(UIImage(named: "disabled"), for: .normal)
proceedbutton.isUserInteractionEnabled = false
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedIndexArray.contains(indexPath.row) {
let index = selectedIndexPathArray.index(of: indexPath.row)
selectedIndexArray.remove(at: index!)
} else {
selectedIndexArray.append(indexPath.row)
}
tableView.reloadData()
}

How to Change the image of UIButton when selected which is on tableVIewCell. in Swift 3

I am implementing a like dislike button on the tableview cell but unable to change the image of the button. can anybody help me out using swift 3
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var tableView: UITableView!
var array: [String] = ["A","B","C","D","E","F"]
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: cell_TableTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell_TableTableViewCell") as UITableViewCell! as! cell_TableTableViewCell!
cell.textLabel?.text = array[indexPath.row]
cell.button_Outlet.tag = indexPath.row
cell.button_Outlet.addTarget(self, action: "LikePressed", for: .touchUpInside)
return cell
}
}
func LikePressed(sender : UIButton){
sender.isSelected = !sender.isSelected
}
While designing your custom cell, you can add image for that button for different states
Default
Selected
When you add selector for that button, in that selector you just need to change button's selection state
func buttonTapped(sender : UIButton){
sender.isSelected = !sender.isSelected
}
It's very simple, for example your button is from storyboard. Add make that it custom button.
1) And add tag value in cellForRowAt indexPath:.
2) And set two images for that butoon.
3) Finally fix selected sate.
See my code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: cell_TableTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell_TableTableViewCell") as UITableViewCell! as! cell_TableTableViewCell!
cell.textLabel?.text = array[indexPath.row]
//Step 1
cell.button_Outlet.tag = indexPath.row
cell.button_Outlet.addTarget(self, action: "LikePressed", for: .touchUpInside)
//Step 2
cell.button_Outlet.setImage(UIImage(named: "LikeImage"), for: .selected)
cell.button_Outlet.setImage(UIImage(named: "DisLikeImage"), for: .selected)
return cell
}
//Step 3
func btnPressed(sender:UIButton) {
if sender.isSelected == false {
sender.isSelected = true
} else {
sender.isSelected = false
}
}
IBOutlet the UIButton into your cell class(Eg. TableViewCell).
Write a method in ViewController class to detect buttonTap.
Eg:
func dislikeTapped(_ sender: UIButton) {
// set required image to sender
}
In TableView-CellForRow method add target to the button in cell.
Eg:
cell.dislikeButton.addTarget(self, action: #selector(self.dislikeTapped(_:), for: .touchUpInside)
You need to create an array too to maintain the state of button as when you scroll cell that are not visible on screen are removed from memory, so they are dequeued again from one that are visible, if you not maintain the state it will use attributes of cell u dequeued from.
var arrSelectedButtonswitTag = [Int]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: cell_TableTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell_TableTableViewCell") as UITableViewCell! as! cell_TableTableViewCell!
cell.textLabel?.text = array[indexPath.row]
//Step 1
cell.button_Outlet.tag = indexPath.row
cell.button_Outlet.addTarget(self, action: "LikePressed", for: .touchUpInside)
//Step 2
cell.button_Outlet.setImage(UIImage(named: "LikeImage"), for: .selected)
cell.button_Outlet.setImage(UIImage(named: "DisLikeImage"), for: .normal)
if arrSelectedButtonswitTag.contain(sender.tag)
sender.isSelected = false
arrSelectedButtonswitTag.remove(sender.tag)
} else {
sender.isSelected = true
arrSelectedButtonswitTag.appen(sender.tag)
}
return cell
}
//Step 3
func btnPressed(sender:UIButton) {
if arrSelectedButtonswitTag.contain(sender.tag)
sender.isSelected = false
arrSelectedButtonswitTag.remove(sender.tag)
} else {
sender.isSelected = true
arrSelectedButtonswitTag.append(sender.tag)
}
}

Resources