在 swiftUI 中的视图数组之间切换

use*_*232 2 view ios swift swiftui

斯威夫特 5.x iOS 13.x

我创建了一系列骰子视图,我想在它们之间切换。为了简短起见,我在这里仅展示两个视图。我创建了一个视图数组,但我不太清楚如何在 SwiftUI 中解决它?或者实际上视图是什么类型的对象,因为它不是视图或看起来的某种视图。

import SwiftUI
import GameplayKit

let dotSize:CGFloat = 24
let diceSize:CGFloat = 128
let fieldSide:CGFloat = 32

let d6 = GKRandomDistribution.d2()

var diceViews:[Any] = [oneDotDice(),twoDotDice()]

struct ContentView: View {
  @State var showInt:Int = 1
  var body: some View {

VStack {
  if showInt == 1 {
    oneDotDice()
      .transition(AnyTransition.opacity)
      .animation(.default)
      .modifier(changeDice(showInt: self.$showInt))
  }
  if showInt == 2 {
    twoDotDice()
      .transition(AnyTransition.opacity)
      .animation(.default)
      .modifier(changeDice(showInt: self.$showInt))
  }
 }
}

struct oneDotDice: View {
  var body: some View {
  Rectangle()
    .fill(Color.clear)
    .frame(width: diceSize, height: diceSize, alignment: .center)
    .border(Color.black)
   .background(Text(1))
  }
}

struct twoDotDice: View {
  var body: some View {
  Rectangle()
    .fill(Color.clear)
    .frame(width: diceSize, height: diceSize, alignment: .center)
    .border(Color.black)
   .background(Text(2))
  }
}

struct changeDice: ViewModifier {
  @Binding var showInt:Int
  func body(content: Content) -> some View {
    content
      .onTapGesture {
        self.showInt = d6.nextInt()
        print("Int ",self.showInt)
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

如何在主循环中使用我的视图数组使此代码更好?我什至无法在 SwiftUI 代码中使用 switch 语句。我需要使用六个嵌套的 if/else 语句......

Asp*_*pid 5

视图只是一个结构体。您可以将其存储在数组或其他属性类型中,然后在另一个视图中使用它。AnyView如果您确实想在一个集合中混合不同类型的视图,这是一个很好的解决方案。为了动态显示该集合,我喜欢使用 ForeEach。您可以迭代的不是确切的视图,而是数组的索引。因此,SwiftUI 将从该视图的数组索引中创建该视图的键。但它是有代价的。您无法动态更改该数组的内容。它在所有父视图生命周期中必须保持不变。老实说,您实际上可以通过 ForeEach 迭代确切的 View,但您需要使它们可识别(它们必须有一个public var id = UUID()属性)。

import SwiftUI

let dotSize:CGFloat = 24
let diceSize:CGFloat = 128
let fieldSide:CGFloat = 32


struct ContentView: View {
  var diceViews:[AnyView] = [AnyView(oneDotDice()), AnyView(twoDotDice())]
  @State var showInt: Int = 1
  var body: some View {
    ZStack{
        ForEach(diceViews.indices){ind in
            ZStack{
                if ind == self.showInt{
                    self.diceViews[ind]
                        .transition(.scale(scale: 0, anchor: .center))
                    .onTapGesture {
                        let newShow = Int.random(in: 0...1)
                        print("new show id \(newShow)")
                          withAnimation(.linear(duration: 0.3)){
                            self.showInt = newShow
                          }
                    }
                }
            }

        }
    }
  }
}
struct oneDotDice: View {
  var text: String = "1"
  var body: some View {
  Rectangle()
    .fill(Color.clear)
    .frame(width: diceSize, height: diceSize)
    .border(Color.black)
   .background(Text(text))
  }
}

struct twoDotDice: View {
  var text: String = "2"
  var body: some View {
  Rectangle()
    .fill(Color.clear)
    .frame(width: diceSize, height: diceSize)
    .border(Color.black)
   .background(Text(text))
  }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我改变了你的随机逻辑,不确定它是如何工作的,但我认为这对你的问题并不重要。