列出重新加载动画故障

Posted

技术标签:

【中文标题】列出重新加载动画故障【英文标题】:List reload animation glitches 【发布时间】:2020-01-05 16:47:15 【问题描述】:

所以我有一个列表,当用户填写搜索关键字时会发生变化,当没有结果时,所有单元格都会崩溃,并且不知何故它们会飞到第一部分,这看起来很丑陋。我的代码中有错误还是这是预期的 SwiftUI 行为?谢谢。

import SwiftUI

struct ContentView: View 

    @ObservedObject var viewModel = ViewModel(photoLibraryService: PhotoLibraryService.shared)

    var body: some View 
        NavigationView 
            List 
                Section 
                    TextField("Enter Album Name", text: $viewModel.searchText)
                
                Section 
                    if viewModel.libraryAlbums.count > 0 
                        ForEach(viewModel.libraryAlbums)  libraryAlbum -> Text in
                            let title = libraryAlbum.assetCollection.localizedTitle ?? "Album"
                            return Text(title)
                        
                    
                
            .listStyle(GroupedListStyle())
                .navigationBarTitle(
                    Text("Albums")
                ).navigationBarItems(trailing: Button("Add Album", action: 
                        PhotoLibraryService.shared.createAlbum(withTitle: "New Album \(Int.random(in: 1...100))")
                ))
        .animation(.default)
    

【问题讨论】:

你想把结果放在第一项吗?那么你需要进行排序而不是过滤 @ErnistIsabekov 不,我想过滤以显示结果。最终结果不是问题,而是从完整列表到结果的转换。您会看到当单元格折叠时,它会飞到顶部以超出其部分。这只是一瞬间的动画错误,但在设备上很明显。 【参考方案1】:

1) 你必须使用一些去抖动来减少刷新列表的需要,同时在搜索字段中输入

2) 禁用行动画

第二部分是最难的部分。诀窍是通过设置它的 id 来强制重新创建一些视图。

这是简单应用程序的代码(能够测试这个想法)

import SwiftUI
import Combine

class Model: ObservableObject 
    @Published var text: String = ""
    @Published var debouncedText: String = ""
    @Published var data = ["art", "audience", "association", "attitude", "ambition", "assistance", "awareness", "apartment", "artisan", "airport", "atmosphere", "actor", "army", "attention", "agreement", "application", "agency", "article", "affair", "apple", "argument", "analysis", "appearance", "assumption", "arrival", "assistant", "addition", "accident", "appointment", "advice", "ability", "alcohol", "anxiety", "ad", "activity"].map(DataRow.init)
    var filtered: [DataRow] 
        data.filter  (row) -> Bool in
            row.txt.lowercased().hasPrefix(debouncedText.lowercased())
        
    

    var id: UUID 
        UUID()
    

    private var store = Set<AnyCancellable>()
    init(delay: Double) 
        $text
            .debounce(for: .seconds(delay), scheduler: RunLoop.main)
            .sink  [weak self] (s) in
            self?.debouncedText = s
        .store(in: &store)
    


struct DataRow: Identifiable 
    let id = UUID()
    let txt: String
    init(_ txt: String) 
        self.txt = txt
    


struct ContentView: View 

    @ObservedObject var search = Model(delay: 0.5)

    var body: some View 

        NavigationView 
            VStack(alignment: .leading) 

                TextField("filter", text: $search.text)
                    .padding(.vertical)
                    .padding(.horizontal)

                List(search.filtered)  (e) in
                    Text(e.txt)
                .id(search.id)
            .navigationBarTitle("Navigation")
        
    



struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

我对结果很满意

【讨论】:

以上是关于列出重新加载动画故障的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView:重新加载数据,不删除单元内动画

重新加载tableview时不显示刷新动画|迅速

如何在 UITableView 重新加载期间控制过渡动画? [复制]

重新加载数据时 TableViewCell 中的动画

创建自定义行动画以重新加载 tableviewcell

用动画重新加载表格视图单元格(Swift)