SwiftUI中Deal与Discard按钮不显示问题求助
解决按钮不显示及布局调整问题
问题原因
你的Toolbar无法显示是因为SwiftUI的toolbar修饰符需要配合NavigationStack(iOS 16+)或NavigationView(iOS 15及以下)使用,没有这些容器时,工具栏不会被渲染。
布局方案选择
如果你的需求是让按钮显示在屏幕中央,直接将按钮嵌入主布局的VStack中比用Toolbar更直接合理,不需要依赖导航容器。
修改后的完整代码
import SwiftUI struct Card: Hashable { let rank: String let suit: String } struct ContentView: View { let ranks = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"] let suits = ["clubs", "diamonds", "hearts", "spades"] let cardWidth: CGFloat = 100 let cardHeight: CGFloat = 150 @State private var playerHand: [Card] = [] @State private var deck: [Card] = [] @State private var discardPile: [Card] = [] @State private var deckImages: [String] = [] private func createDeck() -> [Card] { var deck = [Card]() for suit in suits { for rank in ranks { deck.append(Card(rank: rank, suit: suit)) } } return deck } private func deal() { guard let card = deck.first else { return } playerHand.append(card) deck.removeFirst() deckImages.removeFirst() } private func discard() { guard let card = playerHand.first else { return } discardPile.append(card) playerHand.removeFirst() } var body: some View { VStack(spacing: 30) { // 玩家手牌区域 HStack { ForEach(playerHand, id: \.self) { card in Image(card.rank + "_of_" + card.suit) .resizable() .frame(width: cardWidth, height: cardHeight) } } // 中央操作按钮组 HStack(spacing: 40) { Button("Deal") { deal() } .buttonStyle(.borderedProminent) Button("Discard") { discard() } .buttonStyle(.borderedProminent) } // 牌堆与弃牌堆区域 HStack { VStack { Image(deckImages.first ?? "card_back") .resizable() .frame(width: cardWidth, height: cardHeight) Text("Cards left: \(deck.count)") } Spacer() VStack { ForEach(discardPile, id: \.self) { card in Image(card.rank + "_of_" + card.suit) .resizable() .frame(width: cardWidth, height: cardHeight) } Text("Cards discarded: \(discardPile.count)") } } } .padding() .onAppear { deck = createDeck().shuffled() deckImages = deck.map { $0.rank + "_of_" + $0.suit } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
关键修改点
- 移除了原有的
.toolbar修饰符,将Deal和Discard按钮放在主VStack的中间位置,用HStack横向排列并设置间距 - 给按钮添加了
.buttonStyle(.borderedProminent)让按钮更醒目(可选,可根据需求调整样式) - 调整了主
VStack的spacing,让布局更均衡
如果坚持要用Toolbar实现底部工具栏,只需将整个VStack包裹在NavigationStack中即可:
NavigationStack { // 原VStack内容 } .toolbar { ToolbarItem(placement: .bottomBar) { Button("Deal") { deal() } } ToolbarItem(placement: .bottomBar) { Button("Discard") { discard() } } }
内容的提问来源于stack exchange,提问作者Justin Kachornvanich
相关产品推荐
相关产品推荐

