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)
}
다음은 사용자가 직접 설정을 통해서 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 |