SwiftUI : #3 Understanding @Binding
Binding에 관한 첫번째 게시글을 보시려면 여기를 클릭해주세요.
Binding에 관한 두번째 게시글을 보시려면 여기를 클릭해주세요.
Understanding @Binding
저희는 이전 게시물에서 Binding
이 정확히 무엇인지 배워봤습니다. 이제 바인딩에 대해 다시 살펴보고 바인딩을 사용하여 애플리케이션을 만드는 방법을 살펴보도록 하겠습니다.
첫번째로 할것은 음악 트랙에 따라 달라지는 UI를 만들어 보겠습니다.
Xcode
프로젝트명을 'SwiftUI_Binding_music
'으로 생성하고 새로운 그룹을 만들어서 모델 안에 새로운 Swift
파일을 만듭니다.
//Episode.swift
import Foundation
struct Epicode {
let song: String
let singer: String
let track: String
}
Episode
스트럭트를 만들었으면, 이제 ContentView
에 표시되도록 코드를 추가해주겠습니다.
struct ContentView: View {
let epicode = Epicode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
var body: some View {
VStack {
Text(self.epicode.song)
.font(.title)
Text(self.epicode.track)
.font(.footnote)
.foregroundColor(.secondary)
Text(self.epicode.singer)
.foregroundColor(.secondary)
}
}
}
다음 단계는 버튼을 만드는 것입니다. 버튼을 눌렀을때 어떠한 액션을 취할 수 있도록 해주겠습니다.
일단 버튼을 만들기위해 ContentView
내부에 PlayButton
이라는 struct
를 만들고 그안에 버튼을 추가해주고 ContentView
에 추가 까지 해주도록 하겠습니다.
struct ContentView: View {
let epicode = Epicode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
var body: some View {
VStack {
...
PlayButton()
}
}
}
struct PlayButton: View {
var body: some View {
Button(action: {}) {
Image(systemName: "play.fill")
.font(.system(size: 30))
}.padding(15)
}
}
이제 Play
버튼을 눌렀을때, 재생중이라면 제목 부분의 색이 '파란색' 재생중이 아니라면 '검은색' 으로 나타나게 해주겠습니다. 여기서는 @State
와 삼항연산자를 사용해야 합니다.
let epicode = Epicode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
@State private var isPlaying = false
var body: some View {
VStack {
Text(self.epicode.song)
.font(.title)
//isPlaying이 true이면 블루, false이면 블랙 (기본값은 false로 정해놨음)
.foregroundColor(self.isPlaying ? .blue : .black)
...
}
하지만 버튼을 눌러봐도 아무런 반응을 보이지 않습니다. 그렇다면 PlayButton
쪽에도 똑같이 isPlaying
타입을 넣어줘야할까요?
안됩니다. 지금 이 View
에서 ContentView
와 PlayButton
은 완전히 다른것이라고 생각하면 됩니다.
그렇다면 어떻게해야 Button
에 isPlaying
을 넣어줄 수 있을까요? 이때 써야 하는것이 바로 'Binding
'입니다.
PlayButton
스트럭트에 @Binding var isPlaying: Bool
을 추가해주고, 버튼 액션쪽에도 코드를 작성합니다.
struct PlayButton: View {
@Binding var isPlaying: Bool
var body: some View {
Button(action: {
//isPlaying이 토글된다.
self.isPlaying.toggle()
}) {
Image(systemName: "play.fill")
.font(.system(size: 30))
.foregroundColor(self.isPlaying ? .blue : .black)
}.padding(15)
}
}
하나 더 해줘야 할것은 ContentView
에 실행시켜줬던 PlayButton()
입니다. 지금 보면 에러가 나있죠? 이유는 아직 바인딩 시켜주지 않았기 때문입니다. #2 에서 공부한것처럼 바인딩을 해줄때는 달러($)부호를 사용해야 합니다.
PlayButton(isPlaying: $isPlaying)
⭐️바인딩값으로 가져와서 사용하려면 기본 생성자를 설정해주는것이 중요합니다.
@Binding으로 가져왔다면, 그밑에 init으로 바인딩값을 추가해줘야 하는것이죠.
//예시
@Binding var isActivated: Bool
//생성자
//true값 또는 false값을 기본설정해줌
init(isActivated: Binding<Bool> = .constant(true)) {
_isActivated = isActivated
}
전체 코드
<hide/>
import SwiftUI
struct ContentView: View {
let epicode = Epicode(song: "Dynamite", singer: "BTS", track: "DayTime Version")
@State private var isPlaying = false
var body: some View {
VStack {
Text(self.epicode.song)
.font(.title)
.foregroundColor(self.isPlaying ? .blue : .black)
Text(self.epicode.track)
.font(.footnote)
.foregroundColor(.secondary)
Text(self.epicode.singer)
.foregroundColor(.secondary)
//isPlaying을 바인딩해서 가져옴
PlayButton(isPlaying: $isPlaying)
}
}
}
struct PlayButton: View {
@Binding var isPlaying: Bool
var body: some View {
Button(action: {
//isPlaying이 토글된다.
self.isPlaying.toggle()
}) {
Image(systemName: "play.fill")
.font(.system(size: 30))
.foregroundColor(self.isPlaying ? .blue : .black)
}.padding(15)
}
}
읽어주셔서 감사합니다🤟
[SwiftUI 기초/Others] - SwiftUI : #1 Binding이란 무엇인가?
[SwiftUI 기초/Others] - SwiftUI : #2 Hello Binding (Example)
[SwiftUI 기초/Others] - SwiftUI : @State, @ObservedObject / Struct를 Class로
[SwiftUI 기초/Others] - SwiftUI : State and Binding '클릭시 화면 변경'