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:
Open Xcode and choose "Create a new Xcode project" from the welcome screen.
Choose "App" under the "iOS" tab and click "Next".
Choose "SwiftUI" as the user interface and click "Next".
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.
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:
Open Swift Playgrounds on your iPad.
Select the "My App" template located at the bottom of the app.
Give your playground a name and tap to open
Add a new Swift file in the side bar
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.