SwiftUI:@环境(\.presentationMode)的解除在iOS 14中不起作用

ctzwtxfj  于 2022-12-10  发布在  Swift
关注(0)|答案(4)|浏览(352)

我有一个视图,它显示了一个用于筛选列表中项目的工作表。该视图具有以下var:

struct JobsTab: View {

@State private var jobFilter: JobFilter = JobFilter()

var filter: some View {
        Button {
            self.showFilter = true
        } label: {
            Image(systemName: "line.horizontal.3.decrease.circle")
                .renderingMode(.original)
        }
        .sheet(isPresented: $showFilter) {
            FilterView($jobFilter, categoriesViewModel, jobsViewModel)
        }
    }

然而,在工作表中,我尝试了以下操作,但在单击“完成”按钮时无法使视图消失,只能单击“取消”按钮:

struct FilterView: View {
@Environment(\.presentationMode) var presentationMode
    @ObservedObject var categoriesViewModel: CategoriesViewModel
    @ObservedObject var jobsViewModel: JobsViewModel
    let filterViewModel: FilterViewModel
    
    @Binding var jobFilter: JobFilter
    
    @State private var draft: JobFilter
    @State var searchText = ""
init(_ jobFilter: Binding<JobFilter>, _ categoriesViewModel: CategoriesViewModel, _ jobsViewModel: JobsViewModel) {
        _jobFilter = jobFilter
        _draft = State(wrappedValue: jobFilter.wrappedValue)
        self.categoriesViewModel = categoriesViewModel
        self.jobsViewModel = jobsViewModel
        self.filterViewModel = FilterViewModel()
    }
...
.toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("FilterView.Button.Cancel.Text".capitalizedLocalization) {
                        presentationMode.wrappedValue.dismiss()
                    }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("FilterView.Button.Done.Text".capitalizedLocalization) {
                        let request = Job.defaultRequest()
                        
                        request.predicate = filterViewModel.buildPredicate(withJobFilterDraft: self.draft)
                        request.sortDescriptors = [NSSortDescriptor(key: #keyPath(Job.publicationDate), ascending: false)]
                        
                        jobsViewModel.filteredJobsFetchRequest = request
                        self.jobFilter = self.draft
                        presentationMode.wrappedValue.dismiss()
                    }
                }
            }

我也试过使用@Binding,就像Paul说的here,但是没有成功。有什么解决办法吗?或者我做错了什么?
提前感谢!
编辑:我已经发布了两个视图的属性,因为我认为问题来自FilterViewself.jobFilter = self.draft中的行。我在这里尝试做的是创建一个过滤器视图,当用户按下DONE按钮时,上述行将被执行:我想把JobsTab中的绑定jobFilter赋值给FilterView的真值源(它是@State),可能因为我更新了绑定jobFilter,所以FilterView会再次显示,即使$showFilterfalse?老实说,我不知道。
EDIT 2:我也试过'if #available(iOS 15.0,*){ let _ = Self._printChanges()} else { //回退到早期版本}

in both `FilterView` and its called `JobTabs` and in both, I get the same result: unchanged
1cosmwyk

1cosmwyk1#

根据你的代码,我假设你的FilterView()不是一个子视图,而是一个由它自己独立的视图。因此,要确保“presentationMode. wrapedValue.dismiss()”作品、您不需要在FilerView外部创建@Binding或@State变量()用于在不同视图之间来回传递数据。只需在FilterView中创建一个变量()使它工作。我没有你的完整代码,但我创建了一个类似的情况下,你的问题如下代码:

import SwiftUI

struct Main: View {
@State private var showFilter = false
var body: some View {
    Button {
        self.showFilter = true
    } label: {
        Image(systemName: "line.horizontal.3.decrease.circle")
            .renderingMode(.original)
    }
    .sheet(isPresented: $showFilter) {
       FilterView()
    }
}
}

struct FilterView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
    NavigationView {
        VStack {
            Text("Filter View")
        }.toolbar {
            ToolbarItem(placement: .navigationBarLeading) {
                Button {
                    presentationMode.wrappedValue.dismiss()
                } label: {
                    Text("cancel")
                }
            }
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    presentationMode.wrappedValue.dismiss()
                } label: {
                    Text("okay")
                }
            }
        }
    }
}
}
ar7v8xwq

ar7v8xwq2#

缺少参数onDismiss

.sheet(isPresented: $showFilter, onDismiss: { isPresented = false }) { ... }
34gzjxbg

34gzjxbg3#

视图模型对象通常是错误的来源,因为我们在SwiftUI中不使用这些对象,而是使用结构体来提高速度和一致性。我建议创建一个包含bool属性isSheetPresented以及工作表所需数据的@State结构体。添加一个变异函数,并从button事件在结构体上调用它。将对结构体的绑定传递到工作表中。s视图,在该视图中可以调用另一个变异函数将bool设置为false。

struct SheetConfig {
    var isPresented = false
    var data: [String] = []

    mutating func show(initialData: [String] ) {
        isPresented = true
        data = initialData
    }

    mutating func hide() {
        isPresented = false
    }

}

struct ContentView: View {

    @State var config = SheetConfig()

    var body: some View {
        Button {
            config.show(intialData: ...)
        } label: {

        }
        .sheet(isPresented: $config.isPresented) {
            FilterView($config)
        }
xpszyzbs

xpszyzbs4#

在工作表中尝试添加此内容。

@Environment(\.dismiss) var dismiss // EnvironmentValue

Button("Some text") {
    // Code  
    dismiss() 
}

相关问题