Mobile Development 9 min read

Implementing Audio Playback and Settings Page in a SwiftUI “Electronic Wooden Fish” App

This tutorial walks through adding sound effects with AVFoundation, creating an AudioPlayer helper, implementing navigation to a custom settings view, and using SwiftUI bindings, forms, and modifiers to build a fully functional iOS “Electronic Wooden Fish” application.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Implementing Audio Playback and Settings Page in a SwiftUI “Electronic Wooden Fish” App

In the previous chapter the basic UI, interaction logic, and animations of the "Electronic Wooden Fish" project were completed; this chapter adds sound playback, a custom settings page, and related interaction logic.

First, download a short wooden fish knock sound (usually 1 second, mp3 or m4a) and add it to the Xcode project. Then import the Apple AVFoundation framework, which handles time‑based media, by adding import AVFoundation to the code.

Create a new Swift file named AudioPlayer . Import AVFoundation, Foundation, and SwiftUI, declare a global var soundPlayer: AVAudioPlayer? , and implement a playAudio(forResource:ofType:) function that builds the file path, creates a URL, initializes the player inside a do‑catch block, and calls soundPlayer?.play() . If loading fails, it prints "音频文件出现问题".

In ContentView , call the helper when the wooden fish is tapped: playAudio(forResource: "dong", ofType: "mp3") .

Next, create a new SwiftUI view called DetailView for the settings page. Add a navigation‑bar button in ContentView using .navigationBarItems(trailing: Image(systemName: "slider.horizontal.3")) and wrap the target view in a .sheet(isPresented: $showDetailView) { DetailView() } modal.

Declare a @State var showDetailView: Bool = false to control the sheet, and toggle it with self.showDetailView.toggle() when the button is pressed.

In DetailView , use @Binding properties ( gameType , totalNumber , number ) to receive values from ContentView . Provide constant defaults for previewing, e.g., DetailView(gameType: .constant(""), totalNumber: .constant(0), number: .constant(0)) .

Build the UI with a Form containing a TextField bound to $gameType , a Stepper bound to $totalNumber that displays Text(gameType + ":" + "(totalNumber)") , and another Stepper bound to $number showing the increment value.

Add a close button view: func closeBtn() -> some View { Button(action: { }) { Image(systemName: "xmark.circle.fill").foregroundColor(.white) } } Wrap the form in a NavigationStack , set the title with .navigationBarTitle("编辑内容", displayMode: .inline) , and attach the close button via .navigationBarItems(trailing: closeBtn()) .

Use an environment variable @Environment(.presentationMode) var presentationMode and dismiss the sheet with self.presentationMode.wrappedValue.dismiss() when the close button is tapped.

After these steps the app can play a "dong" sound on each tap, navigate to a settings page where users can edit the game type, total count, and increment value, and close the modal, completing the functional "Electronic Wooden Fish" app.

iOSSwiftUIsettingsnavigationAudio PlaybackAVFoundation
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.