์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- node.js
- tableView
- BOJ
- Xcode
- SwiftUI
- raywenderlich
- ios
- Kuring
- ํ๋ก๊ทธ๋๋จธ์ค
- Flutter
- visionOS
- reactorkit
- BFS
- combine
- TCA
- MVVM
- designpattern
- CollectionView
- SnapKit
- Lv2
- realm
- XCTest
- ๋ฐฑ์ค
- UIKit
- RxSwift
- swift
- ํจ์คํธ์บ ํผ์ค
- rxcocoa
- Swfit
- arkit
- Today
- Total
lgvv98
[SwiftUI 3.0] State/ Binding / EnvironmentObject ๋ณธ๋ฌธ
[SwiftUI 3.0] State/ Binding / EnvironmentObject
๐ฅ ์บ๋ฟ๋งจ 2022. 5. 19. 15:10State/ Binding / EnvironmentObject
โ ์ค๋์ ์ด ์ธ๊ฐ์ง์ ๋ํด์ ์์๋ณด์.
@State: ๊ฐ์ด ๋ณ๊ฒฝ๋์์ ๋, ํ๋ฉด์ ๋ค์ ๋ณด์ฌ์ฃผ์ด์ผ ํ ๋.
@Binding: state๊ฐ์ ์น๊ตฌ๋ค์ view - view ๊ฐ์ ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ.
@EnvironmentObject: parent๋ก child(ํ์) view์ ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ.
์ฐ์ State์ Binding์ ๋ํด์ ์ดํดํด๋ณด์.
โ ์์ ์ฝ๋
struct FirstView: View {
@State var appTitle = tabIndex.first.rawValue
@State var count = 0
enum tabIndex: String {
case first = "1๋ฒ๋ทฐ ์
๋๋ค."
case second = "2๋ฒ๋ทฐ ์
๋๋ค."
case third = "3๋ฒ๋ทฐ ์
๋๋ค"
}
var body: some View {
TabView {
VStack {
Text("์ค์ํํธ ์ ์์ด๋ฅผ ์ ๋ณตํด๋ด
์๋ค. count: \(count)")
.padding()
Button { // action
count += 1
} label: {
Text("์นด์ดํธ ์
")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
.tabItem { Label("1๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
SecondView(count: $count)
.tabItem { Label("2๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
ThirdView(count: $count)
.tabItem { Label("3๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
}
}
}
โ SecondView (ThirdView๋ ์ฝ๋๊ฐ ๊ฐ์ต๋๋ค.)
import SwiftUI
struct SecondView: View {
@Binding var count: Int
init(count: Binding<Int> = .constant(0)) {
_count = count
}
var body: some View {
VStack {
Text("2๋ฒ๋ทฐ์
๋๋ค. \(count)")
Button { // action
count += 1
} label: {
Text("์นด์ดํธ ์
")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
}
}
๐ 1๋ฒ๋ทฐ(@State๋ฅผ ๊ฐ๊ณ ์์)์์ ์นด์ดํธ์ ์ํ๊ณ 2๋ฒ๋ทฐ๋ก ์ด๋ํ๋ฉด 1,2๋ฒ ๋ทฐ ๋ชจ๋ ์นด์ดํธ๊ฐ ๋ฌ๋ผ์ง๋๋ค.
๐ ๊ทธ๋ฐ๋ฐ @Binding์ผ๋ก ์ฒ๋ฆฌ๋์ด ์๋ 2๋ฒ๋ทฐ์์ ์นด์ดํธ ์ ์ํ๊ณ 1๋ฒ๋ทฐ๋ก ๊ฐ๋ค๋ฉด?
-> ์ด ๊ฒฝ์ฐ์๋ ์นด์ดํธ๊ฐ ๋ฌ๋ผ์ง๋๋ค.
๐ ๊ทธ๋ ๋ค๋ฉด 2๋ฒ๋ทฐ์์ ์นด์ดํธ๋ฅผํ๊ณ 3๋ฒ๋ทฐ๋ก ์ด๋์ ๋ฐ๋ก ํ๋ค๋ฉด?
-> ์ด ๊ฒฝ์ฐ์๋ ์นด์ดํธ๊ฐ ๋ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค.
State์ Binding์ ๋ทฐ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ฒ ํด์ค๋๋ค.
State์ ๊ฑธ๋ฆฐ ๋์ผํ Binding์ ์ ๋ถ ๋ฐ์๋๋ค๊ณ ์ดํดํ ์ ์์ต๋๋ค.
๋ค์์ผ๋ก EnvironmentObject์ ๋ํด์ ์์๋ด ์๋ค.
โ @State์ ๊ฒฝ์ฐ์๋ ๋ทฐ ์ ์ฒด๋ฅผ ๋ค์ ๊ทธ๋ฆฌ๋ ๋์์ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด์ row๊ฐ 10์ธ List๋ฅผ ๊ทธ๋ ธ๋ค๊ณ ๊ฐ์ ํฉ์๋ค. row๋ฅผ ํด๋ฆญํ๋ฉด ํด๋น row์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ์ฌ UI๋ฅผ ๊ฐฑ์ ํ๋ค๊ณ ์๊ฐํฉ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ค์ ๋ค ๊ทธ๋ ค์ผํ๋๊น ๋น์ฉ์ด ๋ ํฝ๋๋ค... ํด๋น row๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ํจ์ฌ ๋ ํจ์จ์ ์ด๊ฒ ์ฃ ?
๋ํ, Combine์ด๋ผ๋ ๊ฐ๋ ์ ๋์ ํด์ผ ํ๋๋ฐ, ์ด ๊ฒฝ์ฐ์๋ RxSwift๋ฅผ ๊ณต๋ถํ๋ ๊ธฐ์ต์ ์ด๋ฆฌ๋ฉด ์ฝ๊ฒ ์ ๊ทผํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ๋๋ฉด์ ํ์์์ ๊ตฌ๋ ์ ๊ฐ๋ ์ด ์๊ฒจ์ ํ์๋ทฐ ์ ์ฒด๋ฅผ ๋์์ ์ปจํธ๋กค ํ ์ ์๊ฒ ๋๋ค.
์ ์ดํด๊ฐ ์๊ฐ๋ค๋ฉด ์ฝ๋๋ฅผ ๋ณด์!
๐ ์ฌ์ฉ๋ฒ ์ ๋ฆฌ
1. ObservableObject๋ฅผ ViewModel์์ ์์๋ฐ๊ธฐ
2. ํด๋น View์ environment๋ฅผ ์ฌ์ฉํ์ฌ ViewModel์ ๋ฃ์ด์ฃผ๊ธฐ
โ SwiftUI_PracticeApp
@main
struct SwiftUI_PracticeApp: App {
var body: some Scene {
WindowGroup {
// viewModel์ ๋ฃ์ด์ค๋ค.
FirstView().environmentObject(ViewModel())
}
}
}
โ ViewModel
import Foundation
import Combine
// ObservableObject๋ ์ด๋ฒคํธ ์ฒ๋ฆฌ์ ๋ํ ๊ฒ์ ์์
class ViewModel: ObservableObject {
@Published var appTiltle = ""
}
โ FirstView
import SwiftUI
struct FirstView: View {
@EnvironmentObject var viewModel: ViewModel
@State var appTitle = tabIndex.first.rawValue
@State var count = 0
enum tabIndex: String {
case first = "1๋ฒ๋ทฐ ์
๋๋ค."
case second = "2๋ฒ๋ทฐ ์
๋๋ค."
case third = "3๋ฒ๋ทฐ ์
๋๋ค"
}
var body: some View {
TabView {
VStack {
Text(appTitle)
Text("์ค์ํํธ ์ ์์ด๋ฅผ ์ ๋ณตํด๋ด
์๋ค. count: \(count)")
.padding()
Button { // action
count += 1
viewModel.appTiltle = "\(appTitle)\(count)"
} label: {
Text("์นด์ดํธ ์
")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
.tabItem { Label("1๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
SecondView(count: $count)
.tabItem { Label("2๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
ThirdView(count: $count)
.tabItem { Label("3๋ฒ ๋ทฐ", systemImage: "pencil.circle") }
}
.onReceive(viewModel.$appTiltle) { appTitle in
print("Receieved", appTitle)
self.appTitle = appTitle
}
}
}
โ SecondView
import SwiftUI
struct SecondView: View {
@EnvironmentObject var viewModel: ViewModel
@Binding var count: Int
@State var appTitle: String = ""
init(count: Binding<Int> = .constant(0)) {
_count = count
}
var body: some View {
VStack {
Text(viewModel.appTiltle)
Text("2๋ฒ๋ทฐ์
๋๋ค. \(count)")
Button { // action
count += 1
viewModel.appTiltle = "\(appTitle)\(count)"
} label: {
Text("์นด์ดํธ ์
")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}.onReceive(viewModel.$appTiltle) {
self.appTitle = $0
}
}
}
}
onReceiveํ๊ณ ์๊ธฐ ๋๋ฌธ์ 12, 1213, 121314 ... ์ด๋ฐ์์ผ๋ก UI์ ๋ฐ์๋๋ค.
โ ThirdView
import SwiftUI
struct ThirdView: View {
@EnvironmentObject var viewModel: ViewModel
@Binding var count: Int
@State var appTitle: String = ""
init(count: Binding<Int> = .constant(0)) {
_count = count
}
var body: some View {
VStack {
Text(viewModel.appTiltle)
Text("3๋ฒ๋ทฐ์
๋๋ค. \(count)")
.padding()
Button { // action
count += 1
viewModel.appTiltle = "\(appTitle)\(count)"
} label: {
Text("์นด์ดํธ ์
")
.foregroundColor(.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
}
}
์ฌ๊ธฐ์๋ onReceive๊ฐ ์์ด์ ์ด์ ๊ฐ์ ์ฒ์์ ํ๋ฒ๋ง ๊ฐ์ ธ์ค๊ณ ์ดํ์ ์ง์ํด์ ๊ฐ์ ๋ฐ์๋ค์ด์ง ๋ชปํ๋ค.
๋ฐ๋ผ์ ์นด์ดํธ์ ์ ๋๋ฌ๋ appTitle์ด ๋น ์ํ๋ผ์ 12, 13, 14 .. ์ด๋ฐ์์ผ๋ก UI์ ๋ฐ์๋๋ค.
'apple > ๐ SwiftUI & Combine' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SwiftUI] ButtonStyle (0) | 2022.05.23 |
---|---|
[SwiftUI] QRcodeReader (0) | 2022.05.23 |
[SwiftUI] TabView + CustomTabView (0) | 2022.05.19 |
[SwiftUI] GeometryReader (0) | 2022.05.19 |
[SwiftUI] NavigationView (0) | 2022.05.18 |