SwiftUI -动画视图过渡和位置更改在同一时间

jecbmhm3  于 2023-04-28  发布在  Swift
关注(0)|答案(2)|浏览(220)

我有一个黄色的容器里面有绿色的视野。我想移动容器,同时隐藏/显示内部绿色视图,并显示动画。目前,我正在使用.offset进行移动,并使用if语句进行绿色视图的转换。
问题是,虽然黄色容器移动,但绿色视图不移动。它只是在目标偏移处淡入淡出。我希望它也能沿着黄色容器移动。
| 这是我目前得到的|这就是我想要的|
| --------------|--------------|
|

|

|
下面是我的代码:

  1. struct ContentView: View {
  2. @State var showingSubview = false
  3. var body: some View {
  4. VStack {
  5. Button("Show Subview") {
  6. withAnimation(.easeInOut(duration: 2)) {
  7. showingSubview.toggle()
  8. }
  9. }
  10. if showingSubview {
  11. Text("Subview")
  12. .padding()
  13. .background(Color.green)
  14. }
  15. }
  16. .padding()
  17. .background(Color.yellow)
  18. .offset(x: showingSubview ? 150 : 0, y: 0)
  19. }
  20. }

如何使绿色视图沿着黄色容器的淡入淡出而移动?最好,我想继续使用ifswitch语句进行插入/删除。

tgabmvqs

tgabmvqs1#

您可以在设置动画时更改高度。

代码版本#1

这不会褪色,并出现在黄色矩形内。
验证码:

  1. struct ContentView: View {
  2. @State var showingSubview = false
  3. var body: some View {
  4. VStack(spacing: 0) {
  5. Button("Show Subview") {
  6. withAnimation(.easeInOut(duration: 2)) {
  7. showingSubview.toggle()
  8. }
  9. }
  10. Text("Subview")
  11. .padding()
  12. .background(Color.green)
  13. .padding(.top)
  14. .frame(height: showingSubview ? nil : 0, alignment: .top)
  15. .clipped()
  16. }
  17. .padding()
  18. .background(Color.yellow)
  19. .offset(x: showingSubview ? 150 : 0, y: 0)
  20. }
  21. }

结果#1

代码版本#2

这个版本将淡出并出现在底部边缘,如您的GIF显示。
验证码:

  1. struct ContentView: View {
  2. @State var showingSubview = false
  3. var body: some View {
  4. VStack(spacing: 0) {
  5. Button("Show Subview") {
  6. withAnimation(.easeInOut(duration: 2)) {
  7. showingSubview.toggle()
  8. }
  9. }
  10. Text("Subview")
  11. .padding()
  12. .background(Color.green)
  13. .padding(.top)
  14. .frame(height: showingSubview ? nil : 0, alignment: .top)
  15. .padding(.bottom)
  16. .background(Color.yellow)
  17. .clipped()
  18. .opacity(showingSubview ? 1 : 0)
  19. }
  20. .padding([.horizontal, .top])
  21. .background(Color.yellow)
  22. .padding(.bottom)
  23. .offset(x: showingSubview ? 150 : 0, y: 0)
  24. }
  25. }

结果#2

展开查看全部
mzaanser

mzaanser2#

一年后找到了一个解决方案,它真的很简单-只需添加.scaleEffect(1)

  1. .clipped() /// prevent the green view from overflowing
  2. .scaleEffect(1) /// the magic modifier!

这是一个更干净的解决方案,不涉及设置自定义帧或其他任何东西。此外,它还适用于ifswitch语句!

我不完全确定.scaleEffect(1)为什么工作,但它与SwiftUI如何组合视图有关。我认为修改器使SwiftUI将其呈现为一个新组?如果有人知道原因,我会很感激的。
下面是完整的代码:

  1. struct ContentView: View {
  2. @State var showingSubview = false
  3. var body: some View {
  4. VStack {
  5. Button("Show Subview") {
  6. withAnimation(.easeInOut(duration: 2)) {
  7. showingSubview.toggle()
  8. }
  9. }
  10. if showingSubview {
  11. Text("Subview")
  12. .padding()
  13. .background(Color.green)
  14. }
  15. }
  16. .padding()
  17. .background(Color.yellow)
  18. .clipped() /// 1.
  19. .scaleEffect(1) /// 2.
  20. .offset(x: showingSubview ? 150 : 0, y: 0)
  21. }
  22. }
展开查看全部

相关问题