sheet
메소드 사용 시 동일한 뷰에 전달되는 모델 데이터 값이 다를 경우 클로저에 의해서 원하는 데이터 전달이 되지 않는다.import SwiftUI
struct SampleModel: Identifiable {
let id = UUID().uuidString
let title: String
}
struct MultipleSheetsSample: View {
@State private var selectedModel = SampleModel(title: "First Start!")
@State private var showSheet: Bool = false
var body: some View {
VStack {
Button("ONE") {
selectedModel = SampleModel(title: "ONE")
showSheet.toggle()
}
Button("TWO") {
selectedModel = SampleModel(title: "TWO")
showSheet.toggle()
}
}
.sheet(isPresented: $showSheet, content: {
NextSheetSample(model: selectedModel)
})
}
}
struct NextSheetSample: View {
let model: SampleModel
var body: some View {
Text(model.title)
}
}![](https://velog.velcdn.com/images/j_aion/post/3c8f45f0-edb5-48f6-a81e-60a39dc2525d/image.gif)
첫 번째
One
버튼이 눌릴 때 곧바로One
데이터가 저장된 구조체가 전달되는 게 아니라, 초기값이었던First Start
가 들어 있는 모델이 바인딩되고 있다!
Issue with .sheet() Passing String to a View in SwiftUI 2.0
.sheet
를 호출하는 핵심 로직인 showSheet
가 @State
변수 변경을 모든 시점에서 읽지 못하기 때문에 생기는 문제점이다. 이를 해결하는 세 가지 방법이 존재한다.Binding
사용하기@State
를 통해 다음 뷰로 넣어주는 데이터를 @Binding
으로 만들자..sheets
를 여러 개 사용하기sheet
를 버튼마다 달자. 하이어러키를 주의.$item
사용한 .sheet
사용하기.sheet
의 이니셜라이저로 $item
을 준다. 옵셔널로 선언한 item
이 nil이 아니게 될 때 곧바로 모달 뷰가 나온다. isPresented
를 위해 별도의 불리언 변수를 선언할 필요가 없는, 확장성이 뛰어난 가장 좋은 솔루션.Binding
사용하기.sheet(isPresented: $showSheet, content: {
NextSheetSample(model: $selectedModel)
})
...
@Binding var model: SampleModel
@State
변수의 주소를 넘겨주고, 모달 뷰에서는 이를 Binding
하면 된다. 하지만 로직이 복잡해질 경우 Binding
되는 변수 값이 생각지 않은 대로 작동할 수 있다..sheets
를 여러 개 사용하기Button("ONE") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet, content: {
NextSheetSample(model: SampleModel(title: "ONE"))
isPresented
활성화를 위한 별도의 불리언 변수를 토글하고, 그 sheet
메소드마다 해당 버튼에 대한 데이터를 바인딩한다. 하지만 버튼마다 시트를 넣어여하기 때문에 코드가 복잡해지고, 불리언 변수 역시 버튼 수마다 만들어야 한다는 단점이 있다.$item
사용한 .sheet
사용하기@State private var selectedModel: SampleModel? = nil
...
.sheet(item: $selectedModel) { model in
NextSheetSample(model: model)
}
sheet
메소드의 이니셜라이저로 $item
을 선언한다. 즉 널 값이 아니라면 해당 시트에 데이터를 넣어준다는 뜻인데, isPresented
방법과 달리 불리언 변수를 선언할 필요가 없다. 확장성 역시 가장 뛰어나다.Binding
사용하기import SwiftUI
struct SampleModel: Identifiable {
let id = UUID().uuidString
let title: String
}
struct MultipleSheetsSample: View {
@State private var selectedModel = SampleModel(title: "First Start!")
@State private var showSheet: Bool = false
var body: some View {
VStack {
Button("ONE") {
selectedModel = SampleModel(title: "ONE")
showSheet.toggle()
}
Button("TWO") {
selectedModel = SampleModel(title: "TWO")
showSheet.toggle()
}
}
.sheet(isPresented: $showSheet, content: {
NextSheetSample(model: $selectedModel)
})
}
}
struct NextSheetSample: View {
@Binding var model: SampleModel
var body: some View {
Text(model.title)
}
}
.sheets
를 여러 개 사용하기import SwiftUI
struct SampleModel: Identifiable {
let id = UUID().uuidString
let title: String
}
struct MultipleSheetsSample: View {
@State private var showSheet: Bool = false
@State private var showSheet2: Bool = false
var body: some View {
VStack {
Button("ONE") {
showSheet.toggle()
}
.sheet(isPresented: $showSheet, content: {
NextSheetSample(model: SampleModel(title: "ONE"))
})
Button("TWO") {
showSheet2.toggle()
}
.sheet(isPresented: $showSheet2, content: {
NextSheetSample(model: SampleModel(title: "TWO"))
})
}
}
}
struct NextSheetSample: View {
let model: SampleModel
var body: some View {
Text(model.title)
}
}
struct MultipleSheetsSample_Previews: PreviewProvider {
static var previews: some View {
MultipleSheetsSample()
}
}
$item
사용한 .sheet
사용하기import SwiftUI
struct SampleModel: Identifiable {
let id = UUID().uuidString
let title: String
}
struct MultipleSheetsSample: View {
@State private var selectedModel: SampleModel? = nil
var body: some View {
VStack {
Button("ONE") {
selectedModel = SampleModel(title: "ONE")
}
Button("TWO") {
selectedModel = SampleModel(title: "TOW")
}
}
.sheet(item: $selectedModel) { model in
NextSheetSample(model: model)
}
}
}
struct NextSheetSample: View {
let model: SampleModel
var body: some View {
Text(model.title)
}
}
import SwiftUI
struct SampleModel: Identifiable {
let id = UUID().uuidString
let title: String
}
struct MultipleSheetsSample: View {
@State private var selectedModel: SampleModel? = nil
var body: some View {
ScrollView {
ForEach(0..<50) { index in
Button("Button # \(index)") {
selectedModel = SampleModel(title: "\(index)")
}
.frame(maxWidth: .infinity)
}
}
.sheet(item: $selectedModel) { model in
NextSheetSample(model: model)
}
}
}
struct NextSheetSample: View {
let model: SampleModel
var body: some View {
Text(model.title)
}
}
struct MultipleSheetsSample_Previews: PreviewProvider {
static var previews: some View {
MultipleSheetsSample()
}
}
item
한 번만 사용해서 여러 개의 버튼에 바로 적용하는 확장성.