사용자가 개성을 나타낼 수 있도록 사용자 프로필을 만들어보자. 프로필을 변경할 수 있도록 편집 모드를 추가하고 기본 설정 화면을 디자인해보자. 데이터 입력을 위해 공통 사용자 인터페이스 컨트롤로 작업하고 사용자가 변경 사항을 저장할 때마다 랜드마크 모델 타입을 업데이트해야 한다.
랜드마크 앱은 일부 구성 정보와 설정을 로컬로 저장한다. 이를 사용자가 세부 정보를 편집하기 전에 편집 컨트롤이 없는
ProfileSummary
뷰에 표시해보자.
func toolbar<Content>(@ToolbarContentBuilder content: () -> Content) -> some View where Content : ToolbarContent
지정된 항목으로 툴바 또는 네비게이션 바를 채운다.
사용자는 자신의
ProfileSummary
뷰와ProfileEditor
뷰를 전환할 수 있어야 하므로ProfileHost
에EditButton
을 추가하고 개별 값을 수정할 수 있는 컨트롤이 있는 편집 뷰를 만들어보자.
@frozen @propertyWrapper struct Environment<Value>
뷰의 environment에서 값을 읽는 프로퍼티 래퍼
SwiftUI는 @Environment
프로퍼티 래퍼를 사용해 접근할 수 있는 값에 대한 Environment 저장소를 제공한다.
// summary view 와 edit mode 를 static하게 호스팅하는 뷰
struct ProfileHost: View {
// SwiftUI는 @Environment 프로퍼티 래퍼를 사용해 접근할 수 있는 값에 대한 Environment 저장소를 제공한다.
@Environment(\\.editMode) var editMode
@EnvironmentObject var modelData: ModelData
@State private var draftProfile = Profile.default
var body: some View {
VStack(alignment: .leading, spacing: 20) {
HStack {
Spacer()
EditButton()
}
if editMode?.wrappedValue == .inactive /* enum EditMode */ {
ProfileSummary(profile: modelData.profile)
} else {
Text("Profile Editor")
}
}
.padding()
}
}
struct ProfileHost_Previews: PreviewProvider {
static var previews: some View {
ProfileHost()
.environmentObject(ModelData())
// 이 뷰는 @EnvironmentObject 속성을 사용하지 않지만 하위 뷰가 해당 속성을 사용하므로 상위 뷰에서도 전달해줘야 오류가 발생하지 않음
}
}
ProfileEditor
뷰는 주로 프로필의 개별 세부 정보를 변경하는 다양한 컨트롤로 구성되며, 일부 변경할 수 없는 항목은 뷰에 표시하지 않는다.ProfileSummary
뷰와의 일관성을 위해 편집 뷰에서도 동일한 순서로 프로필 세부 정보를 추가해보자.