[英]SwiftUI - how to cancel the default list animation
有没有办法在不使用列表本身的 .animation(nill) 修饰符的情况下删除默认列表行折叠动画?
正如您在下面的剪辑中看到的那样,我在列表中实现了一个动画修改器,但是默认的列表折叠动画有点破坏了所需的动画。
https://gfycat.com/cheerywelloffalleycat
我已经更新了下面的代码,这样你就可以在你的 Xcode 上运行它而没有任何依赖。
import SwiftUI
struct CurrencyComparison: View {
@State var mainArray = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
@State var array = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
@State var secondArray = ["20", "20","20", "20", "20", "20", "20", "20", "20", "20"]
@State var hide = false
@State var direction = false
@State var triggerAnimation: Bool
var body: some View {
VStack {
List (self.mainArray, id:\.self) { item in
Text(item)
.foregroundColor(Color.black)
.frame(width: 40, height: 80)
.padding(.leading, 80)
.isHidden(self.hide)
Spacer()
Text(item)
.foregroundColor(Color.black)
.frame(width: 40, height: 40)
.padding(.trailing, 80)
.isHidden(self.hide)
}
.background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.red]), startPoint: .center, endPoint: .center))
.animation(Animation.spring().delay(triggerAnimation ? 0 : 0.4))
.transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .move(edge: .trailing)), removal: .move(edge: .trailing)))
.cornerRadius(30)
.padding(.top, 30)
.padding(.bottom, 30)
.shadow(radius: 10)
.gesture(
DragGesture(minimumDistance: 50)
.onEnded { value in
self.hide.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() ) {
if self.mainArray == self.array {
self.mainArray = self.secondArray
} else {
self.mainArray = self.array
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.hide.toggle()
}
}
)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height + 50, alignment: .top)
.background(Color.gray.aspectRatio(contentMode: .fill))
.padding(.top, 120)
}
}
struct CurrencyComparison_Previews: PreviewProvider {
@State static var staticBool = true
static var previews: some View {
CurrencyComparison(triggerAnimation: true)
}
}
extension View {
func isHidden(_ bool: Bool) -> some View {
modifier(HiddenModifier(isHidden: bool))
}
}
private struct HiddenModifier: ViewModifier {
fileprivate let isHidden: Bool
fileprivate func body(content: Content) -> some View {
Group {
if isHidden {
content.hidden()
} else {
content
.transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .slide), removal: .move(edge: .trailing)))
}
}
}
}
好的,所以我设法找到了一个有效的解决方案。 通过在列表数据源发生更改时更改列表项的不透明度。
当不需要的默认动画播放时将其设置为 0,并在我想要的动画开始播放时将其恢复为 1。
这样我就可以隐藏默认列表动画而不删除我自己想要的动画:)
import SwiftUI
struct CurrencyComparison: View {
@State var mainArray = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
@State var array = ["10", "10","10", "10", "10", "10", "10", "10", "10", "10"]
@State var secondArray = ["20", "20","20", "20", "20", "20", "20", "20", "20", "20"]
@State var toggleHide = false
@State var direction = false
@State var triggerAnimation: Bool
var body: some View {
VStack {
List (self.mainArray, id:\.self) { item in
Text(item)
.foregroundColor(Color.black)
.frame(width: 40, height: 80)
.padding(.leading, 80)
.isHidden(self.toggleHide)
.opacity(self.toggleHide ? 0 : 1)
Spacer()
Text(item)
.foregroundColor(Color.black)
.frame(width: 40, height: 40)
.padding(.trailing, 80)
.isHidden(self.toggleHide)
.opacity(self.toggleHide ? 0 : 1)
}
.background(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.red]), startPoint: .center, endPoint: .center))
.animation(Animation.spring().delay(triggerAnimation ? 0 : 0.4))
.transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .move(edge: .trailing)), removal: .move(edge: .trailing)))
.cornerRadius(30)
.padding(.top, 30)
.padding(.bottom, 30)
.shadow(radius: 10)
.gesture(
DragGesture(minimumDistance: 50)
.onEnded { value in
self.toggleHide.toggle()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
if self.mainArray == self.array {
self.mainArray = self.secondArray
} else {
self.mainArray = self.array
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.9) {
self.toggleHide.toggle()
}
}
)
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height + 50, alignment: .top)
.background(Color.gray.aspectRatio(contentMode: .fill))
.padding(.top, 120)
}
}
struct CurrencyComparison_Previews: PreviewProvider {
@State static var staticBool = true
static var previews: some View {
CurrencyComparison(triggerAnimation: true)
}
}
extension View {
func isHidden(_ bool: Bool) -> some View {
modifier(HiddenModifier(isHidden: bool))
}
}
private struct HiddenModifier: ViewModifier {
fileprivate let isHidden: Bool
fileprivate func body(content: Content) -> some View {
Group {
if isHidden {
content.hidden()
} else {
content
.transition(.asymmetric(insertion: AnyTransition.opacity.combined(with: .slide), removal: .move(edge: .trailing)))
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.