0

我在 SwiftUI 视图中有一个工作动画,当我将该视图放入 a 时,它会中断,TabView转到另一个选项卡并返回。我该如何解决?

我的观点更复杂,但我将其归结为以下几点:

import SwiftUI

@main
struct AnimationTestApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Text("Tab 1")
                    }
                Text("Content 2")
                    .tabItem {
                        Text("Tab 2")
                    }
            }
        }
    }
}

struct ContentView: View {
    @StateObject private var viewModel = ViewModel()
    @Namespace var namespace

    var body: some View {
        VStack {
            Button(action: {
                viewModel.move()
            }) {
                Text("Move")
            }

            ZStack() {
                Rectangle()
                    .fill(.gray)
                    .frame(width: 300, height: 300, alignment: .center)
                if viewModel.moved {
                    RectView()
                        .matchedGeometryEffect(id: 0, in: namespace, properties: .frame)
                        .animation(Animation.default.speed(0.5))
                        .offset(x: 0, y: -130)

                } else {
                    RectView()
                        .matchedGeometryEffect(id: 0, in: namespace, properties: .frame)
                        .animation(Animation.default.speed(0.5))
                        .offset(x: 0, y: 130)
                }
            }
        }
    }
}

struct RectView: View {
    var body: some View {
        Rectangle()
            .frame(width: 100, height: 30, alignment: .center)
    }
}


final class ViewModel: ObservableObject {
    @Published var moved = false

    func move() {
        moved = !moved
    }
}

这是该代码的屏幕录像。点击时RectView上下动画流畅。Move切换Tab 2并返回后,我第一次点击Move时,它会在没有动画的情况下跳转。下一个水龙头再次动画。

动画

实际上,视图模型更复杂。状态(在这种情况下:moved)在按下按钮后一段时间会改变。一些工作在后台线程上完成,然后在主线程上触发状态更改。这就是为什么我不能将动画移动到Button动作中的原因。

视图也更复杂。RectView被从视图层次结构的深处移除并完全添加到其他地方。

该方法func animation(_ animation: Animation?)在 iOS 15 中已弃用。该问题在 iOS 14 中已经永远存在。我还尝试删除animation修饰符并将其moved = !moved放入一个withAnimation { }块中。结果还是一样。

我怎么能在保留的同时解决这个问题TabView

4

1 回答 1

-1

你有一些糟糕的编码问题,这里是工作代码,你也不需要matchedGeometryEffect这里:

import SwiftUI

@main
struct AnimationTestApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                ContentView()
                    .tabItem {
                        Text("Tab 1")
                    }
                Text("Content 2")
                    .tabItem {
                        Text("Tab 2")
                    }
            }
        }
    }
}

struct ContentView: View {
    
    @StateObject private var viewModel = ViewModel()

    var body: some View {
        
        VStack {
            
            Button(action: { viewModel.moved.toggle() }) {
                Text("Move")
            }

            ZStack() {

                Rectangle()
                    .fill(Color.gray)
                    .frame(width: 300, height: 300, alignment: .center)
                
                RectView()
                    .offset(x: 0, y: viewModel.moved ? -130 : 130)
                    .animation(Animation.default.speed(0.5), value: viewModel.moved)
                
            }
        }
    }
}

struct RectView: View {
    var body: some View {
        Rectangle()
            .frame(width: 100, height: 30)
    }
}


final class ViewModel: ObservableObject {
    @Published var moved: Bool = false
}
于 2021-10-06T21:56:16.270 回答