Recreate Finder From OS X Panther in SwiftUI (Part 2 of 2)

Daily Coding Tip 038

In yesterday’s coding tip we created the background for the window and the close, minimise and full screen buttons. Today we’ll create the content for the Finder window. We’ll start with the search field, which isn’t very complicated. The background is a white capsule with an offset outline in front of it. The foreground is an HStack with the magnifying glass icon and a regular SwiftUI TextField, which doesn’t actually have a background of its own.

There is a button in the top right of this screenshot of Finder, which was the toggle toolbar button. This no longer exists in the modern version of macOS, and wasn’t available in all windows of all apps in OS X Panther either. It is very similar to the buttons in my 3D Aqua buttons tutorial, with a few subtle changes. It doesn’t need a title, so we don’t need to pass the configuration to the button. The main difference between this and the circular buttons is the use of the Capsule shape instead of Circle, allowing the button to stretch in any direction. The aspect ratio is not locked, so it can be taller or wider without breaking the appearance we expect.

Now that we have the top row complete, we can combine the red, yellow and green buttons with the grey toolbar button. The title for the window will be centred between the two. As you can see, the buttons are given colour by the extension of Color that we created in yesterday’s coding tip. Because their aspect ratio is locked to a square, the circular buttons don’t need to be given a width. The toggle toolbar button is given a width of 30, and the HStack height sets the height of all of its children, so they don’t need to set this individually.

The final touch for the top of the window is the controls. If you look at this screenshot of Finder, you’ll see back and forward buttons, three options for the view mode, and an actions button. We can actually make all of these from the same control, which I’m going to call AquaSegmentedControlView. This requires a specific wave shape for the background, so I’m going to make that first.

The wave shape is used to mask a very light grey colour that is almost white, revealing a linear gradient behind it. Now that we have the background for our buttons, we can move onto the way we create them.

We have defined a type called ButtonData, which allows us to pass the configuration for all of the buttons as an array.

Like the other buttons we’ve created, the action closure is empty for most of them, but you can obviously do what you want in the closures. The exceptio to this is the view modes, which actually has a highlighted segment on the left end. To achieve this I’ve added a viewModeIndex State<Int> property that keeps track of which segment is selected. Tapping a segment changes this property, and the currently selected segment is highlighted in blue.

So now we have all the controls we want, and we have empty closures that we could put code into if we wanted to add functionality. The last thing we need to do is create the scrollviews that show the Finder content, which for the purposes of this tutorial will be hard-coded strings. In the example below, I used emojis for the icons:

"🌐 Network", "🏠 Home", "📄 Documents", "🎼 Music", "🎬 Movies", "🖼 Pictures", "🎮 Games"

But I have not included these in the code sample above. It’s up to you if you want to use these or add images of your own. The important thing is that this is a vertical ScrollView, and a horizontal line is added after the first two items. We’re going to do something similar for the main content area, except this will use a VGrid instead. The grid makes use of the emoji 📁 as an icon for the folders, which was another way for me to save time without having to replicate every icon.

Finally we can brinf everything together to create the complete window.

I used the 🏠 emoji next to the word Home in the AquaWindowControlsView, but you’re welcome to try and replicate that icon as well.

Get more Daily Coding Tips in your inbox!