前提回忆

在上一章节中,咱们完结了“电子木鱼”项目的根底部分,包含根底的UI款式、交互逻辑和动画作用。这一章节,咱们来完结“电子木鱼”App的声响播映、自定义设置页面及其交互逻辑。

音频预备:木鱼敲击声

当每次点击木鱼的时分,电子木鱼App都需求宣布“咚”的敲击声。咱们在网上能够找到并下载木鱼敲击声,下载好的文件拖入到项目中,如下图所示:

实战教程什么年代了还在敲传统木鱼?(二)

在此请记住下载的音频的时长(一般为1秒),以及文件名称、文件后缀名(一般为mp3、m4a),在之后的代码中需精确调用。

紧接着,咱们来完结音频播映相关的代码。音频播映需求运用到一个新的结构:AVFoundation。

AVFoundation是苹果在iOS和OS X系统中,用于处理基于时间的媒体数据的Objective-C结构,供运用者来开发媒体类型的应用程序。

AVFoundation结构能够用来完结播映声响的作用,首要需求在项目中引入AVFoundation结构,由所以Apple自带的结构,能够直接在项目中import导入,如下代码所示:

import AVFoundation

为了项目方便,咱们能够创立一个新的Swift文件来放置播映音频的相关代码。创立一个新的Swift文件,命名为AudioPlayer。在AudioPlayer文件中,引入AVFoundation结构,预设一个播映器,然后创立一个办法来运用播映器,如下代码所示:

import AVFoundation
import Foundation
import SwiftUI
var soundPlayer: AVAudioPlayer?
func playAudio(forResource: String, ofType: String) {
    let path = Bundle.main.path(forResource: forResource, ofType: ofType)!
    let url = URL(fileURLWithPath: path)
    do {
        soundPlayer = try AVAudioPlayer(contentsOf: url)
        soundPlayer?.play()
    } catch {
        print("音频文件出现问题")
    }
}

实战教程什么年代了还在敲传统木鱼?(二)

上述代码中,咱们预先创立了一个播映器soundPlayer,然后创立了一个办法playAudio播映声响,传入两个参数,forResource用于确认所需播映的音频文件的文件名称,ofType为文件的后缀名。

确认后参数后,将两个参数值给到途径path,再把途径给到地址url,便于后面播映器运用。在代码中运用声响播映器AVAudioPlayer播映声响,假如测验执行失败则打印输出错误信息。

完结后,回到Content文件,在点击木鱼时调用playAudio办法,如下代码所示:

playAudio(forResource: "dong", ofType: "mp3")

实战教程什么年代了还在敲传统木鱼?(二)

在预览窗口敲击了一下,作用不错(不禁笑出了声)。

页面跳转:翻开设置页面

接下来,咱们再晋级一下,测验编辑“积德行善值”参数等相关内容。咱们创立一个新的SwiftUI文件,命名为DetailView,如下图所示:

实战教程什么年代了还在敲传统木鱼?(二)

回到ContentView文件,咱们先来完结页面跳转交互逻辑。从ContentView跳转到DetailView页面的交互,是经过导航视图右边的按钮进行跳转,按钮部分能够运用navigationBarItems导航栏元素修饰符创立,如下代码所示:

.navigationBarItems(trailing: Image(systemName: "slider.horizontal.3"))

实战教程什么年代了还在敲传统木鱼?(二)

如此咱们创立了按钮的款式部分,但设置按钮不能进行交互,若是咱们在创立按钮,并且完结按钮的交互动作,那么在navigationBarItems导航栏元素修饰符中的代码就太过于复杂,且不够清晰。

咱们能够创立按钮元素视图,将再这个视图赋予navigationBarItems导航栏元素修饰符,以削减在修饰符中存在太多的不同性质的代码,如下代码所示:

func settingBtn() -> some View {
    Button(action: {
    }) {
        Image(systemName: "slider.horizontal.3")
            .foregroundColor(.white)
    }
}

实战教程什么年代了还在敲传统木鱼?(二)

页面跳转部分,需求提早声明一个Bool类型的参数来控制跳转动作,如下代码所示:

@State var showDetailView:Bool = false

页面跳转能够运用Sheet模态弹窗翻开方式,在Library挑选Modifiers修饰符栏目,找到sheet的修饰符,拖到VStack纵向布局容器中,并绑定声明好的触发条件及确认好需求翻开的页面,如下代码所示:

.sheet(isPresented: $showDetailView) {
	DetailView()
}

创立好页面跳转办法后,将触发条件给予到点击按钮处,并在点击设置按钮时,切换showDetailView的状况,如下代码所示:

self.showDetailView.toggle()

在预览窗口点击顶部导航菜单的“设置”按钮,即可翻开DetailView页面。

实战教程什么年代了还在敲传统木鱼?(二)

设置页面:自定义内容

来到DetailView页面,先设想下咱们需求设置的内容,整个电子木鱼App能够设置哪些内容?

实战教程什么年代了还在敲传统木鱼?(二)

联想在ContentView页面运用@State声明的变量,两个页面参数需求进行联动,则在DetailView页面需求运用@Bingding声明相同的变量,用于两个页面的数据绑定,如下代码所示:

@Binding var gameType: String
@Binding var totalNumber: Int
@Binding var number: Int

运用@Binding做数据双向绑定需求留意2点,一是在DetailView页面声明的用于绑定的变量短少默认值,因此在视图预览的时分需求给予默认值方可正常预览,如下代码所示:

DetailView(gameType: .constant(""), totalNumber: .constant(0), number: .constant(0))

实战教程什么年代了还在敲传统木鱼?(二)

二是在DetailView页面声明的变量,若其他页面需求跳转到该页面,则需求绑定DetailView页面声明的值。

咱们在ContentView页面需求跳转到DetailView页面,因此回到ContentView页面,在跳转的地方绑定对应的参数值,如下代码所示:

DetailView(gameType: $gameType, totalNumber: $totalNumber, number: $number)

实战教程什么年代了还在敲传统木鱼?(二)

完结后,项目不再提示报错信息后,咱们回到DetailView页面来完善页面相关内容。

款式部分,能够运用Form表单作为主体结构,在Library挑选Views栏目,找到Form表单控件,拖入到主体视图中,如下图所示:

实战教程什么年代了还在敲传统木鱼?(二)

参数设置部分,虔诚内容能够运用输入框作为设置,在Library挑选Views栏目,找到TextField输入框控件,拖入到Form表单中,输入框内容绑定运用@Bingding绑定的gameType参数,如下代码所示:

TextField("请输入内容", text: $gameType)

实战教程什么年代了还在敲传统木鱼?(二)

初始总量部分,咱们能够运用步进器作为设置数值的控件,在Library挑选Views栏目,找到Stepper步进器控件,拖入到Form表单中,Stepper步进器的值绑定初始总量totalNumber。

文字部分为了更好地展现该项设置的内容,能够运用字段拼接内容,同理,每次敲击木鱼添加的数值也能够运用Stepper步进器,如下代码所示:

Form {
    TextField("请输入内容", text: $gameType)
    Stepper(value: $totalNumber, in: 0...9999) {
        Text(gameType + ":" + "(totalNumber)")
    }
    Stepper(value: $number, in: 1...9999) {
        Text(gameType + " + " + "(number)")
    }
}

实战教程什么年代了还在敲传统木鱼?(二)

由于在DetailView页面并没有传入相应的值,因此在预览窗口只能看到短少值的作用,咱们在ContentView页面中点开设置检查绑定参数值后的作用,如下图所示:

实战教程什么年代了还在敲传统木鱼?(二)

很好,咱们测验调试了下项目,工作不错。

最后,咱们还需求添加封闭弹窗的交互动作,和上面提及过的办法一致,咱们能够创立按钮元素视图,将再这个视图赋予navigationBarItems导航栏元素修饰符,作为收起弹窗的按钮,如下代码所示:

func closeBtn() -> some View {
	Button(action: {
		}) {
			Image(systemName: "xmark.circle.fill")
			.foregroundColor(.white)
		}
}

然后对整个表单外层添加一个NavigationStack导航栏,并给Form表单添加navigationBarItems修饰符,创立封闭按钮的款式,趁便再把标题加上如下代码所示:

.navigationBarTitle("编辑内容", displayMode: .inline)
.navigationBarItems(trailing: closeBtn())

实战教程什么年代了还在敲传统木鱼?(二)

完结之后,创立一个环境变量用于完结封闭弹窗交互,并在点击封闭按钮时调用它,如下代码所示:

//声明环境变量
@Environment(.presentationMode) var presentationMode
//调用
self.presentationMode.wrappedValue.dismiss()

如此就完结了封闭弹窗的交互作用,回到ContentView视图试试作用,如下图所示:

实战教程什么年代了还在敲传统木鱼?(二)

项目预览:整体项目作用展现

完结之后,咱们回到ContentView页面,预览下整体作用,如下图所示:

项目总结

在本次项目中,咱们经过“电子木鱼”项目学习了如何运用SwiftUI这一声明式创立页面元素,也触摸了彻底运用Library经过拖拽组件和修饰符的方式来构建页面。

动画和交互方面,首次运用了AVFoundation结构,结合SwiftUI完结了敲击木鱼的“咚咚咚”音频播映,在运转项目听到“咚”的那一刻,也都不由得想笑作声,总算能体会到为何“电子木鱼”App能够火起来的原因。

假如一款软件为人们带来快乐,即使它没有特别的功能,也不失为一款优异的作品。

版权声明

本文为稀土技术社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!