Creating a Touch Point Recorder App in SwiftUI

If you're just starting to learn Swift and SwiftUI, it can be helpful to create simple apps that allow you to experiment with the language and framework. One such app is a touch point recorder, which allows you to visualize the coordinates (x, y) of the points where you touch the screen.

In this blog post, we'll walk through the process of creating a touch point recorder app using SwiftUI. Along the way, we'll cover the basics of SwiftUI and how to work with touch gestures.

Setting Up the Project

To get started with building the Point Recorder app, you'll need to create a new project in either Xcode or Swift Playgrounds.

Xcode

To create a new project in Xcode:

  1. Open Xcode and choose "Create a new Xcode project" from the welcome screen.

  2. Choose "App" under the "iOS" tab and click "Next".

  3. Choose "SwiftUI" as the user interface and click "Next".

  4. Enter a name for your project and choose a location to save it. Make sure to select "Create Git repository on my Mac" if you want to use version control for your project.

  5. Click "Create" to create the project.

Swift Playgrounds

If your students are working on an iPad, they can use the "My App" Playgroundbook template to run the PointRecorderView code in a playground. Here's how:

  1. Open Swift Playgrounds on your iPad.

  2. Select the "My App" template located at the bottom of the app.

  3. Give your playground a name and tap to open

  4. Add a new Swift file in the side bar

  5. Copy and paste the PointRecorderView code into the playground.

With the "My App" template, your students can run their SwiftUI code in a live preview, just like in Xcode. This makes it easy to experiment with different layouts and features, and to see how their code changes affect the final output.

Overall, Swift Playgrounds is a great tool for teaching coding on iPad, and the "My App" template is a great starting point for creating SwiftUI apps.

With the project set up, we can now create the PointRecorderView struct. This view will be responsible for displaying the touch points on the screen and recording them.

Creating the PointRecorderView

Here's the code for the PointRecorderView struct:

import SwiftUI

struct PointRecorderView: View {
    // array to hold the recorded touch points
    @State private var points: [CGPoint] = []
    
    var body: some View {
        // use a GeometryReader to get the size of the view
        GeometryReader { geometry in
            // display the touch points on top of a white background
            ZStack {
                Color.white
                // loop over each point and display its coordinates as text
                ForEach(points, id: \.self) { point in
                    Text("(\(Int(point.x)), \(Int(point.y)))")
                        .position(point)
                        .foregroundColor(.black)
                }
            }
            // add a DragGesture to track the user's touch points
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { value in
                        // add the touch point to the points array
                        let point = value.startLocation
                        points.append(point)
                    }
            )
        }
    }
}

struct PointRecorderView_Previews: PreviewProvider {
    static var previews: some View {
        PointRecorderView()
    }
}

extension CGPoint: Hashable {
    public func hash(into hasher: inout Hasher) {
        // combine the x-coordinate of the point with the hasher
        hasher.combine(x)
        // combine the y-coordinate of the point with the hasher
        hasher.combine(y)
    }
}

Let's go through each section of this code to understand how it works.

@State Property Wrapper

The @State property wrapper is used to declare a state variable for the view. In this case, we declare points as an empty array of CGPoint values. We'll use this array to store the touch points recorded by the user.

GeometryReader

The GeometryReader is used to get the size and position of the view. We use it to create a full-screen view that can be tapped by the user to record touch points.

ZStack

The ZStack is used to layer views on top of each other. In this case, we use it to create a white background and display the touch points on top of it.

ForEach

The ForEach is used to loop over each touch point in the points array and display its coordinates as text. We use the id parameter to ensure that each point is uniquely identifiable.

gesture

The gesture modifier is used to add a touch gesture to the view. In this case, we add a DragGesture with a minimum distance of 0. This means that the user can simply tap the screen to record a touch point.

onChanged

The onChanged closure is called when the user touches the screen. It captures the startLocation of the touch gesture and appends it to the points array.

With this code in place, we've created a basic touch point recorder app in SwiftUI. However, there's one more thing we need to do to ensure that the CGPoint values are properly hashed so that they can be used as identifiers for our points array: we need to extend the CGPoint struct to conform to the Hashable protocol.

In this extension, we're telling Swift how to combine the hash values for the x and y coordinates of our CGPoint. By doing this, we're ensuring that two points with the same coordinates will have the same hash value and can be considered equal.

With this extension in place, we can now use our PointRecorderView to record and display a series of points on the screen. When the user taps or drags on the screen, a new CGPoint is added to our points array, and the view is redrawn to show all of the points on the screen.

To use the PointRecorderView in our app, we simply need to create an instance of the view and add it to our SwiftUI hierarchy. For example:

struct ContentView: View {
    var body: some View {
        PointRecorderView()
    }
}

In this example, we're adding the PointRecorderView to the content view of our app. When we run the app, we can tap on the screen to record points, and they will be displayed on the screen in real-time.

Overall, the PointRecorderView is a simple yet powerful tool for visualizing coordinates in SwiftUI. Whether you're teaching students about geometry or simply want to add an interactive element to your app, the PointRecorderView is a great starting point. With just a few lines of code, you can create a fully-functional app that records and displays points on the screen.

Previous
Previous

What is State Machine?

Next
Next

Understanding the Similarities Between Classes and Structs in Swift: Representing Real-World Objects in the Digital World