在swiftUI中是否可以通过按钮在屏幕上添加新视图? [英] In swiftUI is it possible to add a new view onto the screen with a button?
问题描述
每次我点击按钮,我想出现一个新的cardView.我想知道在swiftUI中这是否可行,如果可以,我需要采取什么行动.如果我能够将一些参数传递给cardView结构,那会更好,但是任何帮助都会很棒!
Every time I Tap the button I would like a new cardView to appear. I am wondering if this is possible in swiftUI and if so what action I would need to do it. It would be even better if I am able to pass some parameters in to the cardView struct but any help would be great!
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()
}
} ```
推荐答案
在SwiftUI中,视图反映了状态数据,因此您无需直接修改视图,而是修改状态数据,并基于以下内容构建视图国家.这是SwiftUI背后的核心原则,它使您可以将View关注点与驱动它的数据(在某些术语中为ViewModel)分开.
In SwiftUI, the View reflects the State data, so you don't modify the View directly, but rather modify the State data, and build the View based on the State. This is a core principle behind SwiftUI, and it allows you to separate the View concerns from the data that drives it (ViewModel in some lingo).
因此,假设我们有一个 Card
的数据模型(使其符合 Identifiable
-稍后将需要):
So, let's assume that we have a data model for a Card
(make it conform to Identifiable
- this will be needed later):
struct Card: Identifiable {
let id = UUID()
let name: String
}
让我们在视图中将一组纸牌定义为状态变量:
And let's define an array of cards as a state variable in your View:
@State private var cards: [Card] = [Card(name: "foo")]
然后,尸体可以在 ForEach
或 List
视图中显示这些卡:
Then the body could display these cards with a ForEach
or in a List
view:
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
}
}
}
发生的事情是,按钮的闭合将新的 Card
实例添加到 cards
状态变量.就是这样.它不会直接更改视图中的任何内容.视图会看到更改(这是SwiftUI在后台执行的操作)并重新呈现自己.
What happens is that the closure for the button adds a new Card
instance to the cards
state variable. That's it. It doesn't change anything in the View directly. The View sees the change (that's what SwiftUI does behind the scenes) and re-renders itself.
需要一张 Card
来符合 Identifiable
的原因是让 ForEach
知道如何唯一地识别每张卡.在不符合可识别性的前提下,您可以使用如下所示的关键路径:
The reason you needed a Card
to conform to Identifiable
was to let the ForEach
know how to uniquely identify each card. Without conforming to identifiable, you could use a key path like so:
ForEach(cards, id: \.self) { card in
// ...
}
这篇关于在swiftUI中是否可以通过按钮在屏幕上添加新视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!