view의 environment 로부터 값을 읽어오는 프로퍼티 래퍼다.

 

Environment Modifiers

environment(Object): 이 modifier는 environment에서 관찰 가능한 객체를 읽을 수 있는 environment 프로퍼티를 만든다. 인자로 받은 Object는 view들과 공유하며 변화를 감지할 수 있는 참조 객체다.

environment(EnvironmentValues(KeyPath), Value): environment 프로퍼티를 만들어 명시된 key path 을 읽는다.

 

environment는 뷰가 유저의 데이터, database, 앱 상태에 접근할 수 있게 해준다, 하지만 SwiftUI는 environment를 뷰를 구성하는데에도 사용하기도 한다. 다음 SwiftUI에 포함된 프로퍼티들은 뷰를 구성하기 위한 목적으로 존재한다.

  • colorCheme: 이 프로퍼티는 인터페이스의 appearance를 설정하거나 반환 및 설정할 수 있다. 이것은 enumeration 타입인ColorScheme 으로 light와 dark 값을 갖고 있다
  • dynamicTypeSize: 이 프로퍼티는 텍스트의 사이즈를 반환 및 설정할 수 있다. 이것도 enumeration 타입으로 large, medium, small, xLarge, xSmall, xxLarge, xxxLarge 가 있다. iOS 설정 앱에서 디스플레이 및 밝기 색션으로 이동하면 텍스트 크기라는 옵션으로 설정가능
  • font: 이 프로퍼티는 말 그대로 font를 의미한다.
  • accessibilityEnabled: 이 프로퍼티는 Boolean 값을 반환 및 설정할 수 있다. 설정 앱에서 접근성 섹션으로 이동하면 사용자가 시스템 전체의 접근성 설정을 조정할 수 있는데 이 접근성의 활성화를 의미한다.
  • layoutDirection: 이 프로퍼티는 앱의 레이아웃을 반환 및 설정할 수 있다. 이것은 enumeration 타입으로 leftToRight과 rightToLeft 값으로 되어 있다. 아랍어나 히브리어와 같이 오른쪽에서 왼쪽으로 텍스트가 표시되는 언어에서는 레이아웃 방향을 .rightToLeft 로 설정해야하기 때문
  • calendar: 이 프로퍼티는 뷰에서 사용하는 캘린더를 dates로 가공하여 반환 및 설정할 수 있다. 값은 Calendar 타입이다.
  • locale: 이 프로퍼티는 지역 데이터를 처리할 수 있도록 뷰에 제공되는 지역 값을 반환하거나 설정할 수 있다. Locale 타입이다.
  • timeZone: 이 프로퍼티는 time zone을 설정 및 반환한다. 이것은 날짜와 시간을 계산하여 뷰에서 사용할 수 있게하며 TimeZone 타입이다.

 

 

Environment 프로퍼티 래퍼를 사용하여 뷰의 environment 에 저장된 값을 읽어올 수 있다. 프로퍼티 선언의 EnvironmentValues 키 경로를 사용하여 읽을 값을 나타냅니다. 예를 들어 프로퍼티를 만들어 key path(키 경로)가 colorScheme 인 colorscheme 프로퍼티의 값을 읽을 수 있습니다.

@Environment(\.colorScheme) var colorScheme: ColorScheme

 

선언된 프로퍼티의 wrappedValue에서 읽은 colorScheme 값으로 뷰의 내용을 조건문으로 만들 수 있습니다. 다른 프로퍼티 래퍼와 마찬가지로, 프로퍼티를 직접 참조하여 래핑된 값에 접근합니다.

if colorScheme == .dark { // Checks the wrapped value.
    DarkContent()
} else {
    LightContent()
}

 

만약 값이 바뀌게 된다면 SwiftUI는 @Environment(\.colorScheme) 인 값들이 사용되는 모든 뷰를 업데이트한다. 예를 들어 위에 코드처럼 사용자가 Appearance settings를 바꾸게 되었을 때를 예시로 들 수 있습니다.

 

다음은 @Environment(\.colorScheme)의 값을 변경하는 코드입니다.

import SwiftUI

struct ContentView: View {
   var body: some View {
      Text("Hello World")
         .foregroundColor(Color("MyColor"))
   }
}
#Preview {
   ContentView()
      .environment(\.colorScheme, .dark)
}

왼쪽(Dark) 오른쪽(Light)

다음은 사용자가 직접 설정을 통해서 Appearence를 Dark 모드로 바꿨을때와 Light 모드로 바꿨을때 아이콘의 색상이 바뀌도록 한 예제 코드다.

import SwiftUI

struct ContentView: View {
   @Environment(\.colorScheme) var mode

   var body: some View {
      Image(systemName: "trash")
         .font(Font.system(size: 100))
         .foregroundColor(mode == .dark ? Color.yellow : Color.blue)
         .symbolVariant(mode == .dark ? .fill : .circle)
   }
}
#Preview {
   ContentView()
}

 

Environment 프로퍼티 래퍼를 읽는데 사용할 수 있지만 environment value를 설정하는데 사용할 수는 없다. SwiftUI는 시스템 설정을

기반으로 일부 environment values를 자동적으로 업데이트하고 다른 사람들에게 합리적인 기본값을 제공한다. 또한 environment(_:_:) view modifier를 사용하여 커스텀 environment value를 정의할 수 있다.

SwiftUI가 제공하는 environment values의 전체 목록은 EnvironmentValues structure의 프로퍼티를 참조해야한다. 사용자 지정 environment values를 만드는 방법에 대한 정보는 EnvironmentKey 프로토콜을 참조하면 된다.

Get an obserable object

Environment 는 뷰의 environment로부터 observable object 를 가져오는데 사용할 수 있다. observable object는 반드시 Observable 프로토콜을 준수해야하며 앱은 반드시 object 자체 또는 key path(키 경로)를 사용하여 environment를 설정해야한다.

 

객체 자체를 사용하여 environment에서 객체를 설정하려면, environment(_:) 수정자를 사용하세요

@Observable
class Library {
    var books: [Book] = [Book(), Book(), Book()]


    var availableBooksCount: Int {
        books.filter(\.isAvailable).count
    }
}


@main
struct BookReaderApp: App {
    @State private var library = Library()


    var body: some Scene {
        WindowGroup {
            LibraryView()
                .environment(library)
        }
    }
}

 

obserable 객체를 스스로의 타입으로 가져오기 위해서 프로퍼티를 만들고 Environment 프로퍼티 래퍼의 객체의 타입에 제공한다.

struct LibraryView: View {
    @Environment(Library.self) private var library


    var body: some View {
        // ...
    }
}

 

기본적으로  environment 에서 객체를 읽어오는 경우, 객체 유형을 키로 사용할 때 옵셔널이 아닌 객체를 반환한다. 이 기본 동작은 현재 계층에서 해당 유형의 옵셔널이 아닌 인스턴스를 이전에 environment(_:) modifier 를 사용하여 저장했다고 가정합니다. 만약 뷰가 현재 environment에서 해당 객체를 유형을 통해 가져오려고 시도하고 해당 객체가 환경에 없으면 SwiftUI는 예외를 throw 한다.

 

만약 객체가 environment에 있는 것을 보장할 수 없는 경우, 다음 코드에서 보여지는 것과 같이 해당 객체의 선택적(optional) 버전을 검색합니다. 객체가 환경에 없을 경우, SwiftUI는 예외를 발생시키는 대신에 nil을 반환합니다.

@Environment(Library.self) private var library: Library?

 

Get an observable object using a key path

객체를 key path(키 경로)로 만들기 위해서 environment(_:_:) modifier 를 사용해야한다.

@Observable
class Library {
    var books: [Book] = [Book(), Book(), Book()]


    var availableBooksCount: Int {
        books.filter(\.isAvailable).count
    }
}


@main
struct BookReaderApp: App {
    @State private var library = Library()


    var body: some Scene {
        WindowGroup {
            LibraryView()
                .environment(\.library, library)
        }
    }
}

 

객체를 가져오기 위해서는 프로퍼티를 만들고 명시한 key path(키 경로)를 만들어야한다.

struct LibraryView: View {
    @Environment(\.library) private var library


    var body: some View {
        // ...
    }
}

 

 

 

만일 다른 뷰에서 @EnvironmentObject의 값을 수정하였을 때 다른 뷰에서 그에 대한 대응을 하고싶을 경우 @StateObject로 선언합니다.

'SwiftUI' 카테고리의 다른 글

property wrapper  (0) 2023.11.10
Property, Method  (0) 2023.11.10
URL  (0) 2023.11.08
Files  (0) 2023.11.08
App Storage  (0) 2023.11.07
ytw_developer