SwiftUI嵌套转换和动画
我有一个水平的SwiftUI嵌套转换和动画,swiftui,transition,swiftui-animation,Swiftui,Transition,Swiftui Animation,我有一个水平的滚动视图,其中包含一些矩形s。我试图实现的是淡出每个矩形,然后隐藏(删除)滚动视图 我已经部分实现了这一点: 我这样说的部分原因是,正如您所看到的,矩形s被删除,但ScrollView仍然存在(请参见属于ScrollView的蓝色边框框,我添加了一些填充以使其更可见) 我想我可能需要嵌套转换(每个矩形都有一个.move(edge:)转换,并且滚动视图应该有另一个“外部”转换-但这也可能是错误的方法 如何实现此动画以及如何在动画结束时转换(删除)滚动视图?我尝试了不同的选项,但失败
滚动视图
,其中包含一些矩形
s。我试图实现的是淡出每个矩形
,然后隐藏(删除)滚动视图
我已经部分实现了这一点:
我这样说的部分原因是,正如您所看到的,矩形
s被删除,但ScrollView仍然存在(请参见属于ScrollView的蓝色边框框,我添加了一些填充以使其更可见)
我想我可能需要嵌套转换(每个矩形
都有一个.move(edge:)
转换,并且滚动视图
应该有另一个“外部”转换-但这也可能是错误的方法
如何实现此动画以及如何在动画结束时转换(删除)滚动视图?我尝试了不同的选项,但失败了。注意:黑色的矩形
已修复
以下是示例代码:
struct TestAnimation: View {
@State var show : Bool = true
var colors : [Color] = [.red, .orange, .yellow, .green, .blue]
var body: some View {
VStack(alignment: .leading) {
Spacer()
Color.purple
.frame(height: 100)
.overlay(
Text("Tap Me!").foregroundColor(.white))
.onTapGesture {
self.show.toggle()
}
HStack(alignment: .bottom) {
Rectangle()
.fill(Color.black)
.frame(width: 70, height: 100)
.overlay(Text("A").foregroundColor(.white).font(.largeTitle))
.padding(8)
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .bottom) {
if show {
self.cellForItemAt(idx: 2)
self.cellForItemAt(idx: 3)
self.cellForItemAt(idx: 4)
self.cellForItemAt(idx: 5)
}
}
.frame(height: 100)
.padding(4)
.border(Color.red)//HStack
}//Scrollview
.padding(4)
.border(Color.blue)
}
.padding(4)
.border(Color.gray)//Hstack
}
}
func cellForItemAt(idx: Int) -> some View {
return Rectangle()
.fill(colors[idx-1])
.frame(width: 70, height: 100)
.transition(AnyTransition.move(edge: .bottom).combined(with: .opacity).animation(self.ripple(idx: idx)))
.animation(ripple(idx: idx))
}
func ripple(idx: Int) -> Animation {
Animation
.easeInOut(duration: 0.8)
.delay(0.20 * Double(colors.count - idx) : Double(idx))
}
}
我对您的问题的解决方案是,仅为scrollview创建一个新的
状态
,然后将矩形包装在一个组中,并将组包装在if show
和ononDisappear
setself.showcoll=false
最后,确保在点击点击我!
时将showcoll
设置为true
这是最优雅的方式吗?不,但它能完成任务!
我对您的问题的解决方案是,仅为scrollview创建一个新的
状态
,然后将矩形包装在一个组中,并将组包装在if show
和ononDisappear
setself.showcoll=false
最后,确保在点击点击我!
时将showcoll
设置为true
这是最优雅的方式吗?不,但它能完成任务!
如果你把
scrollview
包装在if show{}
里面,你可以给它一个0.20*的延迟动画,颜色计数。@MuhandJumah,那不行。我已经试过了。或者你是如何实现的?我已经发布了我的答案,我希望它对你有用。祝你好运!如果你把scrollview
包装在if show{}里面呢
你可以给它一个0.20*颜色计数的延迟动画。@MuhandJumah,那不行。我已经试过了。或者你是如何实现的?我已经发布了我的答案,我希望它对你有用。祝你好运!
//
// TestAnimation.swift
// playground
//
// Created by Muhand Jumah on 3/20/20.
// Copyright © 2020 Muhand Jumah. All rights reserved.
//
import SwiftUI
struct TestAnimation: View {
@State var show : Bool = true
@State var showScroll: Bool = true
var colors : [Color] = [.red, .orange, .yellow, .green, .blue]
var body: some View {
VStack(alignment: .leading) {
Spacer()
Color.purple
.frame(height: 100)
.overlay(
Text("Tap Me!").foregroundColor(.white))
.onTapGesture {
self.showScroll = true
self.show.toggle()
}
HStack(alignment: .bottom) {
Rectangle()
.fill(Color.black)
.frame(width: 70, height: 100)
.overlay(Text("A").foregroundColor(.white).font(.largeTitle))
.padding(8)
if(showScroll) {
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .bottom) {
if show {
Group {
self.cellForItemAt(idx: 2)
self.cellForItemAt(idx: 3)
self.cellForItemAt(idx: 4)
self.cellForItemAt(idx: 5)
}.onDisappear {
self.showScroll = false
}
}
}
.frame(height: 100)
.padding(4)
.border(Color.red)//HStack
}//Scrollview
.padding(4)
.border(Color.blue)
}
}
.padding(4)
.border(Color.gray)//Hstack
}
}
func cellForItemAt(idx: Int) -> some View {
return Rectangle()
.fill(colors[idx-1])
.frame(width: 70, height: 100)
.transition(AnyTransition.move(edge: .bottom).combined(with: .opacity).animation(self.ripple(idx: idx)))
.animation(ripple(idx: idx))
}
func ripple(idx: Int) -> Animation {
Animation
.easeInOut(duration: 0.8)
.delay(0.20 * Double(colors.count - idx))
}
}
struct TestAnimation_Previews: PreviewProvider {
static var previews: some View {
TestAnimation()
}
}