Como fazer botões e inserir sons em apps usando SwiftUI

A popularização das maquinas digitais no século XXI trouxe consigo mudanças significativas na forma de produzir e compartilhar conteúdos. Uma dessas formas de disseminação de informações e mídias são os aplicativos: softwares desenvolvidos para serem utilizados em dispositivos digitais como celulares e tablets. No que se diz respeito a estes aplicativos, nota-se que há uma vasta gama de linguagens de programação na qual podem ser desenvolvidos. Para efeito deste artigo, utilizar-se-á a linguagem Swift e SwiftUI para ensinar como fazer botões e inserir imagens e sons em um aplicativo.

Ressalta-se ainda que esse trabalho foi desenvolvido utilizando a versão 15.3 (15E204a) do Xcode em um MacBook Pro M2, na versão 14.4.1 do Mac Sonoma.

Antes de iniciar o tutorial de como criar seu botão e inserir sons ao seu app, esse artigo irá esclarecer alguns conceitos básicos de Swift e SwiftUI.

Primeiramente, vale ressaltar que ao abrir um novo projeto no Xcode, deve-se escolher iOS como a plataforma e então selecionar App como o tipo de documento que se deseja gerar. Caso o SwiftUI não tenha sido importado automaticamente nessa etapa, importe-o.

Note que ao começar um projeto do tipo App o arquivo já é aberto com alguns códigos default, ou seja, comandos padrões que aparecem na sua tela antes mesmo de se começar a programar. Esse código default deve vir com uma pilha de vizualizações do tipo VStack.

VStack é uma estrutura de organização hierárquica que empilha as visualizações, verticalmente, isto é, uma em baixo da outra e é usada para interfaces simples em uma só view. A organização da visualização é feita com a linha de código mais a cima, dentro da VStack, ficando mais a cima na visualização do app.

1. CRIANDO UMA NAVIGATIONSTACK

Como mencionado acima, o código default do Xcode vem com uma VStack, contudo para que se possa criar um botão que navegue entre diferentes views, ou seja, que mude de página ao ser clicado, é necessário substituir essa VStack por uma NavigationStack.

NavigationStack é uma estrutura utilizada para alternar entre telas, gerenciando a hierarquia entre elas. Esse tipo de pilha funciona como se fossem várias views, uma sobre a outra que ao serem acessadas são retiradas da pilha e quando não acessadas vão para o topo da pilha, isso permite uma navegação hierárquica que dá ao código a capacidade de desfazer a mudança entre views.

Dentro da NavigationStack, pode-se criar uma ZStack. ZStack é outro tipo de pilha que organiza elementos no eixo Z, isto é, faz com que diferentes itens de um código fiquem sobrepostos, com o item mais acima, dentro dessa pilha, sendo o mais ao fundo.

No código abaixo, usou-se uma imagem própria, importada do Figma, chamada MainBackground, para se criar o plano de fundo da primeira tela. Para tal, após fazer o design, o mesmo foi salvo como um arquivo do tipo JPG e importado como um Asset, chamado de MainBackground. Essa imagem então foi chamada para o código e editada para se encaixar perfeitamente na tela do app.

Abaixo da imagem, foi criada uma VStack, na qual o botão estará contido. Dentro dessa VStack acionamos o comando Spacer(), esse comando irá garantir que o botão irá para a base da tela, ao invés de ficar no centro.

Dentro dessa VStack cria-se um NavigationLink, com o destino a segunda página do nosso app e pode-se usar uma imagem qualquer, nesse código usou-se uma imagem de um golfinho de autoria do FreePik.

import SwiftUI
struct ContentView: View {
var body: some View {
NavigationStack {
ZStack{
Image("MainBackground")
.resizable()
.scaledToFill()
.frame(alignment: .center)
VStack{

Spacer()

NavigationLink(destination: PageTwo()) {
Image("button1")
.resizable()
.scaledToFit()
.frame(width: 150)
.cornerRadius(20)

}

}
}
.ignoresSafeArea()

}
}
}

#Preview {
ContentView()
}

2. CRIANDO A SEGUNDA TELA

Para que, ao clicar-se no botão criado acima, a tela seja mudada, é preciso que se crie uma nova view. No app criado pela autora, essa nova view é chamada de PageTwo.

Dentro dessa segunda view, importaremos uma outra Struct chamada “MusicaChata”, que ainda será criada, para que uma musica seja tocada ao se selecionar um botão e desligada ao selecionar-se outro. Essa struct também fará com que os botões intercalem-se entre si.

No mais, dentro da struct PageTwo deve-se utilizar o comando “.onAppear”, que faz com que a música selecionada comece a tocar assim que a tela ContentView é trocada pela PageTwo, ou seja, ela começa quando eu mudar minha view, e o “.onDisappear” faz com o som pare de ser tocado uma vez que eu saia da view PageTwo.

import SwiftUI
struct PageTwo: View {
var body: some View {
ZStack{
Image("Background2")
.resizable()
.scaledToFill()
.frame(alignment: .center)

VStack{
MusicaChata()
}

}
.ignoresSafeArea()
.onAppear {
playSound(sound: "Minha Música", type: "m4a", volume: 1, numberOfLoops: -1)
}
.onDisappear(){
stopSound()
}
}
}

#Preview {
PageTwo()
}

3. CRIANDO UMA FUNÇÃO PARA TOCAR A MÚSICA

Para criar uma função que toque uma música é preciso primeiramente importar o Foundation, AVFoundation e criar uma variável do tipo “AVAudioPlayer?”. No código apresentado ela foi nomeada “audioPlayer”.

Esse tipo de variável é referente a uma classe em Swift utilizada para reproduzir sons e a interrogação na declaração da variável indica que o valor dela possa ser “nil”, nulo. Ou seja, mesmo tendo uma variável para reproduzir sons, pode ser que não haja nenhum som para ser reproduzido, mas apesar disso o código deve rodar.

Após declarar a variável, crio duas funções, uma que toca o som, chamando a variável audioPlayer e uma que faz o som parar, usando o comando audioPlayer?.stop().

Na função playSound, que toca o som, deve definir que o som vai ser chamado por uma string, que o tipo de som deve ser definido ao chama-lo, que o volume pode ser um float (número com casas decimais) e que o número inicial de loopings, ou repetições, é um número inteiro igual a zero.

var audioPlayer: AVAudioPlayer?
func playSound(sound: String, type: String, volume: Float, numberOfLoops: Int = 0) {
if let path = Bundle.main.path(forResource: sound, ofType: type) {
do {
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer?.volume = volume
audioPlayer?.numberOfLoops = numberOfLoops
audioPlayer?.play()
} catch {
print("ERROR: Could not find and play the sound file!")
}
}

}
func stopSound(){
audioPlayer?.stop()
}

4. APLICANDO MÚSICA AO BOTÃO

Para criar a struct MusicaChata, abre-se uma nova view, de mesmo nome da struct e dentro dela se declara a variável de estado “isImage1Visible”. Esse tipo de declaração faz com que, ao se alterar o valor da variável, as visualizações relacionadas a essa variável também serão modificados.

Em seguida, dentro do body dessa View cria-se um botão que, se pressionado, irá chamar uma função que tocará uma música e irá alternar entre duas imagens. É nessa parte do código que chamo minha música pelo nome, defino o tipo de arquivo, o número de repetições e o volume. Então, ainda dentro do botão, define-se melhor os detalhes das condições de uso: caso “isImage1Visible” for verdadeiro a imagem mostrada será “speaker”. Se não, a imagem mostrada será “speaker.slash”.

import Foundation
import SwiftUI
import AVFoundation

struct MusicaChata: View {
@State private var isImage1Visible = true


var body: some View {

Button(action: {
self.isImage1Visible.toggle()
if self.isImage1Visible{
playSound(sound: "Minha Música", type: "m4a", volume: 1.0, numberOfLoops: -1)
} else{
stopSound()
}
}) {
if isImage1Visible {
Image(systemName: "speaker")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100)



} else {
Image(systemName: "speaker.slash")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 150)
.foregroundStyle(.white)

}

}
}
}

5. RESULTADO

Por fim, o produto final desenvolvido pela autora desse post foi um aplicativo de duas views, como mostrado abaixo.

Caso queira ver o repositório no gitHub com o código comentado, pressione aqui.

Obrigada pela leitura!

--

--