view - SwiftUI 编译器无法在合理的时间内进行类型检查
问题描述
我有一个 playerView 视图,它当前显示两件事:玩家的手牌和他们牌的总价值。它是这样定义的:
struct playerView: View{
@ObservedObject var player:Player
var isDealt:Bool
var body: some View{
VStack{
ZStack{
ForEach(player.viewCards.indices, id: \.self){ cardNumber in
//The first card has no offset so need conditional
if cardNumber == 0{
if player.viewCards[cardNumber]{
Image(player.hand[cardNumber].suit.rawValue + String(player.hand[cardNumber].rank) ).resizable().frame(width:120, height:160)
}
} else{
if player.viewCards[cardNumber]{
Image(player.hand[cardNumber].suit.rawValue + String(player.hand[cardNumber].rank) ).resizable().frame(width:120, height:160).offset(x: 40, y: -40)
}
}
}
}.padding(.top, 140)
//Display player card Score
if isDealt{
if player.hasAce{
Text("Card Score\n" + String(player.cardScore) + " / " + String(player.cardScore + 10)).font(.body).bold().foregroundColor(.white).lineLimit(2).multilineTextAlignment(.center)
} else{
Text("Card Score\n" + String(player.cardScore)).font(.body).bold().foregroundColor(.white).lineLimit(2).multilineTextAlignment(.center)
}
}
}
}
}
每当我尝试将几乎任何内容添加到代码中时,我都会不断收到错误“编译器无法在合理的时间内对该表达式进行类型检查;尝试将表达式分解为不同的子表达式”。例如,如果我尝试将 ForEach 循环的 else 部分中 Image 的偏移量更改为 (x: 40 * cardNumber, y: -40 * cardNumber),我会收到错误消息。我认为要解决这个问题,我需要通过创建另一个视图来进一步简化我的代码,以便在该视图中使用。但我不完全确定如何/为什么,因为这种观点对我来说似乎并不复杂。有人可以给我一个例子,说明我应该做些什么来进一步简化它?
我对我应该做的事情的理解是获取代码块并将它们转换为视图。所以拿 ZStack 把它变成一个新的视图,并在这个视图中调用它。但要做到这一点,我需要将播放器传递到新视图中,该视图已经传递到该视图中。这是简化视图并消除此错误的正确方法吗?
解决方案
以下是我们可以做的一些事情来帮助编译器。
对于卡片分数文本,您使用的是字符串连接,其中插值会更惯用。试试这个:
Text("""
Card Score
\(player.cardScore) / \(player.cardScore + 10)
"""
)
我们还可以将您的两个卡片分数分支合并为一个:
let aceAlt = player.hasAce ? " / \(player.cardScore + 10)" : ""
Text("""
Card Score
\(player.cardScore)\(aceAlt)
"""
)
.font(.body)
.bold()
.foregroundColor(.white)
.lineLimit(2)
.multilineTextAlignment(.center)
将图像名称计算提取到单独的属性中是合理的:
extension Card {
fileprivate var imageName: String { "\(suit.rawValue)\(rank)" }
}
然后我们可以创建Image
这样的:
Image(player.hand[cardNumber].imageName)
cardNumber == 0
由于case 和 else case之间的唯一区别是offset
,我们可以在cardNumber
case 中使用零偏移量:
Image(player.hand[cardNumber].imageName)
.resizable()
.frame(width:120, height:160)
.offset(x: cardNumber == 0 ? 0 : 40, y: cardNumber == 0 ? 0 : -40)
如果您仍然遇到问题,请将卡片图像和卡片分数提取到辅助函数:
extension Card {
fileprivate var imageName: String { "\(suit.rawValue)\(rank)" }
}
struct PlayerView: View {
@ObservedObject var player: Player
var isDealt: Bool
var body: some View {
VStack {
ZStack {
ForEach(player.viewCards.indices, id: \.self) { cardNumber in
if player.viewCards[cardNumber] {
cardImage(for: player.hand[cardNumber], isFirst: cardNumber == 0)
}
}
}
.padding(.top, 140)
if isDealt {
cardScoreView
}
}
}
private func cardImage(for card: Card, isFirst: Bool) -> some View {
return Image(card.imageName)
.resizable()
.frame(width: 120, height: 160)
.offset(
x: isFirst ? 0 : 40,
y: isFirst ? 0 : -40)
}
private var cardScoreView: some View {
let aceAlt = player.hasAce ? " / \(player.cardScore + 10)" : ""
return Text("""
Card Score
\(player.cardScore)\(aceAlt)
"""
)
.font(.body)
.bold()
.foregroundColor(.white)
.lineLimit(2)
.multilineTextAlignment(.center)
}
}
推荐阅读
- javascript - TypeError:状态在 react 和 redux 上不可迭代
- ios - 我的应用程序上没有出现 utf-8 字符
- laravel - 将数据从 Laravel 导出到 Excel 时如何解决 Class App\Exports\FormExport 包含 1 个抽象方法?
- r - 如何使用 dplyr 将报价数据转换为订单簿数据
- node.js - 如何创建一个连接到 Mongo、显示 Streak、Badges 等的 Node 的 React Web 应用程序?
- html - 如何在html网页中显示源代码?
- python - 在 python 中编写一个简单的数学方程时遇到问题
- python - 如何使用 Canny 边缘检测器摆脱双边缘?
- erlang - 什么是 BEAM 中的同步调用技巧/参考技巧
- javascript - 如何在变量名中使用 javascript 中的模板文字?