skip to Main Content

I have a tableview with a UISwitch in each of the cells. What I am trying to do is that whenever the UISwitch is Toggled On, it adds that cell into an array and when the switch is Toggled Off it removes it. Right now it only adds and doesn’t remove.

Once this is complete I need the CollectionView that is also within this ViewController to update and visually show the newStringArray Cells based on the number in that array and that also is able to appear and disappear based on the cells that have their UISwitch toggled on.

import UIKit
class NewMoveViewController: UIViewController {
    private var stringSource = ["String 1,", "String 2", "String 3"]
    var newStringArray = Array<String>()
    private let tableView: UITableView = {
       let tableView = UITableView()
        tableView.rowHeight = 100
        return tableView
    }()
    private var collectionView: UICollectionView?
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(tableView) 
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.itemSize = CGSize(width: 50, height: 50)
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
        collectionView?.register(NewMoveCollectionViewCell.self, forCellWithReuseIdentifier: NewMoveCollectionViewCell.identifier)
        collectionView?.showsHorizontalScrollIndicator = false 
        title = "Add to Group"
        tableView.register(NewMoveTableViewCell.self, forCellReuseIdentifier: NewMoveTableViewCell.identifier)
        tableView.delegate = self
        tableView.dataSource = self
        collectionView?.backgroundColor = .systemBlue
        collectionView?.dataSource = self
        collectionView?.delegate = self
        guard let myCollection = collectionView else {
            return
        }
        view.addSubview(myCollection)
        // Do any additional setup after loading the view.
    }
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionView?.frame = CGRect(x: 0, y: 100, width: view.frame.size.width, height: 50)
        tableView.frame = CGRect(x: 0, y: 200, width: view.frame.size.width, height: view.frame.size.height)
    }    
}

extension NewMoveViewController : UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: NewMoveTableViewCell.identifier, for: indexPath) as! NewMoveTableViewCell
        let switchView = UISwitch(frame: .zero)
        switchView.setOn(false, animated: true)
        switchView.tag = indexPath.row
        switchView.addTarget(self, action: #selector(self.switchDidChange(_:)), for: .valueChanged)
        cell.accessoryView = switchView       
        cell.configure(with: "", label: "test")        
        return cell
    }
    @objc func switchDidChange(_ sender: UISwitch) {        
        newStringArray.append(stringSource[sender.tag])
      //  newStringArray.remove(stringSource.remove(at: [s]))
       print(newStringArray)
    }    
    func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
        return false
    }    
}

extension NewMoveViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return newStringArray.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NewMoveCollectionViewCell.identifier, for: indexPath) as! NewMoveCollectionViewCell
        return cell
    }
}

2

Answers


  1. In order to get changes you want you have to set property which is gonna indicate whether switch is on or off

    Something like: var switchIsActive = false

    and simply change it in function and if it is turned on you perform one action when it is off you perform another one. Also after function you have to reload your tableView tableView.reloadData()

    You can remove elements in your array by their tag by calling Array.remove(at: Int). It can be done by the cells [indexPath.row]

    Login or Signup to reply.
  2. the hardest part is to remove an object from an array, my approach on these situations is to transform my array in a NSMutableArray because it have a function to remove an specific object, then make a delegate in the cell that informs the viewController to remove the object from the list and reload the tableView.

    the delegate wil be something like this:

    protocol RemoveObjectFromCell {
    func removeObjectIncell(object: MyObject)
    }
    
    class myCell: UITableViewCell {
    //your outlets and variables
    var object: MyObject? 
    var delegate: removeObjectIncell?
    
    
    func setupCell(object: myObject) {
    //configure your cell with the specific object
    }
    
    }
    

    make sure of calling the delegate on the switch action inside you cell class like this:

    @IBAction func switchPressed(sender: UISwitch) {
        if !sender.isOn {
            self.delegate?.removeObjectIncell(object: self.object)
        }
    

    in the view controller implement your protocol and use the required function like this:

    class myViewController: UIViewController, RemoveObjectFromCell {
    
    //everything that goes in your class
    
    
        func removeObjectIncell(object: MyObject) {
        self.myArray.remove(object)
            DispatchQueue.main.async {
                self.myTableView.reloadData()
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search