SwiftUI 转换没有发生

SwiftUI Transition not happening

我是 SwiftUI 的新手,我正在尝试使用 .transition,但由于某种原因没有发生转换。

您可以看到下面的代码:

查看

import SwiftUI

struct ContentView: View {
  @ObservedObject var viewModel = ViewModel()
  
  var body: some View {
    if self.viewModel.model.show {
      Text("Showing")
        .padding()
    } else {
      Text("Not Showing")
        .padding()
        .transition(.asymmetric(insertion: .scale, removal: .opacity))
    }
    
    Button {
      self.viewModel.show()
    } label: {
      Text("Tap to change")
    }
  }
}

ViewModel

class ViewModel: ObservableObject {
  @Published private(set) var model = Model()
  
  func show() {
    self.model.toggleShow()
  }
}

型号

struct Model {
  var show: Bool = true
  
  mutating func toggleShow() {
    self.show.toggle()
  }
}

当我点击按钮时,文本会发生变化,但不会发生转换。

我觉得我在这里遗漏了一些微不足道的东西。

有人可以帮忙吗?

您需要一个动画(动画转换)和一个容器(执行实际转换,因为默认隐式 Group 不这样做)。

这里是固定的部分代码(用Xcode 13.2 / iOS 15.2测试)

*注意:Preview > Debug > Slow Animation 为了更好的可见性

var body: some View {
    VStack {                            // << this !!
        if self.viewModel.model.show {
            Text("Showing")
                .padding()
        } else {
            Text("Not Showing")
                .padding()
                .transition(.asymmetric(insertion: .scale, removal: .opacity))
        }
    }
    .animation(.default, value: self.viewModel.model.show)  // << here !!

    Button {
        self.viewModel.show()
    } label: {
        Text("Tap to change")
    }
}

你的代码很好(除了你需要 VStack 包装文本和按钮这一事实),你只需要告诉 SwiftUI 通过将命令包装在 withAnimation() 中来使用转换.

您只需在 ContentView 中执行以下操作(查看按钮):

    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            if self.viewModel.model.show {
                Text("Showing")
                    .padding()
            } else {
                Text("Not Showing")
                    .padding()
                    .transition(.asymmetric(insertion: .scale, removal: .opacity))
            }
            
            
            Button {
                withAnimation {       // This is what you need to trigger the transition
                    self.viewModel.show()
                }
            } label: {
                Text("Tap to change")
            }
        }
        .animation(.easeIn, value: self.viewModel.show)

    }