1

Hello I am trying to complete my task since 2 days but still no success searched everywhere , I want to select multiple rows from tableview cells (which contains 2 labels and one image) then I want to transfer into another vc and show in tableview , I am able to select multiple rows and get this type index from selected rows but now I don't know how to get data and transfer into another vc and show in table view please help I am getting selected rows index like this [[0, 1], [0, 2], [0, 3]

VC Code

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {


    @IBOutlet weak var tableview: UITableView!


    var labone = ["1","2","3","4","5","6"]
    var labtwo = ["a","b","c","d","e","f"]
    var img =  ["bag","bag","bag","bag","bag","bag"]


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func button(_ sender: Any) {

        let selectedindexPath = tableview.indexPathsForSelectedRows
        if(selectedindexPath != nil){
            let toy  = labone[0]
            print(toy)
            print(selectedindexPath) }

        else{
            print("null")
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return labone.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

         let name = cell.viewWithTag(1) as! UILabel
        let name_two = cell.viewWithTag(2) as! UILabel
        let imgg = cell.viewWithTag(3) as! UIImageView

        name.text = labone[indexPath.row]
        name_two.text = labtwo[indexPath.row]
        imgg.image = UIImage(named: img[indexPath.row])


        return cell

    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
        cell.contentView.backgroundColor = UIColor.yellow

    }


    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        // let selectedCell = tableview.cellForRow(at: indexPath)
        if let label = cell?.contentView.viewWithTag(4) as? UIImageView {
            label.image = UIImage(named: "check_disable")
        }

    }

}
  • Learn how to pass data from one view controller to another. [https://stackoverflow.com/a/9736559/7698092]. – Awais Fayyaz Apr 14 '18 at 11:19
  • You need to create a model (struct or class) containing these properties, labone, labtwo, img. Have an array of this model, from which you shall populate your tableview. Each time a row is selected, you make changes in the corresponding model in the array. When you wish to send this data over to the next VC, you can send the entire array over and access it in the next VC – Rakshith Nandish Apr 14 '18 at 11:20
  • And what data are you trying to pass ? – Awais Fayyaz Apr 14 '18 at 11:20
  • Rakshith Nandish if I select multiple rows so get all records in one array how I can show in another vc tableview ? – Shahzad ali Apr 14 '18 at 11:23
  • Awais I know how to transfer data between two controllers , I say how can transfer selected rows records to another tableview – Shahzad ali Apr 14 '18 at 11:23

2 Answers2

1

You should use some structure like below and then update the state of item selected or deselected then when you want to go to next viewController you can filter your dataSource with the items selected like below,

 class CellModel {

    var labelOne: String
    var labelTwo: String
    var imageName: String
    var isSelected = false

    init(_ labelOne: String, labelTwo: String, imageName: String) {
        self.labelOne = labelOne
        self.labelTwo = labelTwo
        self.imageName = imageName
    }
}

Update your viewController,

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

   let dataSource = [CellModel("1", labelTwo: "a", imageName: "bag"),
                     CellModel("2", labelTwo: "b", imageName: "bag"),
                     CellModel("3", labelTwo: "c", imageName: "bag"),
                     CellModel("4", labelTwo: "d", imageName: "bag"),
                     CellModel("5", labelTwo: "e", imageName: "bag"),
                     CellModel("6", labelTwo: "f", imageName: "bag")]
}

then you can update your cellForRowAt like below,

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

       let name = cell.viewWithTag(1) as! UILabel
       let name_two = cell.viewWithTag(2) as! UILabel
       let imgg = cell.viewWithTag(3) as! UIImageView

       let model = self.dataSource[indexPath.row]
       name.text = model.labelOne
       name_two.text = model.labelTwo
       imgg.image = UIImage(named: model.imageName)

       return cell
    }

update the numberOfRowInSection with this

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {    
     return self.dataSource.count
 }

and you can update the state of model when cell is selected/deseleced like this,

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
        cell.contentView.backgroundColor = UIColor.yellow
        self.dataSource[indexPath.row].isSelected = true
    }


    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        // let selectedCell = tableview.cellForRow(at: indexPath)
        if let label = cell?.contentView.viewWithTag(4) as? UIImageView {
            label.image = UIImage(named: "check_disable")
            self.dataSource[indexPath.row].isSelected = false
      }
 }

and finally in button action you can filter the selected models and pass to next viewController

@IBAction func button(_ sender: Any) {

     let selectedItems = self.dataSource.filter({ $0.isSelected == true })
     // Pass to next ViewController the selectedItmes
}
Kamran
  • 14,987
  • 4
  • 33
  • 51
  • Thank you bro I have implemented this but facing these issues , when select row colour is not changing and check disable enable don't work , and after selecting rows I am getting this data [, ] [, ] – Shahzad ali Apr 14 '18 at 12:10
  • 1
    The bit about using `tableView.dequeueReusableCell()` in `didSelectRowAt`/`didDeselectRowAt` is wrong. That call specifically recycles/creates a cell that is not currently on screen. You should be using `tableview.cellForRow(at: indexPath)` in order to make changes to a cell that's currently on-screen. – Duncan C Apr 14 '18 at 19:59
  • @DuncanC I focused on providing the solution to filter out the proper data but your observation is right. – Kamran Apr 14 '18 at 20:04
0

As @Rakshith suggest in their comment, move your data (labone, labtwo, img arrays) out of the view controller and into a model object. Pass that model object to your second view controller.

Also create an array selectedIndexPaths in your second view controller. When you tap the button in your ViewController, get the array of selected index paths and pass it to your second view controller.

In your second view controller's viewWillAppear, use the selectedIndexPaths variable to copy the items selected items into an array itemsToDisplay and use that in your table view data source methods to populate the second view controller's table view.

Duncan C
  • 128,072
  • 22
  • 173
  • 272