본문 바로가기

Apple Developer/Swift

SwiftUI property wrapper 정리 (swift @ 사용법)

728x90
반응형

처음에 이 @ 들을 잘 몰라서 강의 듣는 것 조차 어려웠다. 

 

@State @Binding

ObservableObject (protocol 임)

@Published

@ObsevedObject

@StateObject

@Environment

@EnvironmentObject

 

1. @State 는 해당 뷰에서 상태를 저장함, 그 값이 변경될 때마다 UI 가 업데이트 된다. 

다른 뷰에서 사용하려면 다음에 나오는 Binding 을 써야 함

struct ContentView: View {
	@State private var isPlaying: Bool = false
    
    var body: some View {
    	Button(isPlaying ? "Pause":"Play"){
        	isPlaying.toggle()
        }
    }
}

 

2. @Binding 뷰와 상태를 바인딩, 상위 뷰에서 하위 뷰에 @State 값을 전달 받아 연결함 (변화를 감지함)

 

// MARK: - 상위뷰
struct PlayerView: View {
    var episode: Episode
    @State private var isPlaying: Bool = false
    
    var body: some View {
        VStack {
            Text(episode.title)
                .foregroundStyle(isPlaying ? .primary: .secondary)
            PlayButton(isPlaying: $isPlaying) // $ 활용하여 참조
        }
    }
}

// MARK: - 하위뷰
struct PlayButton: View{
    @Binding var isPlaying: Bool
    
    var body: some View {
        Button(isPlaying ? "Pause" : "Play") {
            isPlaying.toggle()
        }
    }
}

 

3. ObservableObject 이 것은 클래스 프로토콜인데 관찰하는 값이 변경되면 변경 사항을 알려준다 
    뷰에서 인스턴스 변화를 감시하기 위해 주로 뷰모델 객체로 생성할 때 사용할 수 있다. 

 

4. @Published 로 선언하면 뷰에서 해당 값을 관찰할 수 있음

 

5. @ObservedObject 는 뷰에서 ObservableObject타입의 인스턴스를 선언해 사용할 때 사용 

ObservableObject의 값이 업데이트 되면 뷰도 업데이트 함 

 

위 세가지를 한번에 작성 하면 아래와 같다

// MARK: - 3. ObservableObject 인스턴스
class User: ObservableObject {
    @Published var age = 10
}

// MARK: - 5. 뷰에서 사용하기
struct ContentView: View {
    @ObservedObject var user: User
    
    var body: some View {
        Button("Plus Age"){
            user.age += 1
        }
    }
}

 

6. @StateObject 는 @ObservedObject와 거의 동일. 뷰마다 하나의 인스턴스를 생성함, 최초 생성 시에 사용하는 것이 좋다. 

 

7. @Environment 미리 정의 되어 있는 시스템 공유 데이터 임. 사용하려는 공유 데이터의 이름을 KeyPath(\.)로 전달하여 사용 해야 됨

시스템 공유 데이터는 변하기 때문에 var 로 선언해야 함 

 

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme
    
    var body: some View {
        Text("Dark Mode Check")
            .foregroundColor(colorScheme == .dark ? .white : .black)
        // dark 모드이면 글자를 흰색으로 함
    }
}

 

8. @EnvironmentObject 는 앱 전역에서 공통으로 사용할 데이터를 주입할 때 사용, 너무 자주 사용하면 데이터 의존성이 앱 전체로 퍼져 영향도가 커짐, Test 만들기도 힘듬

 

class Info: ObservableObject {
    @Published var age = 10
}

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            MainView()
                .EnvironmentObject(Info())
        }
    }
}

struct MainView: View {
    @EnvironmentObject var info: Info
    
    var body: some View {
        Button(action: {
            self.info.age += 1
        }) {
            Text("Plus Age")
        }
        SubView()
    }
}

struct SubView: View {
    @EnvironmentObject var info: Info
    
    var body: some View {
        Button(action: {
            self.info.age -= 1
        }) {
            Text("Minus Age")
        }
    }
}

 

이걸 알아야 SwiftUI를 할 수 있음

 

728x90
반응형