如何在 SwiftUI 延迟一段时间后显示新视图
How do I show a new view after some delay amount of time SwiftUI
所以我正在构建一个 21 点模拟器游戏,我现在的问题是让它更逼真。从我按下 "Hit Me" 按钮开始,我希望在上传下一张卡片之前有延迟。类似地,当下一个玩家离开时,我也希望延迟。所以现在我有一个玩家视图,一个手视图和一个卡片视图。玩家和手都是可观察的。
var body: some View {
HStack {
VStack(alignment: .trailing, spacing: 0){
ForEach(0..<self.player.hands.count, id: \.self) {
index in ZStack {
Spacer()
HandView.init(hand: self.player.hands[index])
}
}
Spacer().frame(height: 45)
Text(self.player.id).bold().font(Font.system(size: 20))
Spacer()
}
.padding(.all)
if !player.isRobot{
VStack{Button(action: {
self.player.requestCard()
}, label: {
Text("Hit Me!")
})
Button(action: {
self.player.handleInput(turn: turnPosibilities.stay)
self.player.objectWillChange.send()
}, label: {
Text("Stay")
})}
.offset(x: 10, y: 0)}
}
}
@ObservedObject var hand:Hand
var bust: some View {
GeometryReader { geometry in
Path { path in
path.move(to: CGPoint.init(x: geometry.frame(in: .local).midX, y: CGFloat(geometry.frame(in: .local).midY)))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).minY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).maxY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).maxY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).minY))
}
.fill(Color.red)
}
}
var body: some View {
ZStack
{ForEach(0..<self.hand.cards.count, id: \.self){
card in
VStack(alignment: .leading, spacing: 2) {PlayingCardView(rank: self.hand.cards[card].rankRaw, suit: self.hand.cards[card].suit, isFaceUp: self.hand.cards[card].isFaceUp ).rotationEffect(Angle.init(degrees: Double(multiply(index: card, offset: 10))))
.offset(x: multiply(index: card, offset: 15), y: multiply(index: card, offset: 40))
}
}
}
}
}
ZStack{
if isFaceUp {
Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(#colorLiteral(red: 0.9999127984, green: 1, blue: 0.9998814464, alpha: 1))).cornerRadius(25).overlay(Image(self.suit.rawValue).resizable().aspectRatio(contentMode: .fit).padding(.all))
Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70)
Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70).rotationEffect(Angle.init(degrees: 180))
}
else {
Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(UIColor(red: 0.58, green: 0.65, blue: 0.65, alpha: 1.00)
)).cornerRadius(25)
}
}.clipShape(RoundedRectangle(cornerRadius: 25)).overlay(RoundedRectangle(cornerRadius: 25).stroke(Color.black, lineWidth: 2))
}
这是可能的方法
VStack{Button(action: {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // 1 sec delay
self.player.requestCard()
}
}, label: {
Text("Hit Me!")
})
这可以在 SwiftUI 中通过定义 @State
变量/标志并显示基于它的新视图来实现。在下面的代码片段中,showSecondView
确定何时显示下一个视图。
struct ContentView: View {
@State var showSecondView = false
var body: some View {
Group {
Text("Hello, World!")
.font(.largeTitle)
.foregroundColor(.primary)
if showSecondView {
Text("SecondView")
.font(.title)
.foregroundColor(.secondary)
}
}
.onAppear() {
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (_) in
withAnimation {
self.showSecondView = true
}
}
}
}
所以我正在构建一个 21 点模拟器游戏,我现在的问题是让它更逼真。从我按下 "Hit Me" 按钮开始,我希望在上传下一张卡片之前有延迟。类似地,当下一个玩家离开时,我也希望延迟。所以现在我有一个玩家视图,一个手视图和一个卡片视图。玩家和手都是可观察的。
var body: some View {
HStack {
VStack(alignment: .trailing, spacing: 0){
ForEach(0..<self.player.hands.count, id: \.self) {
index in ZStack {
Spacer()
HandView.init(hand: self.player.hands[index])
}
}
Spacer().frame(height: 45)
Text(self.player.id).bold().font(Font.system(size: 20))
Spacer()
}
.padding(.all)
if !player.isRobot{
VStack{Button(action: {
self.player.requestCard()
}, label: {
Text("Hit Me!")
})
Button(action: {
self.player.handleInput(turn: turnPosibilities.stay)
self.player.objectWillChange.send()
}, label: {
Text("Stay")
})}
.offset(x: 10, y: 0)}
}
}
@ObservedObject var hand:Hand
var bust: some View {
GeometryReader { geometry in
Path { path in
path.move(to: CGPoint.init(x: geometry.frame(in: .local).midX, y: CGFloat(geometry.frame(in: .local).midY)))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).minY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).minX, y: geometry.frame(in: .local).maxY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).maxY))
path.addLine(to: CGPoint.init(x: geometry.frame(in: .local).maxX, y: geometry.frame(in: .local).minY))
}
.fill(Color.red)
}
}
var body: some View {
ZStack
{ForEach(0..<self.hand.cards.count, id: \.self){
card in
VStack(alignment: .leading, spacing: 2) {PlayingCardView(rank: self.hand.cards[card].rankRaw, suit: self.hand.cards[card].suit, isFaceUp: self.hand.cards[card].isFaceUp ).rotationEffect(Angle.init(degrees: Double(multiply(index: card, offset: 10))))
.offset(x: multiply(index: card, offset: 15), y: multiply(index: card, offset: 40))
}
}
}
}
}
ZStack{
if isFaceUp {
Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(#colorLiteral(red: 0.9999127984, green: 1, blue: 0.9998814464, alpha: 1))).cornerRadius(25).overlay(Image(self.suit.rawValue).resizable().aspectRatio(contentMode: .fit).padding(.all))
Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70)
Text(String(self.rank)).font(.custom("Poppins-SemiBoldItalic", size: 40)).offset(x: 29, y: -70).rotationEffect(Angle.init(degrees: 180))
}
else {
Rectangle().frame(width: 130, height:182).foregroundColor(Color.init(UIColor(red: 0.58, green: 0.65, blue: 0.65, alpha: 1.00)
)).cornerRadius(25)
}
}.clipShape(RoundedRectangle(cornerRadius: 25)).overlay(RoundedRectangle(cornerRadius: 25).stroke(Color.black, lineWidth: 2))
}
这是可能的方法
VStack{Button(action: {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { // 1 sec delay
self.player.requestCard()
}
}, label: {
Text("Hit Me!")
})
这可以在 SwiftUI 中通过定义 @State
变量/标志并显示基于它的新视图来实现。在下面的代码片段中,showSecondView
确定何时显示下一个视图。
struct ContentView: View {
@State var showSecondView = false
var body: some View {
Group {
Text("Hello, World!")
.font(.largeTitle)
.foregroundColor(.primary)
if showSecondView {
Text("SecondView")
.font(.title)
.foregroundColor(.secondary)
}
}
.onAppear() {
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { (_) in
withAnimation {
self.showSecondView = true
}
}
}
}