0

I have a tableView in a View Controller with delegate and datasource wired up through the IB. I'm using the tableView for multi selection. In my didSelectRowAt IndexPath, selection lets the user mark a relationship between two Core Data entities:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
    {

        let wageClassObject = self.wageClasses[indexPath.row]
        let wageClassStatus = wageClassObject.value(forKey: "checked") as? Bool
        wageClassObject.setValue(!wageClassStatus!, forKey:"checked")

        if (wageClassStatus)! {
        proposalToEdit?.addToWageClasses(wageClassObject)    
        }
        else {
            proposalToEdit?.removeFromWageClasses(wageClassObject)    
        }    
    }

When the user loads the view the first time, selecting a row has no effect. When the user loads the view the second time, the add and remove functions work great.

I've tried every solution suggested in this thread but no dice. I can't find a case quite like mine, either, where the issue is that it doesn't work the first time the view loads.

Suggestions greatly appreciated!

Edited to add: viewDidLoad and Core Data code

 override func viewDidLoad() {
       loadProposalData()
        tableView.reloadData()
        super.viewDidLoad()

        proposalNameField.delegate = self
        pensionField.delegate = self
        percentField.delegate = self

        if let topItem = self.navigationController?.navigationBar.topItem {

            topItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.plain, target: nil, action: nil)

        }
  if  wageClasses != nil {
             getWageClasses()
            print("\(wageClasses)")
        }



    }
 func getWageClasses(){
        let fetchRequest: NSFetchRequest<WageClass> = WageClass.fetchRequest()

        do {
            try self.wageClasses = context.fetch(fetchRequest)

        } catch {
            // handle error
        }

    }


 @IBAction func calculateButtonTapped(_ sender: UIButton) {

    var proposal: Proposal!

    if proposalToEdit == nil {
        proposal = Proposal(context: context)

    } else {

        proposal = proposalToEdit

    }



        proposal.dateCreated = currentDateTime as NSDate?



    if let proposalName = proposalNameField.text {
        proposal.proposalName = proposalName
    }

    if let pensionContribution = pensionField.text {
        proposal.pensionContribution = (pensionContribution as NSString).doubleValue
    }

    if let percentIncrease = percentField.text {
        proposal.percentIncrease = (percentIncrease as NSString).doubleValue
    }



   /// if let setting the checked value?




    adD.saveContext()

    _ = navigationController?.popViewController(animated: true)
}

I am not using viewDidAppear.

A little more about the Core Data. I have two entities, proposal and wageClass. Both have a to-many relationship to each other. On this viewController, the user can edit the proposal through three textfields (name, percent increase, pension amount) and then select related wageClasses from the tableView.

I want the user to be able to input the proposal fields and select the related wageClasses the first time they click the Add button in the nav bar on the previous viewController. What's happening is that the user clicks add, inputs the data to the text fields, selects the wage classes, and hits calculate. The text fields save and the labels update with the programmed calculations, but the wageClasses data remain nil. If the user selects the proposal again (that's what I mean by loads the view a second time above) then the user can add the wageClasses and all the calculations run correctly. But not before that second opening of the view.

screenshot of the view

Community
  • 1
  • 1
  • can you show what exactly you are doing in `viewDidLoad` and `viewDidAppear` methods and what do you mean by "loading the view second time"? View controllers load their view usually once per app lifecycle. Any more code about giving access to Core Data stack in this ViewController? – Wladek Surala Apr 13 '17 at 17:54
  • edited to add requested info. Thanks! – camelCaseUpInYourFace Apr 13 '17 at 20:39

2 Answers2

0

You code uses proposalToEdit instance variable:

if (wageClassStatus)! {
    proposalToEdit?.addToWageClasses(wageClassObject)    
}
else {
    proposalToEdit?.removeFromWageClasses(wageClassObject)    
}  

Which is basically nil here, it must be initialized before calling this functions, thus making this calls not executed (can't be done on nil object). You insert it to the context for the first time in calculateButtonTapped:

if proposalToEdit == nil {
    proposal = Proposal(context: context)
}

if you want it to work first time (i.e. before first click on 'calculate'), add above code somewhere in viewDidLoad, like this:

override func viewDidLoad() {
   loadProposalData()
   if proposalToEdit == nil {
       proposal = Proposal(context: context)
   }

If above doesn't work I suggest you add a link to the repository to help debug this code, I cannot find more flaws in here, but there are no details in add and remove implementations, as well as how your core data stack works.

Wladek Surala
  • 2,590
  • 1
  • 26
  • 31
0

If anyone is stuck on the same problem, the key is to create the core data object before you add a relationship to another object. The above code doesn't work because I was trying to add relationships to objects that didn't yet exist.

My solution was to separate the operations in two view controllers but I would love to know more about how such can be achieved in one view controller.