SWIFTUI/Grammar

SwiftUI : State and Binding '클릭시 화면 변경'

서근 2021. 2. 12. 15:47
반응형

앞에서 @State@Binding을 배워봤으니 간단하게 프로젝트를 만들어서 활용해보도록 하겠습니다.

 

클릭시 화면 변경

뷰 생성

우선 화면에 표시될 뷰를 따로 만들어 주겠습니다.

//musicPlay View

import SwiftUI

struct Episode {
    let song: String
    let singer: String
    let track: String
}


struct musicPlay: View {
    
    let episode = Episode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
   
   @State var isPlaying = false
    
    var body: some View {
        
            VStack {
                Text(self.episode.song)
                    .font(.title)
                    //isPlaying이 재생중이면 blue 아니면 white
                    .foregroundColor(self.isPlaying ? .blue : .white)
                
                Text(self.episode.track)
                    .font(.footnote)
                    .foregroundColor(.secondary)
                
                Text(self.episode.singer)
                
                playButton()
                
            }
            //버튼을 눌렀을때 적용시켜줄 삼항연산자 코드 추가
            .padding(isPlaying ? 100 : 30)
            .background(self.isPlaying ? Color.yellow : Color.blue)
            .cornerRadius(self.isPlaying ? 60 : 10)
    }
}

버튼추가

버튼을 눌렀을때 표시될 코드는 작성했지만 정작 버튼은 만들어주지 않았습니다. 아래에 버튼을 추가해보도록 하겠습니다.

// playButton View

struct playButton: View {
    
    //isPlaying 바인딩
    @Binding var isPlaying: Bool
    
    var body: some View {
        Button(action: {
            //애니메이션과 함께
            withAnimation{
                self.isPlaying.toggle()
            }
        }) {
            //재생중이면 일시정지 버튼
            if(self.isPlaying) {
                Image(systemName: "pause.fill")
                    .foregroundColor(Color.blue)
            //재생중이지 않으면 재생버튼 생성
            } else {
                Image(systemName: "play.fill")
                    .foregroundColor(Color.black)
            }
        }
        .font(.system(size: 30))
        .padding(12)
    }
}

Playing: Bool 타입을 Binding으로 가져왔으니 위에 코드도 추가야해야 할것이 있습니다.

 

바인딩으로 가져오면 추가햐아하는건 앞 게시글에서 다뤄서 알고계시죠? :)

//musicPlay
playButton(isPlaying: $isPlaying)

현재 까지 코드

<hide/>
//musicPlay View

import SwiftUI

struct Episode {
    let song: String
    let singer: String
    let track: String
}


struct musicPlay: View {
    
    let episode = Episode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
   
   @State var isPlaying = false
    
    var body: some View {
        
            VStack {
                Text(self.episode.song)
                    .font(.title)
                    //isPlaying이 재생중이면 blue 아니면 white
                    .foregroundColor(self.isPlaying ? .blue : .white)
                
                Text(self.episode.track)
                    .font(.footnote)
                    .foregroundColor(.secondary)
                
                Text(self.episode.singer)
                
                playButton(isPlaying: $isPlaying)
                
            }
            //버튼을 눌렀을때 적용시켜줄 삼항연산자 코드 추가
            .padding(isPlaying ? 100 : 30)
            .background(self.isPlaying ? Color.yellow : Color.blue)
            .cornerRadius(self.isPlaying ? 60 : 10)
    }
}

화면 터치시 배경 변경 뷰 생성

플레이버튼을 만들어줬으니, 이제 ContentView로 가서 플레이버튼을 넣어주고 화면을 터치할 때 마다 뒷배경이 바뀌는 뷰를 만들어보겠습니다. 

//ContetView

let play = musicPlay()

struct ContentView: View {
     var body: some View {
     
            VStack{
                Spacer()
                
                musicPlay()
                    .padding(40)
                Spacer()
            }
            .frame(maxWidth: .infinity)
            .background(Color.yellow)
            .edgesIgnoringSafeArea(.all)
     }
 }

musicPlay를 가져왔고, 배경화면을 노란색으로 덮어줬습니다. 이제 버튼쪽이 아닌 버튼밖을 터치하면 배경화면을 바꾸고 싶은데 어떻게 해야할까요? 바로 아래 추가해야 할 코드들이 몇가지 있습니다.

struct ContentView: View {

    @State var index = 0
    
    //배경화면을 배열함
    private var backgroundColors = [
        Color.yellow,
        Color.blue,
        Color.green,
        Color.white
    ]

배경화면을 배열하고 index값을 @State로 추가합니다. 그리고 bakcground 쪽을 수정해줘야 합니다.

.background(backgroundColors[index])

배경을 배열에 맞는 색으로 가져왔다면, onTapGesture로 제스쳐를 추가해줘야 하겠죠?

            .onTapGesture {
                    //index가 background숫자보다 1이 낮으면 index = 0
                    if(self.index == self.backgroundColors.count-1){
                        self.index = 0
                    //그게 아니라면 index 값 + 1
                    }else {
                        self.index += 1
                }

backgroundColors.count-1 해야 할까요?

 

이유는 Swift에서는 0 부터 카운트가 시작해서, 배경색에서의 0 = 'yellow', 1 = 'blue', 2=' green', 3='white', 4 = 'empty' 입니다. 그렇기 때문에 만약 if 문 없이 self.index += 1 을 주게 되면 index값이 '4'가 되었을때 오류가 생기게 됩니다.

 

이제 화면을 실행시켜 보도록 하겠습니다.

 

 

 

읽어주셔서 감사합니다🤟