Chapter 18 - Show new list

In chapter 18, where we add the code to perform a segue to the last opened list before the app was terminated, I wanted to try to go a little further and figure out if I could have the app perform a segue to the “ShowChecklist” screen right after I add a new checklist. I figure this would be best handled in AllListsViewController.swift, since it is already performing such segues if the user has the checklist selected and quits the app.

I added some lines to the ListDetailVC(_:didFinishAdding:) delegate function in AllListsVC that handles adding a new list:

func listDetailViewController(_ controller: ListDetailViewController, didFinishAdding checklist: Checklist) {
        let newRowIndex = dataModel.lists.count
        let indexPath = IndexPath(row: newRowIndex, section: 0)
        let indexPaths = [indexPath]
        tableView.insertRows(at: indexPaths, with: .automatic)
        navigationController?.popViewController(animated: true)
        dataModel.indexOfSelectedChecklist = newRowIndex
        performSegue(withIdentifier: "ShowChecklist", sender: checklist)

The last two lines are all I added, after the nav controller pops the item detail screen and goes back to the All Checklists screen, I set the dataModel index to the new row index, and then perform the segue to the newly added checklist. This segue itself works, however, if I go to add an item to the new checklist, I get a debugger output “Unknown class AddItem in Interface Builder file”. The item is saved though, so I’m not sure what I am supposed to do about that either.
Print statements I added tell me that the pop back to the main screen resets the dataModel.indexOfSelectedChecklist back to -1 AFTER this function sets it to the new row index, and the -1 is carried into the AppDelegate saveData function, and the newly added list is not returned to after quitting and restarting the app. This functionality works only if I go back and tap the list, like it should.

I tried to comment out the call to popViewController to see what would happen, which succeeded in not resetting the dataModel value back to -1, but instead wrecked control flow for the Nav Controller, letting me press the back button to go from the individual checklist view back to the checklist add screen. If I hit Cancel then, the screen goes back to the main Checklists view, while still adding the new list; and If I were to hit Done instead of Cancel, it just repeats and won’t let me go back to the main screen until I hit back, then Cancel, at which point it would have added as many duplicate lists as the amount of times I hit Done.

So to sum it up, Im trying to figure out the proper way to segue automatically into a newly created list, while also retaining the ability to save that index and return to the new list if the app is quit while the new list is selected. I guess I am not really sure how all this fits together still, and any insight into how to go about doing that, or where I went wrong, would be greatly appreciated.


I would suggest that you first fix this error and then see if the rest of the code works after that or if you find new issues after fixing this one.

When you get a complaint about an unknown class in the Interface Builder file, it generally means that the class has changed somehow (possibly) or that the class name changed and that Interface Builder is not able to find this class any longer. Just go to Interface Builder, find where the AddItem reference is in the Identify Inspector and fix it.

I don’t have the PDF file open at the moment and so don’t remember if AddItem is the right name or if you have the incorrect name there. If it is the correct name, then simply removing and then adding back the same name sometimes fixes issues. If the name is incorrect, then fix it and then try running the app.

Hopefully, this helps :slight_smile:

Thanks for the response! Sounds like an easy fix. Any insight on the main point, trying to jump directly to the new list once it’s added? I get the unknown item error whether i add the extra lines of code or not, and otherwise the checklists behave as they should, with items being correctly added, and data persisting throughout quit/reboot. I was trying to poke around and do a little extra to make sure i knew what i was doing, and i found that I do not. Lol :sweat_smile:

I thought that your original post said that this worked? Or at least, that’s the impression I got :slight_smile: You said, “This segue itself works, however, if I go to add an item to the new checklist, I get a debugger output “Unknown class AddItem in Interface Builder file”” So I thought that meant that the segue you added to take you to the newly created checklist works?

yeah it segues to the new list after I add it, but something happens where the dataModel’s selected row value is reset to -1, so if i quit the app and relaunch, it won’t return to the new list that i just created, like it would do with a list that had previously existed. It returns to the main screen in this case. So nothing is broken, but i was hoping to get a better grip on how the parts move and work together by solving this little issue.

should I add a segue in the storyboard directly from the add list screen to the view checklist screen? instead of popping the view controller when i hit done and returning the all checklists screen, adding a new checklist would then segue directly to the newly created list?

So I found the AddItem error in Interface Builder, I had given the Navigation Controller UINavigationItem a class name AddItem, I removed it, and now the debugger message is gone. Thanks for your input!
I would really appreciate some feedback about how to get the app to go back to the newly added checklist after I add the extra functionality to perform the segue. I know it sounds trivial, but it would really help me understand better how the app works if I could iron out that one little kink

Since you are trying to do something different to the tutorial, I’d really have to see the full code in order to understand what your code might be trying to do. But if you’d like some high-level pointers on what to look for, then here are some things to consider:

  1. If you want to see what is setting indexOfSelectedChecklist to -1, you can always do a global search across your project for indexOfSelectedChecklist and see where it is modified/updated. Then, you can either add log statements or breakpoints to see how/when this happens and figure out the order of code execution and then figure out how you might want to change that to do what you want.

  2. Since the indexOfSelectedChecklist property of DataModel also handles persisting the current selection via UserDefaults you can also look at the indexOfSelectedChecklist property code and see how you can modify it to filter out a value of -1 if you already have a value other than -1 already set.

These are two separate things that you can experiment with. One or the other (or both) should help you figure out what you need to do.

My code should be identical to the tutorial up to the beginning of Chapter 19. The only code I added outside the tutorial were the last two line of the segment in my first post:

dataModel.indexOfSelectedChecklist = newRowIndex
performSegue(withIdentifier: "ShowChecklist", sender: checklist)

this works by popping back to the main list of lists, and then going to the newly added checklist right away.
All of the following takes place within AllListsViewController
The code shown is added in the delegate listDetailViewController(_:didFinishAdding:) function, which then updates the indexOfSelectedChecklist value to whatever index the new checklist was added to.
The program then runs in navigationController(_:willShow:) and because we bounced back to the main list of Checklists, this triggers the reset of indexOfSelectedChecklist to -1.
In viewDidAppear(_:) the value remains at -1, and the segue is skipped because of this.
The function tableView(_:didSelectRowAt:) is never triggered because of the automatic segue, so the indexOfSelectedRow value remains -1 unless I press back and then tap the new list.
I had thought adding the indexOfSelectedRow update at the end of the List Detail delegate (_:didFinishAdding) and then performing the automatic segue might be enough, but apparently not.
I tried filtering out the update like you suggested if the value was already set at something other than -1, but then this entered a endless loop when adding a new list and then pressing back to the main screen, where navigationController(_:willShow:) and viewDidAppear(_:) bounce back to the checklist from the main screen, never letting me select another list.

So should I just try to manually call tableView(_:didSelectRowAt:) with he value of the newly added row at the end of listDetailViewController(_:didFinishAdding)?

Thanks for your help!

When it comes to coding, there are no “truly correct” answers - just ones that work for you and your use-case :smiley: So, if you think something is worth trying, don’t worry about whether that is the “right” thing to do - just try it out. You’ll learn from it whether it works or not.

If it works, you’ve got the solution that works for your situation. If it doesn’t, then you get one more bits of information as to why it doesn’t work for your particular situation and then you can figure out what to try next.

So just try what you think might work and you’ll hit upon the answer. Do note that if the approach you’re thinking of now doesn’t work (I don’t know if it will or not, off hand) then you might have to consider revamping how you store the checklist to show on the next session launch. Again, I don’t know if this will be needed or not, but just saying that if the existing code doesn’t suit your requirements, then there is no need to keep butting your head against a wall - don’t be afraid to drop (or modify) existing code to get things to work the way you want :slight_smile:

This topic was automatically closed after 166 days. New replies are no longer allowed.