ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • @State, @Binding, @ObservedObject, @EnvironmentObject
    스유를 써봐유! 2021. 9. 5. 02:40
    728x90
    반응형

     

     

     

     

     

     

    안녕하세요. iOS 개발자 에이든입니다!👦🏻

     

     

     

    요즘 앱 개발은 거의 SwiftUI만 쓰고 있는데,

    확실히 이전에 ViewController를 활용할 때 보다 좋은 점이 너무 많더라구요ㅎㅎ (사..사랑해 애플..)

    그중 @State. @Binding이 너무 편해서 공유해드리려고 합니다!

     

     바로 스무스하게~ 들어갑니다!

     


     

     

     


    @State, @Binding

    • @State
    1. 상태로 선언한 모든 속성의 저장소관리합니다.
    2. 상태가 변경되면 View를 다시 그립니다.
    3. Value Type이 아니고, Value를 변경하는 수단입니다. 값에 접근하려면 wrapValue 속성 값을 반환하는 변수를 사용해서 접근을 해야 합니다!
    4. View의 내부 또는 View에서 호출한 Method에서만 Access 해야 하기 때문에 private으로 선언해야 합니다.
    5. 다른 View에 상태 속성을 전달하려면 $를 앞에 붙여서 변수 이름을 사용합니다.

    struct ContentView: View {
    
        @State var textBackgroundColorIsBlack: Bool = true
        
        var body: some View {
            NavigationView {
                VStack {
                    NavigationLink("Move", destination: InternalView(textBackgroundColorIsBlack: $textBackgroundColorIsBlack))
                        .foregroundColor(.white)
                        .frame(width: 100, height: 50, alignment: .center)
                        .background(textBackgroundColorIsBlack ? Color.black : Color.red)
                }
                .navigationBarTitle("Home", displayMode: .automatic)
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }​

     

    • @Binding
    1. @State로 선언된 속성과 양방향으로 연결되는 거라고 생각하시면 됩니다.
    2. @Binding으로 선언된 값이 바뀌면 이를 전달했던 @State도 같이 값이 바뀌게 됩니다.

    struct InternalView: View {
        @Binding var textBackgroundColorIsBlack: Bool
        
        var body: some View {
            VStack {
                Spacer()
                Button("Change Color", action: {
                    textBackgroundColorIsBlack.toggle()
                })
                Spacer()
            }
        }
    }
    
    struct InternalView_Previews: PreviewProvider {
        static var previews: some View {
            InternalView(textBackgroundColorIsBlack: .constant(true))
        }
    }​

     

     

     

    해당 코드들을 돌리면 아래와 같은 결과가 나와요!

     

     

     

     

     

     


    @ObservedObject, @EnvironmentObject

    • @ObservedObject
    1. 관찰 가능한 개체를 Subscribe 하고 관찰 가능한 개체가 변하면 이에 따라 처리가 가능합니다.
    2. @State와 거의 유사하고, Custom Type을 사용할 때 사용하면 좋습니다.
    3. @ObservedObject를 사용하기 위해서는 ObservableObject Protocol을 채택해야 합니다.

    class TextBackground: ObservableObject {
        @Published var isBlack: Bool = true
    }​

     

    • @EnvironmentObject
    1. 부모 또는 상위 View에서 제공하는 관찰 가능한 객체에 대한 Property Wrapper
    2. @State - @Binding의 관계와 @ObservedObjrct - @EnvironmentObejct는 거의 같다고 보시면 됩니다.
    3. 상위 View에서 environmentObject(_:) Method를 호출하여 모델 객체를 반드시 설정해야 합니다.

    - 아래 코드를 동작시키면 @State, @Binding에서 나온 예제와 같은 결과가 나옵니다!
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            
        // environmentObject(_:) Method를 호출하여 모델 객체를 반드시 설정!!!!
        let contentView = ContentView().environmentObject(TextBackground())
    
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }​
    struct ContentView: View {
        
        @EnvironmentObject var textBackground: TextBackground
        
        var body: some View {
            NavigationView {
                VStack {
                    NavigationLink("Move", destination: InternalView())
                        .foregroundColor(.white)
                        .frame(width: 100, height: 50, alignment: .center)
                        .background(textBackground.isBlack ? Color.black : Color.red)
                }
                .navigationBarTitle("Home", displayMode: .automatic)
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    struct InternalView: View {
    
        @EnvironmentObject var textBackground: TextBackground
        
        var body: some View {
            VStack {
                Spacer()
                Button("Change Color", action: {
                    textBackground.isBlack.toggle()
                })
                Spacer()
            }
        }
    }
    
    struct InternalView_Previews: PreviewProvider {
        static var previews: some View {
            InternalView()
        }
    }

     


     

    자 오늘은 @State, @Binding, @ObservedObject, @EnvironmentObject에 대해 알아보았습니다!

    이 녀석들 덕분에 다른 상태에 따라 서로 다른 View가 바뀌게 하는 것이 훨씬 쉬워진 것 같고, 코드도 훨씬 깔끔해졌습니다ㅋㅋ

    SwiftUI로 넘어오며 간단해진 것들은 이 녀석들이 끝이 아니랍니다. 다른 녀석들도 감동 그 자체..

    다음 시간을 기대해주세요!!

     

     

     

    혹시라도 부족하거나 잘못된 부분 그리고 질문 있으시면 언제든 댓글 부탁드려요! 감사합니다!👦🏻👋🏻

    728x90
    반응형

    '스유를 써봐유!' 카테고리의 다른 글

    @AppStorage와 UserDefaults  (0) 2021.10.17
    NavigationView, NavigationLink  (0) 2021.09.26
    Text Attributed  (1) 2021.09.13
    Custom TabBar  (0) 2021.08.15
    Prologue  (1) 2021.08.01

    댓글

Designed by Tistory.