Notice
Recent Posts
Recent Comments
Link
ยซ   2024/07   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
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
Archives
Today
Total
๊ด€๋ฆฌ ๋ฉ”๋‰ด

lgvv98

[SwiftUI 3.0] State/ Binding / EnvironmentObject ๋ณธ๋ฌธ

apple/๐Ÿš SwiftUI & Combine

[SwiftUI 3.0] State/ Binding / EnvironmentObject

๐Ÿฅ• ์บ๋Ÿฟ๋งจ 2022. 5. 19. 15:10

State/ 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
Comments