Building a Simple Time Tracker With SwiftUI — Part 3

Allowing user to delete projects and creating basic UIs for all platforms

Photo by Debby Hudson on Unsplash

In the last part we saved projects to UserDefaults. In this part we’re going to allow the user to delete projects and code our basic UI. I did some sketching for what I would like the UI to look like and during that process got a couple of ideas for features to add (like categorisation of projects), but for this part the focus will be in getting a basic UI for each of the platforms. We can tune everything in the next part. You can find all of the code for this part in the post/part-3 branch on GitHub.

UI sketches

To be able to handle different UI’s for different platforms, we need to add a check to do just that. This won’t be a run time check, like your normal if-else statements. This will be a build time check. So how do we write that? We use hashtags, like this:

Here you can see how the build time and runtime checks differ. #if is a build time check, while the normal if is a run time check. Here is a great explanation in StackOverflow why you need to do the checks this way. Basically we are first checking if the operating system is macOS or iOS. If it is iOS, we’re using a runtime check to see if it is an iPad, if not we use iPhone UI.

Basic iPhone UI

Basic UI

Simplicity is the key when it comes to the way I like to design interfaces. If there is no need to show some certain elements, then they should be hidden. What to we want to show:

  • The title of the app
  • The projects we track time for (name, time, on/off button)
  • Button to add new projects with
  • Edit button to allow the user to delete projects with.

For the next part, the improvement I want to have deletion of projects to be behind a swipe. The swipe will reveal a delete button, which can be used to delete the project. For me that is the default functionality for deleting items from a list, so that will be the part of the final UI. There also needs to be some fine tuning of the buttons to make them fully line up with each other. But this is a perfectly fine for the first version.

There’s a couple of fun things that we will do here:

  • We’ll show a message if there are no projects, and the projects if we have them.
  • We will use ZStack to position our add button in the bottom of the screen.
  • The edit button will be made using the .toolbar method in SwiftUI.
  • For adding new projects we will use .sheet to give the user a text field and a save button.

The Code

We have three different @State objects. One for our projects array, like before. One for toggling the addition of new projects. And one for toggling the edit mode.

We have a NavigationView to wrap our other views in, this allows us to have a nice title up top using .navigationBarTitle() this also allows us to use .toolbar to add our button for toggling the edit mode. If you wan’t to learn more about the toolbar modifier, you can watch this video by Sean Allen on the subject. The edit mode brings the biggest change to our app, as it allows the user to delete existing projects. This is how our ProjectView.swift looks after the change:

We give @Binding to every ProjectView so we can add a delete button and disable the start/stop when the edit mode is active.

Next we have a ZStack to allow us to have a floating add button in the bottom of our screen. We could have just as easily put the add button as a toolbar item, but I think the big add button on the bottom makes a clear call to action.

Last but not least, we have .sheet that gets activated when the add button is clicked, to show you a very simple sheet for adding a new project. The code for the AddProject.swift looks like this:

A very basic Form with a simple TextField for the name and a save button. Using .sheet doesn’t make the prettiest interface and we will definitely fix that later.

Basic iPad UI

The iPad UI and code is almost identical to the iPhone design and code, except we cannot use NavigationView. The NavigationView on the iPad wants us to have NavigationItems, and it will show the selected item as the main view. To remove the NavigationView is simple but requires a bit of playing around to get the edit button to show in the same manner. Here’s the code for that:

We make the title and position the edit button manually using Spacer() . Spacer takes all the available space, and will automatically push all other views to the side. Normally views take only the space they need, Spacer is special because it does the opposite. Besides those differences the code is exactly the same as it is with the iPhone code.

macOS Changes

For macOS, I only made the UI more like the iOS and added the support for the edit mode. The edit mode now shows a text field and an add button next to it for adding new projects. Very basic way of getting the same changes as we have on other platforms to work. In a later part we will work on a bigger overhaul of the macOS UI. Since there were very little changes, and changes that will be deleted later, I won’t add any source code here. You can always check the branch for all the changes made.

Thanks for reading. Here are the links to the other parts as well as my newsletter. Sign up to get interesting articles and videos straight to your inbox.

iOS developer building cool products and nerding out about comics. Currently running my first big D&D campaign. Occasionally funny,