SwiftUI:点击导航链接时列表会将项目下移

问题描述 投票:0回答:1

每当我在列表滚动一点后点击列表中的导航链接时,列表似乎会暂时向下移动。请观看以下视频(启用“慢速动画”的模拟器):

这是我的代码:

struct SearchView: View {
    private static let navTitle = "Title"

    @EnvironmentObject var locModel: LocationViewModel
    
    @ObservedObject private var searchModel = SearchViewModel()
    
    var body: some View {
        NavigationStack {
            if searchModel.isLoading {
                ProgressView()
                    .navigationTitle(SearchView.navTitle)
            } else if searchModel.results.isEmpty {
                Text("No results.") // TODO
                    .navigationTitle(SearchView.navTitle)
            } else if let total = searchModel.total, let lastPage = searchModel.lastLoadedPage {
                List {
                    Section {
                        ForEach(searchModel.results.indices, id: \.self) { i in
                            SearchResultRow(searchModel.results[i]).id(i)
                        }
                        
                        if searchModel.results.count < total {
                            HStack {
                                Spacer()
                                ProgressView()
                                Spacer()
                            }.task {
                                await load(page: lastPage + 1)
                            }
                        }
                        
                    } header: {
                        if let locName = locModel.location?.name {
                            Text("**\(total)** results near **\(locName)**")
                        }
                    }
                }
                .navigationTitle(SearchView.navTitle)
            }
        }
        .onAppear {
            Task.detached { await load() }
        }
        .onChange(of: locModel) {
            Task.detached { await load() }
        }
    }
    
    private func load(page: Int = 1) async {
        if let loc = locModel.location {
            await searchModel.load(location: loc, page: page)
        }
    }
}

struct MinyanSearchResultRow: View {    
    let searchResult: SearchResult
    
    init(_ searchResult: SearchResult) {
        self.searchResult = searchResult
       
    }
    
    var body: some View {
        NavigationLink {
            DetailView(searchResult: searchResult)
        } label: {
                VStack(alignment: .leading) {
                    Text("Hello there")
                }
            }        
    }
}

struct DetailView: View {
    let searchResult: SearchResult
                    
    var body: some View {
        Text("Test")
    }
}
swift xcode swiftui
1个回答
0
投票

很多错误:不应该使用视图模型对象,而是使用

View
。等待的异步函数应该返回一些不是空的东西,通常存储在
@State
中。像这样初始化一个
@ObservedObject
是内存泄漏,没有所有权。对于许多
if
来说效率很低,相反,定义一次
View
并在参数上使用 bool 逻辑(或将逻辑重构为计算得出的 var)。
onAppear
Task.detached
看起来像是一个错误,在 SwiftUI 中使用 async/await 是
.task
/
.task(id:)
。最严重的会崩溃的错误是
ForEach
是需要提供
View
数据的
Identifiable
,它不是for循环,所以改变:

ForEach(searchModel.results.indices, id: \.self) { i in
    SearchResultRow(searchModel.results[i]).id(i) // this [i] will crash if the results change in size.
}

ForEach(searchModel.results) { result in
    SearchResultRow(result) // this [i] will crash if the results change in size.
}
...
struct SearchResult: Identifiable {
...

希望所有这些建议都能有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.