SwiftUI:ビューの作成後に、ビューの遷移を動的に変更します

Aug 16 2020

ビューの作成後にビューの遷移を動的に変更したい。私は、状態変数を切り替えるisTransition1間のスイッチへ]ボタンをクリックして、transition1そしてtransition2以下のように。ただし、これらの遷移の1つが不透明度である場合は、意図したとおりに機能しません。トランジションを変更した直後に削除されるビューは、常に元のトランジションを保持します。驚いたことに、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)
        }
      }
    }
  }
}

回答

1 Asperi Aug 16 2020 at 11:44

あなたが達成しようとした効果を正しく理解したかどうかはわかりませんが、ビュー階層をリセットしてみてください(少なくともこれは遷移を確実にリセットするので、相互に影響を与えません):

  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 !!
  }