0

Problem I want to allow users to hit 'swap' in a table cell and then find a different Realm object to populate the 2 text labels (for exercise name and number of reps) in the cell with the values from the new object.

Research There's quite a bit (admittedly old) on 'moving rows' (e.g. here How to swap two custom cells with one another in tableview?) and also here (UITableView swap cells) and then there's obviously a lot on reloading data in itself but I can't find anything on this use case.

What have I tried my code below works fine for retrieving a new object. i.e. there's some data in the cell, then when you hit the 'swapButton' it goes grabs another one ready to put in the tableView. I know how to reload data generally but not within one particular cell in situ (the cell that the particular swap button belongs to... each cell has a 'swap button').

I'm guessing I need to somehow find the indexRow of the 'swapButton' and then access the cell properties of that particular cell but not sure where to start (I've played around with quite a few different variants but I'm just guessing so it's not working!)

class WorkoutCell : UITableViewCell {

    @IBOutlet weak var exerciseName: UILabel!
    @IBOutlet weak var repsNumber: UILabel!
    @IBAction func swapButtonPressed(_ sender: Any) {
        swapExercise()
    }

    func swapExercise() {

        let realmExercisePool = realm.objects(ExerciseGeneratorObject.self)
        func generateExercise() -> WorkoutExercise {
            let index = Int(arc4random_uniform(UInt32(realmExercisePool.count)))
            return realmExercisePool[index].generateExercise()
        }

    }
//do something here like cell.workoutName 
//= swapExercise[indexRow].generateExercise().name??? 
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
nc14
  • 539
  • 1
  • 8
  • 26

2 Answers2

0

Hold your objects somewhere in a VC that shows UITableView. Then add the VC as the target to swap button. Implement swapping objects on button press and reload data of table view after. The whole idea is to move logic to view controller, not in separate cell.

There are 2 ways. 1. Adding VS as button action target.

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = ... // get cell and configure it
    cell.swapBtn.addTarget(self, action: #selector(swapTapped(_:)), for: .touchUpInside)
    return cell
}

func swapTapped(_ button: UIButton) {
    let buttonPosition = button.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!
    // find object at that index path
    // swap it with another
    self.tableView.reloadData()
}
  1. Make VC to be delegate of cell. More code. Here you create protocol in cell and add delegate variable. Then when you create cell you assign to VC as delegate for cell:

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = ... // get cell and configure it cell.delegate = self return cell }

    func swapTappedForCell(_ cell: SwapCell) { // the same logic for swapping }

kirander
  • 2,202
  • 20
  • 18
  • hey thanks for replying - so you mean move the function down into the VC? How do I 'add the VC as the target of the button?" and then implement the 'swapping of objects' that's what I'm struggling with (I've moved the function into the VC now) – nc14 May 14 '18 at 22:55
  • Here is how you add VC as a action target and find in which cell touch happen https://stackoverflow.com/questions/1802707/detecting-which-uibutton-was-pressed-in-a-uitableview – kirander May 14 '18 at 23:09
  • thanks - most of these solutions are from 2010-2012 though so quite outdated now, i'll try adapt them – nc14 May 15 '18 at 05:59
  • there is a solution on here that seems to be the right (Cocoanuts answer) but the code is from 2010 so isn't particularly helpful unfortunately – nc14 May 15 '18 at 06:32
  • the code remains the same for today. nothing changed. just translate it to swift – kirander May 15 '18 at 08:47
  • Unfortunately I'm still fairly new to programming so 'translating it to swift' is probably a bigger challenge for me! – nc14 May 15 '18 at 09:01
  • I get loads of errors when i try the code above. e.g. "use of unresolved identifier button", "button has no member convertPoint" etc, am I meant to put those code blocks in my tableview section and cell class section respectively? – nc14 May 15 '18 at 09:15
0

Solution from OP I adapted the code here How to access the content of a custom cell in swift using button tag?

Using delegates and protocols is the most sustainable way to achieve this I think.

I hope this helps others with the same problem!

nc14
  • 539
  • 1
  • 8
  • 26