我的 SwiftUI 应用程序中有一个列表,顶部有按钮可以查看要加载到列表中的上一个/下一个项目类别。当您按下按钮时,列表的源会发生变化,并且列表会以其默认动画进行更新(行折叠起来)。
简化的可重现版本的代码(请参阅下面的屏幕截图):
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我不想在这里使用默认的列表动画。我希望列表项水平滑动。因此,当您按>
箭头查看下一类别的项目时,屏幕上的现有项目应移至左侧,而新项目应从右侧进入。当您按下按钮时则相反<
。基本上,它应该感觉像一个具有多个页面的集合视图,您可以在多个页面之间滚动。
previous
我已经发现将和next
函数的内容包装起来withAnimation
会将默认列表动画更改为其他内容。然后,我尝试添加.transition(.slide)
到列表(以及其中的文本)以更改新动画,但这没有效果。不知道如何更改列表的动画,尤其是两个不同按钮的不同的一个/方向。
使用带有每个类别列表的 ScrollView 不会在实际应用程序中扩展,尽管这可能是这个行数很少的简单示例的解决方案:)
如果您的按钮按照您的建议进行包装,并且我添加了一个简单的方向布尔值:
Button(action: {
withAnimation {
slideRight = true
self.previous()
}
}) {
Text("<")
}
Run Code Online (Sandbox Code Playgroud)
另一个方向则相反:
Button(action: {
withAnimation {
slideRight = false
self.next()
}
}) {
Text(">")
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样转换你的视图:
List(viewingModels, id: \.self) { model in
Text(model)
}
.id(UUID())
.transition(.asymmetric(insertion: .move(edge: slideRight ? .leading : .trailing),
removal: .move(edge: slideRight ? .trailing : .leading)))
Run Code Online (Sandbox Code Playgroud)
请注意,为了使列表不显示动画,我们需要每次为列表提供一个新的唯一 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)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4901 次 |
最近记录: |