ios 在swiftUI中,是否可以通过按钮在屏幕上添加新视图?

eulz3vhy  于 2023-07-09  发布在  iOS
关注(0)|答案(2)|浏览(171)

每次我点击按钮时,我都希望出现一个新的cardView。我想知道这在swiftUI中是否可能,如果是这样,我需要做什么。如果我能把一些参数传递给cardView结构体就更好了,但是任何帮助都是很好的!

struct ContentView: View {
    var body: some View {
        ZStack {
            VStack {
                TextButton(action: {print("Button tapped")}, text: "new card")
                CardView()
            }
        }
    }
}

struct CardView: View {
    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color(#colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)))
                .frame(width: 100, height: 100 * 1.618)
                .cornerRadius(16)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.1), radius: 1, x: 0, y: 1)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.2), radius: 10, x: 0, y: 10)

            VStack {
                Text("Card")
                    .font(.system(size: 10) )
                    .foregroundColor(.white)
                    .bold()
            }
        }
    }
}

struct TextButton: View {
    let action: () -> Void
    let text: String

    var body: some View {
        Button(action: action, label: {
            Text(text)
                .padding(.horizontal, 16)
                .padding(.vertical, 16)
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(.infinity)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.1), radius: 1, x: 0, y: 1)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.2), radius: 10, x: 0, y: 10)
        })
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
} ```
z9gpfhce

z9gpfhce1#

在SwiftUI中,View反映的是State数据,所以你不是直接修改View,而是修改State数据,然后根据State构建View。这是SwiftUI背后的核心原则,它允许您将视图关注点与驱动它的数据(某些术语中的ViewModel)分开。
因此,让我们假设我们有一个Card的数据模型(使其符合Identifiable-这将在稍后需要):

struct Card: Identifiable {
  let id = UUID()
  let name: String
}

让我们在View中定义一个卡片数组作为状态变量:

@State private var cards: [Card] = [Card(name: "foo")]

然后,主体可以用ForEachList视图显示这些卡:

var body = some View {
  VStack() {
    Button("Add Card") {
       self.cards.append(Card(name: "I'm an added card"))
    }
    ForEach(cards) { card in
       CardView(for: card) // if your CardView had parameters
    }
  }
}

按钮的闭包向cards状态变量添加了一个新的Card示例。就是这样。它不会直接改变视图中的任何内容。View会看到更改(这就是SwiftUI在幕后所做的)并重新呈现自己。
您需要Card来符合Identifiable的原因是让ForEach知道如何唯一地标识每张卡。在不符合identifiable的情况下,您可以使用这样的密钥路径:

ForEach(cards) { card in
  // ...
}
sd2nnvve

sd2nnvve2#

看看这个

import SwiftUI

struct ContentView: View {

    @State var cards: [CardView] = [CardView()]


    var body: some View {
        VStack {
            TextButton(action: {
                print("Button tapped")
                self.cards.append(CardView())

            }, text: "new card")
            ZStack {
                ForEach(cards, id: \.self) { card in
                    card
                        .rotationEffect(card.angle)

                }

            }
        }
    }
}

struct CardView: View, Hashable, Identifiable {

    var id = UUID()

    var angle : Angle {
        let angle = Angle(degrees: Double.random(in: 0...30))
        print(angle.degrees)
        return angle
    }
    var body: some View {
        ZStack {
            Rectangle()
                .fill(Color(#colorLiteral(red: 0.7450980544, green: 0.1568627506, blue: 0.07450980693, alpha: 1)))
                .frame(width: 100, height: 100 * 1.618)
                .cornerRadius(16)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.1), radius: 1, x: 0, y: 1)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.2), radius: 10, x: 0, y: 10)

            VStack {
                Text("Card \(angle.degrees)")
                    .font(.system(size: 10) )
                    .foregroundColor(.white)
                    .bold()
            }
        }
    }
}

struct TextButton: View {
    let action: () -> Void
    let text: String

    var body: some View {
        Button(action: action, label: {
            Text(text)
                .padding(.horizontal, 16)
                .padding(.vertical, 16)
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(.infinity)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.1), radius: 1, x: 0, y: 1)
                .shadow(color: Color(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)).opacity(0.2), radius: 10, x: 0, y: 10)
        })
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

相关问题