본문 바로가기
IOS - Swift/SwiftUI

[iOS/SwiftUI] Property Wrapper - 기본편

by 게게겍 2024. 3. 29.

스유를 시작하면서 사용한 속성들을 정리해보았다.

정리를 시작하면서 든 생각은 엥 사실상 Combine 아니냐 라는 생각이 들었지만 제대로 컴바인과 Rx도 해본적이 없기에..

일단 전체적으로 정리를 해보고 추후 깊게 하나하나 파볼 생각이다.

Property Wrapper

@State - 뷰의 상태를 저장하는 속성

스유에서 상태를 처리하는 방법

뷰의 상태를 저장하는 프로퍼티로 상태관리 주체는 해당 뷰

기본적으로 private 선언이기에 다른 뷰와 값을 소통하려면 Binding을 이용

값이 변경될때마다 UI 업데이트

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

여기에서 버튼값을 뷰의 상태를 위해 사용되고 이를 토글로 사용할 수 있다. 이는 isPlaying의 상태값이 변경되는 것이고 이렇게 UI가 변경되게 된다

@Binding

  • 뷰와 상태를 바인딩 하는 방법
  • 상위 @State변수를 전달받아 하위 뷰에서 캐치해 변화감지 및 연결
  • Binding은 다른 뷰가 소유한 속성을 연결하기에 소유권 및 저장공간이 없음
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: SisPlaying) //binding
    Binding
    }
    }
    }

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

ObservableObject

  • 클래스 프로토콜로 관찰하는 어떠한 값이 변경되면 변경사항을 알려줌
  • 뷰에서 인스턴스 변화를 감시하기 위해 뷰모델 객체로 생성할때 사용할 수 있음
class Contact: ObservableObject {
  @Published var name: String
  @Published var age: Int
  
  init(name: String, age: Int) {
    self.name = name
    self.age = age
  }
  
  func haveBirthday() -> Int {
    age += 1
    return age
  }
}

let john = Contact(name: "John Appleseed", age: 24)
cancellable = john.objectWillChange
  .sink { _ in
    print("\\(john.age) will change")
  }
print(john.haveBirthday())

@Published

  • observableObject를 구현한 클래스 내에서 프로퍼티 선언시 사용
  • @Publish로 선언된 프로퍼티를 뷰에서 관찰할 수 있음
  • ObservableObject의 ObjectWillChange.send() 기능을 @Published 프로퍼티가 변경되면 자동으로 호출

@ObervableObject

뷰에서 ObervableObject 타입의 인스턴스 선언시 사용

ObervableObject의 값이 업데이트 되면 뷰를 업데이트

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

struct ContentView: View {
  @ObservedObject var user: User

  var body: some View {
    Button("Plus Age") {
      user.age += 1
    }
  }
}

@StateObject

뷰에서 ObervableObject 타입의 인스턴스 선언시 사용

뷰마다 하나의 인스턴스를 생성하며, 뷰가 사라지기 전까지 같은 인스턴스 유지

@ObervableObject의 뷰 렌더링시 인스턴스 초기화 이슈 해결위함

매번 인스턴스가 새롭게 생성되는 것처럼 외부에서 주입받는 경우가 아닌 최초 생성선언시에 @StateObject 를 사용하는것이 적절한 방법

@Environment

미리 정의되어 있는 시스템 공유 데이터

사용하려는 공유 데이터의 이름을 KeyPath로 전달하여 사용

시스템 공유 데이터는 가변하기에 var로 선언 필요

뷰가 생성되는 시점에 값이 자동으로 초기화됨

struct ContentView: View {
  @Environment(\\.colorScheme) var colorScheme
  
  var body: some View {
    Text("Hello, world!")
      .foregroundColor(colorScheme == .dark ? .white : .black)
  }
}

@EnvironmentObject

ObervableObject를 통해 구현된 타입의 인스턴스를 전역적으로 공유하여 사용

앱 전역에서 공통으로 사용할 데이터를 주입 및 사용

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("Click Me for plus age")
    }
    SubView()
  }
}

struct SubView: View {
  @EnvironmentObject var info: Info

  var body: some View {
    Button(action: {
      self.info.age -= 1
    }) {
      Text("Click Me for minus age")
    }
  }
}

 

 

 


출처

https://fastcampus.co.kr/dev_online_ios

 

네카라쿠배 5개 앱으로 완성하는 iOS 앱 개발 초격차 패키지 Online. | 패스트캠퍼스

네카라쿠배 출신 강사님들 먼저 클론코딩 진행 중! 네카라쿠배 iOS 멘토부터 WWDC Scholarship Winner까지, iOS 전문가 7인과 함께 네카라쿠배 5개 앱 주요 기능 100% 클론코딩하고 압도적 앱 개발 포트폴

fastcampus.co.kr

 

'IOS - Swift > SwiftUI' 카테고리의 다른 글

[iOS/SwiftUI] LunchScreen 적용하기  (0) 2023.12.31