假设我有一个简单的个人资料屏幕,如下所示:

class Model: ObservableObject {
    @Published var isSignedIn = false

    init() {}

    func login() {
        //Some networking here
        isSignedIn = true
    }
    func logout() {
        //Some networking here
        isSignedIn = false
    }
}

struct ContentView: View {
    @ObservedObject var model = Model()

    var body: some View {
        ZStack {
            //ProfileView
            VStack {
                //Some Views with WithAnimation inside
                // ...

                Text("Hello, Dear User!")
                Button(action: {
                    self.model.logout()
                }) {
                    Text("Sign Out")
                }
            }
            .opacity(model.isSignedIn ? 1 : 0)

            //LoginView
            VStack {
                Text("Hello, Stranger")
                Button(action: {
                    self.model.login()
                }) {
                    Text("Sign In")
                }
            }
            .opacity(model.isSignedIn ? 0 : 1)
        }
    }
}
我想将动画应用于不透明度变化。
第一种方法是使用.animation修饰符。但是它具有某些缺点:如果内部视图具有WithAnimation,它将无法正常工作-它会覆盖使用WithAnimation设置的动画。
我使用.onReceive的第二种方法:
class Model: ObservableObject {
    @Published var isSignedIn = false

    init() {}

    func login() {
        isSignedIn = true
    }
    func logout() {
        isSignedIn = false
    }
}

struct ContentView: View {
    @ObservedObject var model = Model()

    @State var isSignedIn = false

    var body: some View {
        ZStack {
            //ProfileView
            VStack {
                Text("Hello, Dear User!")
                Button(action: {
                    self.model.logout()
                }) {
                    Text("Sign Out")
                }
            }
            .opacity(model.isSignedIn ? 1 : 0)

            //LoginView
            VStack {
                Text("Hello, Stranger")
                Button(action: {
                    self.model.login()
                }) {
                    Text("Sign In")
                }
            }
            .opacity(model.isSignedIn ? 0 : 1)
        }
        .onReceive(self.model.$isSignedIn) { value in
            withAnimation(Animation.easeIn) {
                self.isSignedIn = value
            }
        }
    }
}
有一些问题(我认为):
  • 需要另一个@State var来处理
  • 模型中的更改
  • 每个WithAnimation块都需要单独的.onReceive

  • 所以问题是:将WithAnimation应用于@ObservedObject是正确的方法,还是有更好的解决方案?

    最佳答案

    您可以直接在withAnimation内部指定动画。这样,它仅特定于此更改:

    Button(action: {
        withAnimation(.easeInOut) { // add animation
            self.model.logout()
        }
    }) {
        Text("Sign Out")
    }
    

    关于ios - 如何与@ObservedObject一起使用WithAnimation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63652507/

    10-12 14:39