SwiftUI,如何在不重新创建视图的情况下切换到视图?

时间:2021-01-12 11:38:34

标签: ios swift swiftui

我的应用程序中有几个不同的视图,用户可以在它们之间切换。这些视图之一是我创建的 SearchView。此视图可用于在文档中搜索用户指定的字符串,然后选择要跳转到的搜索结果之一。这是通过在用户按下搜索按钮时生成一堆搜索结果来实现的。每个搜索结果都是其他视图的组合,这导致搜索过程和搜索结果生成过程需要相当长的时间,这在最初发生时很好。我的问题是,如果用户在搜索视图中进行搜索,切换到另一个视图,然后返回到搜索视图,重新创建所有搜索结果视图需要很长时间。

如何将搜索视图或搜索结果视图保存在某个未清除的变量中,以允许重复使用先前生成的搜索视图结果?

我已经使用环境对象来存储用于创建搜索结果的数据,例如搜索字符串、示例文本、章节等。因此在切换回搜索视图时不会重新创建数据,唯一的问题是视图本身。

这是搜索视图结构:

@EnvironmentObject var modelView: ModelView

var OnJumpToSearchResult: ((Int) -> Void)?

var body: some View {
    ScrollView {
        HStack {
            //Search Field
            HStack {
                TextField("Search string here", text: $modelView.searchString)
            }
            .padding()
            .background(Color(.systemGray5))
            .cornerRadius(6)
            .padding(.horizontal)
            
            //Search Button
            Button(action: { modelView.searchResults = PerformSearch(pages: modelView.searchPages, pageHeadings: modelView.pageHeadings, searchString: modelView.searchString, sampleRadius: sampleRadius) }, label: {
                Text("Search")
                    .padding(.trailing)
            })
        }
        
        //Display Search Results
        if modelView.searchResults.isEmpty {
            EmptyView()
        }
        else
        {
            ForEach(modelView.searchResults, id: \.self) { searchResult in
                Button(action: {
                    if OnJumpToSearchResult != nil {
                        OnJumpToSearchResult?(searchResult.pageNumber - 1) }
                    
                }) {
                    VStack {
                        Text("\(searchResult.heading)")
                            .bold()
                        HStack {
                            HighlightedTextView(String(searchResult.sampleText), matching: modelView.searchString, caseInsensitive: true)
                            Spacer()
                            Text("s.\(searchResult.pageNumber)")
                        }
                        .padding()
                    }
                    
                    
                    Divider()
                        .background(Color(.systemGray4))
                        .padding(.leading)
                }
            }
        }
    }
}

搜索视图的父视图在初始化时初始化搜索视图,并在它更新时重用它(而不是重新初始化一个新视图)。

1 个答案:

答案 0 :(得分:0)

如果您的搜索视图不依赖于其父视图中的任何内容,那么您只需在父视图中创建一次,并且在父视图中继其子视图时不会重新创建它(但如果重新创建父视图)

struct ViewThatRendersSearchView: View {
  let searchView = SearchView() // create it one time
  @State private var shouldShowSearchView = false
  var body: some View {
    if shouldShowSearchView {
      searchView // Won't be recreated each time
    } else {
      EmptyView()
    }
  }
}