【问题标题】:SwiftUI: Change a view's transition dynamically after the view is createdSwiftUI:创建视图后动态更改视图的转换
【发布时间】:2020-12-05 11:42:52
【问题描述】:

我想在视图创建后动态地更改视图的过渡。我通过单击按钮在transition1transition2 之间切换来切换状态变量isTransition1,如下所示。但是,如果这些过渡之一是不透明度,则它不会按预期工作。更改过渡后立即删除的视图始终保持其原始过渡。令人惊讶的是,如果我将transition2 更改为滑动,它将毫无问题地工作。要移除的视图将使用新的过渡。有什么办法可以让不透明度在这里起作用吗?

let transition1 = AnyTransition.asymmetric(insertion: .move(edge: .trailing),
                                           removal: .move(edge: .leading))

let transition2 = AnyTransition.opacity

struct Wrapper1<Content: View>: View {
  let content: Content

  var body: some View {
    content
  }
}

struct Wrapper2<Content: View>: View {
  let content: Content

  var body: some View {
    content
  }
}

struct TextView: View {
  let count: Int
  let color: Color

  var body: some View {
    ZStack {
      color
        .edgesIgnoringSafeArea(.all)
        .frame(maxWidth: UIScreen.main.bounds.width,
               maxHeight: UIScreen.main.bounds.height)

      Text("Count: \(count)")
        .font(.title)
        .offset(y: -200)
    }
  }
}

struct ContentView: View {
  @State private var count = 0
  @State private var isTransition1 = false

  var body: some View {
    ZStack {
      if count % 2 == 0 {
        Wrapper1(content: TextView(count: count, color: Color.green)
          .transition(isTransition1 ? transition1 : transition2))
        } else {
          Wrapper2(content: TextView(count: count, color: Color.red)
            .transition(isTransition1 ? transition1 : transition2))
        }

      HStack(spacing: 100) {
        Button(action: {
          self.isTransition1.toggle()
        }) {
          Text("Toggle Transition").font(.title)
        }

        Button(action: {
          withAnimation(.linear(duration: 2)) {
            self.count += 1
          }
        }) {
          Text("Increase").font(.title)
        }
      }
    }
  }
}

【问题讨论】:

  • 我正在尝试在使用 SwiftUI 实现自定义导航堆栈时实现相同的目标。 @appthumb 您是否设法找到解决方案或解决方法?
  • 很遗憾,没有...
  • 嗨!有这方面的消息吗?我有同样奇怪的行为......

标签: swift swiftui


【解决方案1】:

不确定我是否正确理解了您尝试实现的效果,但尝试重置视图层次结构(至少这肯定会重置过渡,因此它们不会相互影响):

  var body: some View {
    ZStack {
      if count % 2 == 0 {
        Wrapper1(content: TextView(count: count, color: Color.green)
          .transition(isTransition1 ? transition1 : transition2))
        } else {
          Wrapper2(content: TextView(count: count, color: Color.red)
            .transition(isTransition1 ? transition1 : transition2))
        }

      HStack(spacing: 100) {
        Button(action: {
          self.isTransition1.toggle()
        }) {
          Text("Toggle Transition").font(.title)
        }

        Button(action: {
          withAnimation(.linear(duration: 2)) {
            self.count += 1
          }
        }) {
          Text("Increase").font(.title)
        }
      }
    }.id(isTransition1)     // << here !!
  }

【讨论】:

  • 它确实将先前的过渡重置为无,但我也希望删除的视图在被删除时呈现新的过渡。例如,如果当前转换是transition2(不透明度),我单击按钮Toggle Transition 更改为transition1(移动),然后单击按钮Increase 切换视图。我希望删除的视图移动到屏幕的左侧,但使用 .id(_:) 似乎只会将过渡重置为无 - 删除的视图会在没有任何过渡的情况下消失。
  • 这种方法的另一个奇怪的副作用是按钮Toggle Transition一旦被按下就似乎保持在按下状态...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-20
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多