@Binding
- SwiftUI에서 사용되는 프로퍼티 래퍼(wrapper) 중 하나로, 데이터의 양방향 바인딩을 생성하는 데 사용
- '@Binding' 을 사용하면 부모 뷰로부터 전달된 데이터를 자식 뷰에서 수정할 수 있음
- 보통 부모 뷰에서 자식 뷰로 데이터를 전달할 때, 데이터는 일방향을 전달됨
부모 뷰에서 자식 뷰로 데이터를 전달하고 나면, 자식 뷰에서 그 데이터를 수정하여 다시 부모 뷰로 전달하기 위해선 추가 작업이 필요
→ '@Binding'을 사용하면 부모 뷰와 자식 뷰 간의 데이터 흐름을 양방향으로 만듦
즉, 부모 뷰로부터 받은 데이터를 자식 뷰에서 변경하면 부모 뷰에서도 자동 변경
@State 관련 게시물 코드를 이용함 2023.08.19 - [분류 전체보기] - SwiftUI - @State
바인딩 설정 (자식 뷰)
'isActivated' 라는 바인딩을 사용하여 배경색과 패딩을 동적으로 변경
struct newView : View {
// 데이터 연동
@Binding
var isActivated: Bool
// 생성자
init(isActivated: Binding<Bool> = .constant(false)){
_isActivated = isActivated
}
var body: some View{
HStack{
Text("1!")
.foregroundColor(.blue) // 글자색 지정
.bold() // 글자 두껍게
.font(.system(size: 40)) // 글자 사이즈 지정
Text("2!")
.foregroundColor(.blue)
.bold()
.font(.system(size: 40))
Text("3!")
.foregroundColor(.blue)
.bold()
.font(.system(size: 40))
} // HStack
.background(self.isActivated ? .green : .red) // isActivated가 true이면 green, false이면 red
.padding(self.isActivated ? 30 : 10) //isActivated가 true이면 30, false이면 10
} // View
}
- 'isActivated'는 부모 뷰로부터 전달된 바인딩
- 'init(_ : Binding<T>)' 생성자를 이용하여 'isActivated' 바인딩을 초기화
- 생성자의 기본값으로 '.constant(false)'을 사용하여 기본적으로 false 값을 가지게 됨
- 마지막으로 'isActivated' 바인딩 값에 따라 HStack의 배경색과 패등을 설정
부모 뷰
struct Tutorial: View {
// @State : 값의 변화를 감지하고 뷰에 적용
@State private var isActivated : Bool = false
var body: some View {
NavigationView{
VStack{
VStack{
newView(isActivated: $isActivated)
newView(isActivated: $isActivated)
newView(isActivated: $isActivated)
} // VStack
......
- 자식 뷰인 'newView'를 가져올 때 'newView'는 'isActivated' 바인딩을 전달해줘야 함
- '$isActivated' : 'isActivated' 변수에 대한 바인딩을 생성하는 역할
- 생성된 바인딩은 'newView' 내부에서 'isActivated' 값을 읽거나 변경하는 데 사용
네비게이션 뷰로 이동할 때의 바인딩
이동할 뷰
// 이동할 뷰
struct myTextView : View{
// 데이터 연동
@Binding
var isActivated: Bool
// 생성자
init(isActivated: Binding<Bool> = .constant(false)){
_isActivated = isActivated
}
// 배경색 배열 인덱스
@State var index = 0
// 배경색 배열
let backgroundColorArray = [Color.red, Color.blue, Color.green, Color.yellow, Color.brown]
var body: some View{
VStack{
// 공간 추가
Spacer()
Text("배경 아이템 인덱스 \(self.index)")
.font(.system(size: 30))
.fontWeight(.bold)
// 배경을 전체로 설정
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 100)
Text("isActivated : \(String(self.isActivated))")
.font(.system(size: 30))
.fontWeight(.bold)
.foregroundColor(self.isActivated ? .yellow : .gray)
.background(.black)
Spacer()
}
.......
- '@Binding' 설정 및 초기화
- Text를 추가하여 바인딩된 'isActivated'를 String으로 바꾸어 화면에 출력
- 'isActivated'의 값이 true이면 배경색이 노란색, false이면 회색으로 설정
부모 뷰
......
// destination : 이동하고자 하는 뷰
NavigationLink(destination: myTextView(isActivated: $isActivated)){
Text("네비게이션")
.fontWeight(.heavy)
.font(.system(size:30))
.padding()
.background(.yellow)
.foregroundColor(.white)
.cornerRadius(30)
}
.padding(30)
......
- NavigationLink를 통해 이동하고자 하는 뷰인 'myTextView'를 호출할 때 'isActivated' 값을 바인딩함
전체 코드
메인 뷰
import SwiftUI
struct Tutorial: View {
// @State : 값의 변화를 감지하고 뷰에 적용
@State private var isActivated : Bool = false
var body: some View {
NavigationView{
VStack{
VStack{
newView(isActivated: $isActivated)
newView(isActivated: $isActivated)
newView(isActivated: $isActivated)
} // VStack
// isAcitved가 true이면 50, false면 10으로 패딩 지정
.padding(isActivated ? 50 : 10)
// isAcitved가 true이면 .yellow, false면 .green
.background(isActivated ? .yellow : .green)
// 탭 제스처 추가
.onTapGesture {
// 애니메이션 추가
withAnimation{
// toggle() true이면 false로 false면 true로 변경
self.isActivated.toggle()
}
}
// destination : 이동하고자 하는 뷰
NavigationLink(destination: myTextView(isActivated: $isActivated)){
Text("네비게이션")
.fontWeight(.heavy)
.font(.system(size:30))
.padding()
.background(.yellow)
.foregroundColor(.white)
.cornerRadius(30)
}
.padding(30)
}
} // NavigationView
} // body
}
서브 뷰
struct newView : View {
// 데이터 연동
@Binding
var isActivated: Bool
// 생성자
init(isActivated: Binding<Bool> = .constant(false)){
_isActivated = isActivated
}
var body: some View{
HStack{
Text("1!")
.foregroundColor(.blue) // 글자색 지정
.bold() // 글자 두껍게
.font(.system(size: 40)) // 글자 사이즈 지정
Text("2!")
.foregroundColor(.blue)
.bold()
.font(.system(size: 40))
Text("3!")
.foregroundColor(.blue)
.bold()
.font(.system(size: 40))
} // HStack
.background(self.isActivated ? .green : .red) // isActivated가 true이면 green, false이면 red
.padding(self.isActivated ? 30 : 10) //isActivated가 true이면 30, false이면 10
} // View
}
이동할 뷰
// 이동할 뷰
struct myTextView : View{
// 데이터 연동
@Binding
var isActivated: Bool
// 생성자
init(isActivated: Binding<Bool> = .constant(false)){
_isActivated = isActivated
}
// 배경색 배열 인덱스
@State var index = 0
// 배경색 배열
let backgroundColorArray = [Color.red, Color.blue, Color.green, Color.yellow, Color.brown]
var body: some View{
VStack{
// 공간 추가
Spacer()
Text("배경 아이템 인덱스 \(self.index)")
.font(.system(size: 30))
.fontWeight(.bold)
// 배경을 전체로 설정
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 100)
Text("isActivated : \(String(self.isActivated))")
.font(.system(size: 30))
.fontWeight(.bold)
.foregroundColor(self.isActivated ? .yellow : .gray)
.background(.black)
Spacer()
}
.background(self.backgroundColorArray[self.index])
.onTapGesture {
// index가 backgroundColorArray의 배열 수보다 커지면 index를 0으로 설정
if (index == backgroundColorArray.count - 1){
index = 0
}
else{
index += 1
}
} // onTopGesture
}
}
참고) https://www.youtube.com/watch?v=dCDCmNkKkWk&list=PLgOlaPUIbynqyJHiTEv7CFaXd8g5jtogT&index=3
'SwiftUI' 카테고리의 다른 글
SwiftUI - SwiftUI 모드로 Xcode 이용 (1) | 2024.01.07 |
---|---|
SwiftUI - 개요 (0) | 2024.01.07 |
SwiftUI - @State (0) | 2023.08.19 |
SwiftUI - 튜토리얼 (0) | 2023.08.17 |
SwiftUI - Container Views (VStack, HStack) (0) | 2023.07.28 |