SwiftUI 从另一个视图重新排序列表动态部分 [英] SwiftUI Reorder list dynamic sections from another view

查看:25
本文介绍了SwiftUI 从另一个视图重新排序列表动态部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的 List,其中的部分存储在 ObservableObject 中.我想从另一个角度对它们重新排序.

I have a simple List with sections that are stored inside an ObservableObject. I'd like to reorder them from another view.

这是我的代码:

class ViewModel: ObservableObject {
    @Published var sections = ["S1", "S2", "S3", "S4"]
    
    func move(from source: IndexSet, to destination: Int) {
        sections.move(fromOffsets: source, toOffset: destination)
    }
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    @State var showOrderingView = false

    var body: some View {
        VStack {
            Button("Reorder sections") {
                self.showOrderingView = true
            }
            list
        }
        .sheet(isPresented: $showOrderingView) {
            OrderingView(viewModel: self.viewModel)
        }
    }

    var list: some View {
        List {
            ForEach(viewModel.sections, id: \.self) { section in
                Section(header: Text(section)) {
                    ForEach(0 ..< 3, id: \.self) { _ in
                        Text("Item")
                    }
                }
            }
        }
    }
}

struct OrderingView: View {
    @ObservedObject var viewModel: ViewModel

    var body: some View {
        NavigationView {
            List {
                ForEach(viewModel.sections, id: \.self) { section in
                    Text(section)
                }
                .onMove(perform: viewModel.move)
            }
            .navigationBarItems(trailing: EditButton())
        }
    }
}

但是在 OrderingView 中尝试移动部分时出现此错误:尝试为单元格创建两个动画".可能是因为各部分的顺序发生了变化.

But in the OrderingView when trying to move sections I'm getting this error: "Attempt to create two animations for cell". Likely it's because the order of the sections has changed.

如何更改部分的顺序?

推荐答案

这种情况下的问题是重新创建多次<代码>视图模型,所以在片材进行的修饰刚刚失去.(奇怪的是,在带有 StateObject 的 SwiftUI 2.0 中,这些更改也丢失了,并且 EditButton 根本不起作用.)

The problem of this scenario is recreated many times ViewModel, so modifications made in sheet just lost. (The strange thing is that in SwiftUI 2.0 with StateObject these changes also lost and EditButton does not work at all.)

无论如何.看起来这里是一个找到的解决方法.这个想法是打破采访依赖性(绑定)并使用纯数据将它们显式传递到工作表中,然后从工作表中显式返回它们.

Anyway. It looks like here is a found workaround. The idea is to break interview dependency (binding) and work with pure data passing them explicitly into sheet and return them back explicitly from it.

经过测试使用 Xcode 12/iOS 14,但我尽量避免使用 SwiftUI 2.0 功能.

Tested & worked with Xcode 12 / iOS 14, but I tried to avoid using SwiftUI 2.0 features.

class ViewModel: ObservableObject {
    @Published var sections = ["S1", "S2", "S3", "S4"]

    func move(from source: IndexSet, to destination: Int) {
        sections.move(fromOffsets: source, toOffset: destination)
    }
}

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    @State var showOrderingView = false

    var body: some View {
        VStack {
            Button("Reorder sections") {
                self.showOrderingView = true
            }

            list
        }
        .sheet(isPresented: $showOrderingView) {
            OrderingView(sections: viewModel.sections) {
                self.viewModel.sections = $0
            }
        }
    }

    var list: some View {
        List {
            ForEach(viewModel.sections, id: \.self) { section in
                Section(header: Text(section)) {
                    ForEach(0 ..< 3, id: \.self) { _ in
                        Text("Item")
                    }
                }
            }
        }
    }
}

struct OrderingView: View {
    @State private var sections: [String]
    let callback: ([String]) -> ()

    init(sections: [String], callback: @escaping ([String]) -> ())
    {
        self._sections = State(initialValue: sections)
        self.callback = callback
    }

    var body: some View {
        NavigationView {
            List {
                ForEach(sections, id: \.self) { section in
                    Text(section)
                }
                .onMove {
                    self.sections.move(fromOffsets: $0, toOffset: $1)
                }
            }
            .navigationBarItems(trailing: EditButton())
        }
        .onDisappear {
            self.callback(self.sections)
        }
    }
}

这篇关于SwiftUI 从另一个视图重新排序列表动态部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆