2016-10-18 1 views
2

Je tente de créer un écran de configuration afin qu'un utilisateur puisse définir le nombre d'entraînements qu'il souhaite effectuer. J'ai réussi à ajouter une vue de table à un contrôleur de vue vide, mais il y avait quelques limitations stylistiques - telles que l'expansion et l'effondrement de la table en fonction du nombre de cellules.Utilisation d'un moteur pas à pas dans une cellule de vue de table - mais les données renvoyées au VC ne se mettent pas à jour correctement

Donc je me suis dit que je voudrais mettre en place l'écran dans un tableviewcontroller. Maintenant, tout va bien, jusqu'à ce que je devienne mon Stepper en section 0, cell 1, pour augmenter et diminuer le nombre de lignes . Cela fonctionne dans la mesure où le tableau de données (workouts[]) met à jour le contrôleur de vue avec la dernière valeur (dans la méthode cellForRowAt:indexPath) qui à son tour met à jour le numberOfRowsInSection avec le (supposé) dernier workouts.count.

Cependant, il s'avère que workouts.count contient le nombre avant que le tableau a été mis à jour par le dernier pas. Maintenant, j'ai essayé un certain nombre de solution de contournement mais je ne peux toujours pas obtenir la méthode numberOfRowsInSection pour mettre à jour correctement - il me semble que la matrice Workouts n'est pas mise à jour dans le View Controller avec la dernière valeur, plutôt valeur de consigne précédente.

Ceci est mon contrôleur de vue:

class AViewController: UITableViewController { 

//MARK: Properties 
@IBOutlet weak var aTableView: UITableView! 

var sections: [String] = ["", "Set Up Circuits"] 
var workouts: [Exercise] = [] 

//MARK: Initialisation 
override func viewDidLoad() { 
    super.viewDidLoad() 
    workouts = [Exercise(name: "Circuit 1", timeMinutes: 2)] 
    self.tableView.delegate = self 
    self.tableView.dataSource = self 
} 

//MARK: Table Config 
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return self.sections[section] 
} 

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 
    switch section { 
    case 0: 
     return 0.1 
    default: 
     return 32.0 
    } 
} 

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
    switch indexPath.section { 
    case 0: 
     return 60 
    default: 
     return 44 
    } 
} 

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

    var numberOfRowsInSection: Int = 0 

    switch section { 
    case 0: 
     numberOfRowsInSection = 1 
    default: 
     numberOfRowsInSection = workouts.count 
     //numberOfRowsInSection = 1 
    } 
    print(numberOfRowsInSection, "number of rows in section", section) 
    return numberOfRowsInSection 
} 

//MARK: Table Protocols 
override func numberOfSections(in tableView: UITableView) -> Int { 
    return sections.count 
} 

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    switch indexPath.section { 

    //Setting layout for circuit number config 
    case 0: 
     let cell = aTableView.dequeueReusableCell(withIdentifier: "ACircuitTableViewCell") as! ACircuitTableViewCell 
     cell.tableView = self.aTableView 
     self.workouts = cell.workouts 
     print(workouts.count, " VC workouts array count") 
     return cell 

    //Setting layout for circuit cells 
    default: 
     let cell = aTableView.dequeueReusableCell(withIdentifier: "ATableViewCell") as! ATableViewCell 
     cell.aLabel.text = workouts[indexPath.row].getName() 
     cell.aDetail.text = "Tap here to configure" 
     return cell 

    } 
} 

Ceci est mon ACircuitTableViewCell:

class ACircuitTableViewCell: UITableViewCell { 

//MARK: Properties 
@IBOutlet weak var circuitNumber: UILabel! 
@IBOutlet weak var circuitLabel: UILabel! 
@IBOutlet weak var circStepper: UIStepper! 


var tableView: UITableView! 
// var updateCallback : ((_ updateList: Bool)-> Void)? 

//var exercises: [Exercise]? 
var anArray: [Exercise] = [] 
var workouts: [Exercise] = [Exercise(name: "Circuit 1", timeMinutes: 2)] 

var workoutsCount: Int = 1 
var indexPath: NSIndexPath = NSIndexPath(row: 0, section: 1) 
//MARK: Original Functions 
override func awakeFromNib() { 
    super.awakeFromNib() 
    // Initialization code 

    circuitNumber.text = String(workouts.count) 
} 

override func setSelected(_ selected: Bool, animated: Bool) { 
    super.setSelected(selected, animated: animated) 
} 

@IBAction func valueChanged(_ sender: AnyObject) { 
    print("Method .valueChanged activated") 

    //Update circuitNumber label 
    circuitNumber.text = String(Int(circStepper.value)) 

    //View pre-array-update status of variables 
    print(workouts.count, "anArray before appending") 
    print(circStepper.value, "stepper value before appending") 
    print(circuitNumber.text, "circuitNumber") 

    //Update workouts array 
    if workouts.count < Int(circStepper.value) { 
     workouts.append(Exercise(name: "Circuit \(Int(circStepper.value))", timeMinutes: 2)) 
     print(workouts.count, "after appending") 

     tableView.reloadData() 

     print(workouts.count, "new workout.count") 
    } 


    print(workouts.count, "workouts.count") 
    print("Method .valueChanged completed") 

} 

Ceci est la sortie de la console à partir lors du chargement d'applications, à trois coups sur le stepper + bouton .

1 number of rows in section 1 
1 number of rows in section 0 
1 number of rows in section 1 
1 number of rows in section 0 
1 number of rows in section 1 
1 number of rows in section 0 
1 VC workouts array count 
Method .valueChanged activated 
1 anArray before appending 
2.0 stepper value before appending 
Optional("2") circuitNumber 
2 after appending 
1 number of rows in section 1 
1 number of rows in section 0 
2 new workout.count 
2 workouts.count 
Method .valueChanged completed 
2 VC workouts array count 
Method .valueChanged activated 
2 anArray before appending 
3.0 stepper value before appending 
Optional("3") circuitNumber 
3 after appending 
2 number of rows in section 1 
1 number of rows in section 0 
3 new workout.count 
3 workouts.count 
Method .valueChanged completed 
3 VC workouts array count 
Method .valueChanged activated 
3 anArray before appending 
4.0 stepper value before appending 
Optional("4") circuitNumber 
4 after appending 
3 number of rows in section 1 
1 number of rows in section 0 
4 new workout.count 
4 workouts.count 
Method .valueChanged completed 
4 VC workouts array count 
Method .valueChanged activated 
4 anArray before appending 
5.0 stepper value before appending 
Optional("5") circuitNumber 
5 after appending 
4 number of rows in section 1 
1 number of rows in section 0 
5 new workout.count 
5 workouts.count 
Method .valueChanged completed 
5 VC workouts array count 
+0

Veuillez ne pas stocker la source de données dans vos cellules (ou dans d'autres vues). Il casse le modèle MVC. Ce que vous devez faire est de gérer le rappel stepper dans le contrôleur et de changer la source de données de viewController. – alexburtnik

+0

@alexburtnik merci! Une fois que j'ai compris comment gérer le rappel stepper dans le contrôleur, la table a fonctionné comme je le voulais. – Sonera

+0

De rien. Juste posté deux approches communes pour gérer les événements de vue dans viewController. Vous avez probablement utilisé l'un d'eux – alexburtnik

Répondre

0

Vous devez gérer le rappel pas-à-pas dans le contrôleur et y changer la source de données de viewController.

  1. La façon la plus commune pour gérer les événements cellulaires dans un contrôleur de vue est à l'aide des délégués, comme je l'ai décrit ici: https://stackoverflow.com/a/40111943/1689376

  2. Vous pouvez aussi ajouter une action avec self droite cible dans cellForRow méthode :

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! TableViewCell 
    cell.stepper?.tag = indexPath.row 
    cell.stepper?.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged) 
    return cell 
} 

func stepperValueChanged(_ stepper: UIStepper) { 
    //use stepper.tag as index to fetch an object from your dataSource 
    let workout = dataSource[stepper.tag] 
}