Welcome to Hack@Brown's iOS App Development starter pack! We'll walk you through building your first app and give you a quick look at a bunch of reusable features that you can use for your future projects. After working through this pack, you should be comfortable with navigating Xcode and beginning your journey into creating components, tab views, and interactable/updateable features.
As you work through this starter pack, feel free to reference the files in the repo to see what a completed project looks like. A great tool you can use to learn is "Show Quick Help" by right-clicking keywords in Xcode to view their documentation as you code.
📚 Table of Contents
Before we begin coding, set up the following:
- Download Xcode from the App Store with the latest MacOS here (Windows is not supported)
- Open Xcode and "Create New Project..."
- Select App, name your project, change the interface to SwiftUI, and choose Swift as the language
- With a new project opened, you should see [Name].App, ContentView, and Assets created for you
The three components of the project below will teach you some of the most important building blocks in Swift.
- vars: Variables that store types of data. Modifying a var with @State will link it to a view and update it if its value changes.
- struct: Models an instance with specified values, method, properties, functionality. Similar to a class, which Swift also supports.
- Graphical Stacks: Layout collections that frame elements horizontally, vertically, or on top of each other (
HStack,VStack,ZStack). - View: A declared type on struct/var that contributes to building the app interface that is displayed in ContentView and the app itself.
- Closure: A chunk of code that can be stored in a variable and called upon later like a method. Can remember and interact with values from their creation.
For a video tutorial on using Xcode and learning parts of Swift, see this and that.
The goal is to create a reusable header that will appear across all tabs, which will be later implemented
- Create a new folder in your project folder called components by right-clicking the latter
- Use Command⌘ + N to create a new Swift file in the folder called Header
- Import
SwiftUIand create astructwith the typeView - Within the struct, create a
varto store aStringfor the title and thevar body, which should implement aZStackwithin it withColorandText(String)
To see the finished component, select ContentView, and enable a preview screen by going to Editor -> Canvas.
By calling the struct (AppHeader) with a title argument (AppHeader(title: "Test")), the canvas will compile and display your header.
At the bottom of our App, we want to have a row of buttons to switch between five tabs. We can use Swift's TabView feature for this.
- Create a new folder in the App folder named Views and five new Swift files for different Views
- After importing
SwiftUIin each, create a newstructwith the typeViewand avar body - In the
body, create aVStackthat calls the header component, generates text that displays the name of the tab, andSpacer()s that push the header to the top and center the text. - With all five views completed, create a
TabViewin ContentView that calls all five views and.tabItemto create matchingLabels with names and icons (usesystemImageto access Swift's built-in icons)
On one of the tabs, we will implement a grid of emojis that can be interacted with, and in response, create emojis that fall down the screen. See files EmojiGrid and DropView for comments and overall structure.
To structure an interactable grid of six emojis, we will split its creation into unit cells and a grid that combines them.
- Create a new Swift file under components and import SwiftUI
- Use a
Viewstructthat models an EmojiCell with aStringvariable to dictate its appearance and a closure variable to react to.onTapGesture - In the
var body, attach the gesture recognizer.onTapGestureto the emoji text and assign its action to the closure - Use a new
viewstructbelow that models the EmojiGrid and create aStringarray of emojis, an array ofGridItem(.flexible())to format columns, and a closure variable, which passes the emoji as aStringto the view, that is triggered by each cell's closure - In the
var body, create aLazyVGridand pass the previous array formatting as its parameter - Use a loop afterwards to create multiple EmojiCells
ForEachemoji in the stored array, where each cell is linked to the grid's closure so that taps can trigger the parent's action
The tab under Views that will be used should have the capability of creating, storing, and updating emojis as they are tapped into existence and removed once they fall off screen
- Create a separate
Identifiablestructthat acts as a data model for every emoji that is dropped with variables to track itsUUID(), String,CGFloatcoordinates and velocities - In the
Viewstruct, create updateable@Statevariables that automatically trigger view updates for an array of currently dropped emojis, the width of the screen, and the height of the screen - Use a
ZStackto organize all dropped emojis to render in the back first, aVStackfor the header and emoji grid, and aGeometryReaderto measure the width and height whenColor.clear.onAppearoccurs - When creating
EmojiGrid, define/delegate its closure using random positions and velocities withCGFloat.random(in:\[min\]...\[max\]to create a new instance of theIdentifiablestructthat should be appended to the@Statearray - On completion of the
ZStack, begin aTimerwith.scheduledTimerthat repeatedly increments the position of the emoji by its velocity and checks a condition for it to be removed
Having completed this pack, you now have a ticket to begin your journey through the world of app development. Whether it be tabs or closures in games or programs, we're excited to see what you can do and hope you enjoy your time at Hack@Brown 2026. With that... Happy Hacking!
