SwiftUI 从另一个视图重新排序列表动态部分 [英] SwiftUI Reorder list dynamic sections from another view
问题描述
我有一个简单的 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屋!