14 Replies
      Latest reply on May 17, 2018 1:56 PM by Claude31
      Cellomaster87 Level 1 Level 1 (0 points)

        Dear all,

        In my continuous struggle to learn how to code I am starting to see some light as, without help, I can complete the lessons and the apps work!

         

        Just now I would like to complete the challenge at the end of Unit 4.9 of 'App Development with Swift'.

        The app by itself (a room booking app) works as follows:

        - TableView(1) > click '+' > get into another TableView(2) > insert a bunch of data (names, dates, ... ) > click 'Done' button

        - TableView(1) now has a row carefully populated with the data I have inserted in TableView(2).

         

        Now, the challenge asks that I create a segue from TableView(1)'s cell that would allow the user to get back to TableView(2) and see the datas (and I assume possibly edit them).

        I had no problem creating a functioning segue but I get to an empty TableView(2), instead of to the one I just used.

         

        I wonder if this has something to do with data not being saved but I doubt it because every new entry gets appended into an array.

        I can paste hundreds of lines of code but I would prefer to get a hint to the logic needed to get back to my 'detailTableView'.

         

        Is it the reloadView() method?

        Thank you for your help and feel free to ask me any other detail I could add to help you help me!

        I will keep crunching my brain as I feel something improving!

         

        Thanks!

        • Re: Segue to view details of a previous input
          Claude31 Level 7 Level 7 (3,240 points)

          Have you written the prepare(segue:) function ?

           

          in this func, you set the var that will be used by the second controller to load the tableview.

           

          This looks like this:

           

          override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
                 let destVC = segue.destination as! DestViewController // the class of the destination controller
                 destVC.var1 =  // set value for each property of destination controller needed for table view
                 } 
              } 

           

          in the destination controller, you use this var1.... in viewDidLoad

            • Re: Segue to view details of a previous input
              Cellomaster87 Level 1 Level 1 (0 points)

              Please give a look at the discussion labelled How to segue back to filled-in version of TableViewController (Swift)? on StackOverflow.

              I have already implemented their suggestion and, still the TVC reloads as an unfilled form, while I need it to reload the data it has just passed.

               

              Also, each property of destination controller should be equal to the part of that just saved in the array the tapped cell belongs to.

                • Re: Segue to view details of a previous input
                  Claude31 Level 7 Level 7 (3,240 points)

                  Well, I will not review all this code.

                   

                  Please post:

                  - Your prepare function

                  - the viewDidload in destinationVC

                    • Re: Segue to view details of a previous input
                      Cellomaster87 Level 1 Level 1 (0 points)

                      Forgive me, I didn't ask you to review all that code because it works until I get to the challenge in the book which says as follows:

                       

                      Update the RegistrationTableViewController with a segue that allows the user to select and view the details of a registration in the AddRegistrationTableViewController.

                       

                      Your proposed solution makes the app crash because there is no identifier to the segue.

                      So: my prepare function is just this by now:

                       

                      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                              if segue.identifier == "ViewReservationDetails" {
                                 
                              }
                          }

                       

                      All the proposed solution do not give the desired result, at least by now.

                       

                      The viewDidLoad in the AddRegistrationTableViewController:

                      override func viewDidLoad() {
                              super.viewDidLoad()
                             
                              let midnightToday = Calendar.current.startOfDay(for: Date())
                              checkInDatePicker.minimumDate = midnightToday
                              checkInDatePicker.date = midnightToday
                             
                              updateDateViews()
                              updateNumberOfGuests()
                              updateRoomType()
                          }

                       

                      Thank you for your help.

                        • Re: Segue to view details of a previous input
                          Claude31 Level 7 Level 7 (3,240 points)

                          So you update  the dates with a date from calendar ; I guess this is correctly displayed ?

                           

                          Probably, the other elements of the table

                                  updateDateViews() 
                                  updateNumberOfGuests() 
                                  updateRoomType()

                           

                          Could you post the code of those functions ? They probably use the var that you need to set in prepare segue.

                            • Re: Segue to view details of a previous input
                              Cellomaster87 Level 1 Level 1 (0 points)

                              Please find the code below.

                              In the meantime I am wondering ... when I first create a new Registration object, where does it get saved?

                              And if it does get saved, why can't I just call it back and load it into the summoned back TVC?

                               

                              func updateDateViews() {
                                      checkOutDatePicker.minimumDate = checkInDatePicker.date.addingTimeInterval(86400)
                                     
                                      let dateFormatter = DateFormatter()
                                      dateFormatter.dateStyle = .medium
                                     
                                      checkInDateLabel.text = dateFormatter.string(from: checkInDatePicker.date)
                                      checkOutDateLabel.text = dateFormatter.string(from: checkOutDatePicker.date)
                                  }

                               

                              func updateNumberOfGuests() {
                                      numberOfAdultsLabel.text = "\(Int(numberOfAdultsStepper.value))"
                                      numberOfChildrenLabel.text = "\(Int(numberOfChildrenStepper.value))"
                                  }

                               

                              func updateRoomType() {
                                      if let roomType = roomType {
                                          roomTypeLabel.text = roomType.name
                                      } else {
                                          roomTypeLabel.text = "Not Set"
                                      }
                                  }

                               

                              Thank you

                                • Re: Segue to view details of a previous input
                                  Claude31 Level 7 Level 7 (3,240 points)

                                  I think I see your problem.

                                   

                                  In the destination controller, you should define properties to hold the values:

                                  var numberOfAdults : Int = 0          // This will be updated later
                                  var numberOfChildren : Int = 0
                                  var checkInDate = Date()
                                  var checkOutDate = Date()
                                  var roomType : RoomType     // in fact, the type you have defined

                                  Then, in viewDidload of destination VC, you set the outlets with the correct values, such as:

                                   

                                  numberOfAdultsStepper.value = numberOfAdults

                                   

                                  In fact, you should also use the var elsewhere, such as:

                                   

                                  func updateNumberOfGuests() {
                                          numberOfAdultsLabel.text = String(numberOfAdults)
                                          numberOfChildrenLabel.text = String(numberOfChildren)
                                      }

                                   

                                  And, in prepare segue, you set the values for all those var, as read from the selectedCell.

                                    • Re: Segue to view details of a previous input
                                      Cellomaster87 Level 1 Level 1 (0 points)

                                      Ok, I am going to try this. While I write the rest, could you please also write how the prepare segue should look.

                                      I need to know how to read the properties from the selectedCell.

                                       

                                      By now I have only this:

                                      override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                                              tableView.deselectRow(at: indexPath, animated: true)
                                              performSegue(withIdentifier: "ViewRegistrationDetails", sender: indexPath)
                                          }
                                         
                                          override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                                              if segue.identifier == "ViewRegistrationDetails" {
                                                  let destinationViewController = segue.destination as? AddRegistrationTableViewController
                                              }
                                          }

                                       

                                      Thank you

                                        • Re: Segue to view details of a previous input
                                          Claude31 Level 7 Level 7 (3,240 points)

                                          Your segue is starting from the cell when you click, right ?

                                          Sender should be the cell, not the indexPath

                                           

                                          Then

                                           

                                              override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                                          
                                                  if (segue.identifier == "ViewRegistrationDetails") {     // Your segue identifier
                                                      if let cell = sender as? UITableViewCell {
                                                          if let destVC = segue.destination as? DestViewController {     // Your type
                                                              destVC.numberOfAdults = cell.numberOfAdults    // How have you defined numberOfAdults in cell ?
                                                              // The same for other var
                                                          }
                                                      }
                                                  }
                                              }
                                            • Re: Segue to view details of a previous input
                                              Cellomaster87 Level 1 Level 1 (0 points)

                                              This is how the cellForRowAt looks like:

                                               

                                              override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                                                      let cell = tableView.dequeueReusableCell(withIdentifier: "RegistrationCell", for: indexPath)
                                                     
                                                      let registration = registrations[indexPath.row]
                                                      let dateFormatter = DateFormatter()
                                                      dateFormatter.dateStyle = .short
                                              
                                                      cell.textLabel?.text = registration.firstName + " " + registration.lastName
                                                      cell.detailTextLabel?.text = dateFormatter.string(from: registration.checkInDate) + " - " + registration.roomType.name
                                              
                                                      return cell
                                                  }

                                              I guess I should take the data from there if I want to go back.

                                                • Re: Segue to view details of a previous input
                                                  Claude31 Level 7 Level 7 (3,240 points)

                                                  Where do you store or compute numberOfAdults, numberOfChildren ?

                                                   

                                                  prepare should look like:

                                                   

                                                      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
                                                          if segue.identifier == "ViewRegistrationDetails" {
                                                              if let destinationViewController = segue.destination as? AddRegistrationTableViewController {          // Additional if
                                                  
                                                               if let selectedRow = tableView.indexPathForSelectedRow.row     {       
                                                                 // I suppose you have defined an IBOutlet for the table view ;
                                                                 // otherwise, when you select cell, you could save the indexPath.row of the selectedCell
                                                                         let registration = registrations[selectedRow]
                                                                        // set properties here
                                                                  }
                                                  
                                                            }
                                                          }
                                                      }
                                                    • Re: Segue to view details of a previous input
                                                      Cellomaster87 Level 1 Level 1 (0 points)

                                                      I'm sorry, I am getting more and more confused (I'm a beginner and trying my best to learn but after just 3 months of learning my head is exploding at this...).

                                                       

                                                      Could you please give a look at the code in the StackOverflow post (that is really all the code except for a TableView that doesn't get used in this case) and tell me what has to be changed or, at least, in which direction I have to look.

                                                      All the changes proposed produce more and more errors, though I am sure part of it is because I am not comfortable enough to understand your instructions ...

                                                       

                                                      I can also send you the project if you may give me your e-mail address.

                                                      I understand if you do not have the time for this.

                                                      After three days of mind-crunching and failure I have almost decided to move on to the next project and come back when I will be able to look at this and just do it.

                                                       

                                                      Thank you