我的SwiftUI应用程序中有一个列表,上面有个按钮,用于查看要加载到列表中的项目的上一个/下一个类别。当您按下按钮时,列表的来源将更改,并且列表将以其默认动画(其中的行被折叠)更新。
简化的可复制版本的代码(请参见下面的屏幕截图):
$name
现在,我不想在此处使用默认的列表动画。我希望列表项水平滑动。因此,当您按下import SwiftUI
struct ContentView: View {
private let models = [
["a", "b", "c", "d", "e", "f"],
["g", "h"],
["i", "j", "k", "l"],
]
@State private var selectedCategory = 1
private var viewingModels: [String] {
models[selectedCategory]
}
var body: some View {
VStack(spacing: 0.0) {
HStack {
Button(action: previous) {
Text("<")
}
Text("\(selectedCategory)")
Button(action: next) {
Text(">")
}
}
List(viewingModels, id: \.self) { model in
Text(model)
}
}
}
private func previous() {
if selectedCategory > 0 {
selectedCategory -= 1
}
}
private func next() {
if selectedCategory < (models.count - 1) {
selectedCategory += 1
}
}
}
箭头查看下一类别的项目时,屏幕上的现有项目应移至左侧,而新项目应从右侧移入。按下>
按钮时则相反。基本上,它应该看起来像是一个具有多个页面的收藏夹视图。
我已经发现用<
包装previous
和next
函数的内容会将默认的列表动画更改为其他内容。然后,我尝试将withAnimation
添加到列表(及其中的文本)以更改新的动画,但这没有效果。不确定如何更改列表的动画,尤其是对于2个不同的按钮使用不同的“单向/单向”。
在实际应用中使用按类别列出列表的ScrollView不会在实际应用中按比例缩放,尽管是的,这可能是此简单示例(行数很少)的解决方案:)
答案 0 :(得分:2)
如果按您的建议包装了按钮,并且我添加了一个简单的布尔值指示:
Button(action: {
withAnimation {
slideRight = true
self.previous()
}
}) {
Text("<")
}
与另一方向相反:
Button(action: {
withAnimation {
slideRight = false
self.next()
}
}) {
Text(">")
}
然后您可以像这样转换视图:
List(viewingModels, id: \.self) { model in
Text(model)
}
.id(UUID())
.transition(.asymmetric(insertion: .move(edge: slideRight ? .leading : .trailing),
removal: .move(edge: slideRight ? .trailing : .leading)))
请注意,为了使列表不具有动画效果,我们需要每次为列表指定一个新的唯一ID,请参阅本文:https://swiftui-lab.com/swiftui-id/
更新:
我想提供完整的简化代码,并根据以下评论删除了UUID()用法。
import SwiftUI
struct ContentView: View {
private let models = [
["a", "b", "c", "d", "e", "f"],
["g", "h"],
["i", "j", "k", "l"],
]
@State private var selectedCategory = 0
@State private var slideRight = true
private var viewingModels: [String] {
models[selectedCategory]
}
var body: some View {
VStack(spacing: 0.0) {
HStack {
Button(action: {
withAnimation {
if(self.selectedCategory - 1 < 0) { self.selectedCategory = self.models.count - 1 }
else { self.selectedCategory -= 1 }
self.slideRight = true
}
}) {
Image(systemName: "arrow.left")
}
Text("\(selectedCategory + 1)")
Button(action: {
withAnimation {
if(self.selectedCategory + 1 > self.models.count - 1) { self.selectedCategory = 0 }
else { self.selectedCategory += 1 }
self.slideRight = false
}
}) {
Image(systemName: "arrow.right")
}
}.font(.title)
List(viewingModels, id: \.self) { model in
Text(model)
}
.id(selectedCategory)
.transition(.asymmetric(insertion: .move(edge: slideRight ? .leading : .trailing),
removal: .move(edge: slideRight ? .trailing : .leading)))
}.padding(10)
}
}