SwiftUI: Mengubah transisi tampilan secara dinamis setelah tampilan dibuat

Aug 16 2020

Saya ingin mengubah transisi tampilan secara dinamis setelah tampilan dibuat. Saya beralih variabel Negara isTransition1dengan mengklik tombol untuk beralih antara transition1dan transition2seperti di bawah ini. Namun, itu tidak berfungsi sebagaimana mestinya jika salah satu dari transisi ini adalah opasitas. Tampilan yang akan dihapus segera setelah mengubah transisi selalu mempertahankan transisi aslinya. Anehnya, jika saya beralih transition2ke slide, itu akan berfungsi tanpa masalah. Tampilan yang akan dihapus akan menggunakan transisi baru. Apakah ada cara untuk membuat opacity berfungsi di sini?

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

Jawaban

1 Asperi Aug 16 2020 at 11:44

Tidak yakin apakah saya memahami dengan benar efek apa yang Anda coba capai, tetapi coba setel ulang hierarki tampilan (setidaknya ini pasti menyetel ulang transisi, sehingga tidak saling memengaruhi):

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