-1

In my app I have a switch and I want it to be an indicator for saving images. For now I have just a button that saves all the images.

enter image description here

It just makes more sense with an example

What I've tried:

func saveTapped() {

let cell = collectionView?.cellForItem(at: indexPath) as! CustomCell

for image in images where cell.savingSwitch.isOn  {

...

But I can't access indexPath. How should I call this Save method in order to access a particular row in my collectionView? Or is there another way?

Max Kraev
  • 740
  • 12
  • 31

2 Answers2

1

First, you'll need a way to store the "save" settings alongside each image in your table, e.g. by keeping the image and the flag in a struct:

struct TableEntry {
   let image: UIImage
   var save = false
}

and use a var images: [TableEntry] in the data source of your tableview.

You can then use the tag property of each UISwitch to store the row it's in, e.g. in

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(...)
    cell.switch.tag = indexPath.row
    cell.switch.isOn = self.images[indexPath.row].save
    cell.imageView.image = self.images[indexPath.row].image
    return cell
}

and then use the tag in the method that's called when the switch value changes to know which image is being referred to:

@IBAction func switchChanged(_ sender: UISwitch) {
    self.images[sender.tag].save = sender.isOn
}

func saveTapped() {
    let imagesToSave = self.images.filter { $0.save }
}
Gereon
  • 17,258
  • 4
  • 42
  • 73
  • Each switch is constructed as reusable for every cell, so I have problems with tags) Or is it handles the tag enumeration? – Max Kraev Apr 15 '18 at 10:55
  • You need to set the tag after dequeueing the cell - updated my answer. Not sure what you mean by "tag enum" - it's simply an Int. – Gereon Apr 15 '18 at 11:00
  • Right, that was kind of obvious. Thanks. But I have another strange bug: when I scroll up and down, so cells got reused, switch state is now assigned to a different cell. I tried to store property in the CustomCell but still I got this – Max Kraev Apr 15 '18 at 11:07
  • You also need to set the switches `isOn` property after dequeueing. See the updated answer. Basically, due to cell reuse, you can never reliably store state in the cell itself. – Gereon Apr 15 '18 at 11:11
1

In your CustomCell, you can add a closure to be fired when switch state is changed like below,

class CustomCell: UITableViewCell {

   var onSwitchStateChange: ((Bool) -> Void)?

   @IBAction func switchTapped(_ sender: UISwitch) {
       self.onSwitchStateChange?(sender.isOn)
   }
}

then you can update your cellForRowAt like below,

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

   cell.onSwitchStateChange = { state in
     guard state else { return }

     let image = images[indexPath.row]
     // Upload Image
   }
}
Kamran
  • 14,987
  • 4
  • 33
  • 51