@State 바인딩에 오류가있는 iOS14

Sep 17 2020

아래 swiftUI 코드는 iOS13에서 잘 작동했지만 iOS14로 테스트 할 때 모달 시트를 표시하려고 할 때 강제 풀림 옵션으로 인해 치명적인 오류가 발생합니다. 내가 알 수있는 한, showsDetails는 selectedModel을 할당 한 후에 만 ​​참이 되었기 때문에 시트는 selectedModel에 대해 nil 값을 제공하려고 시도해서는 안됩니다.

struct SpeakerBrandMenu: View {
    var filteredSpeakers: [Speaker] {
        // An array of Speaker objects
        }
        
    @State var selectedModel: Speaker?
    @State private var showingDetails = false

    var body: some View {
        List{       
        ForEach(filteredSpeakers) { speaker in
            HStack {
                Button(action: {
                    self.selectedModel = speaker
                    self.showingDetails = true
                }) {
                    SpeakerModelRow(speaker: speaker).contentShape(Rectangle())
                }
                .buttonStyle(PlainButtonStyle())

                Spacer()
                
                Button(
                //unrelated
                ).padding(5)
              }
            }
        } .sheet(isPresented: self.$showingDetails) { SpeakerDetailView(speaker: self.selectedModel!, showSheet: self.$showingDetails).environmentObject(self.favoriteSpeakers).environmentObject(self.settings)}
               
          .navigationBarTitle(Text(brand), displayMode: .inline)
    }
}

흥미롭게도, speaker: self.selectedModel ?? filteredSpeakers[0]예상대로 정확히 동작하는대로 포장을 풀면 메뉴 항목을 처음 누르면 첫 번째 항목이 시트로 전달되지만 시트를 닫고 다른 항목을 선택하면 매번 올바른 항목이 표시됩니다. 따라서 selectedModel을 할당하는 버튼이 시간이 지정되기 전에 시트를 표시하려고하는 것과 같습니다.

답변

3 pawello2222 Sep 17 2020 at 05:39

이제 iOS 14 sheet(isPresented:content:)에서이 (가) 미리 생성 된 것처럼 보이 므로 변경 사항 selectedModel은 무시됩니다.

sheet(item:content:)대신 사용해보십시오 .

var body: some View {
    List {
        ...
    }
    .sheet(item: self.$selectedModel) { SpeakerDetailView(speaker: $0)
    }
}

다음을 사용하여 시트를 닫습니다 @Environment(\.presentationMode).

struct SpeakerDetailView: View {
    @Environment(\.presentationMode) private var presentationMode
    var speaker: Speaker

    var body: some View {
        Text("Speaker view")
            .onTapGesture {
                presentationMode.wrappedValue.dismiss()
            }
    }
}