无法在 SwiftUI 'Text' 中推断通用类型 'S' 在 CS193p 项目中,在 Xcode 中
Can't Infer Generic Type 'S' in SwiftUI 'Text' in CS193p project, in Xcode
背景
我正在关注 Stanfords 的 CS193p iOS 开发在线课程。我使用 Xcode 11.3 和 Swift 5.1.2.
问题
第五讲ViewBuilder + Shape + ViewModifier 结束的时候,我遇到了一个错误,就是Swift编译器报错'Generic parameter 'S' could not be inferred'。
Snapshot: IDE complains about it
代码片段
EmojiMemoryGameView.swift
中的代码
import SwiftUI
struct EmojiMemoryGameView: View {
@ObservedObject var viewModel: EmojiMemoryGame
var body: some View {
Grid(viewModel.cards) { card in
CardView(card: card).onTapGesture(perform: {
self.viewModel.choose(card: card)
})
.padding(5)
}
.padding()
.foregroundColor(Color.orange)
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let game = EmojiMemoryGame()
game.choose(card: game.cards[0])
return EmojiMemoryGameView(viewModel: game)
}
}
struct CardView: View {
var card: MemoryGame<String>.Card
var body: some View {
GeometryReader { geometry in
self.body(for: geometry.size)
}
}
@ViewBuilder
private func body(for size: CGSize) -> some View {
if card.isFaceUp || !card.isMatched {
ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}
}
private func fontSize(for size: CGSize) -> CGFloat {
return min(size.width, size.height) * fontScaleFactor
}
// MARK: - Drawing Constants
private let fontScaleFactor: CGFloat = 0.75
}
}
MemoryGame.swift
中的代码
import Foundation
struct MemoryGame<CardContent> where CardContent: Equatable { // costraints and gains
private(set) var cards: Array<Card>
private var indexOfTheOneAndOnlyFaceUpCard: Int? {
get {
cards.indices.filter { cards[[=14=]].isFaceUp }.only
}
set {
for index in cards.indices {
// newValue is a var only appears in set method
cards[index].isFaceUp = index == newValue
}
}
}
init(numberOfPairsOfCards: Int, cardContentFactory: (Int) -> CardContent) {
cards = Array<Card>()
let maxIndex = 2 * numberOfPairsOfCards - 1
var pairIndices = [Int]()
for i in 0...maxIndex {
let randomNumber = Double.random(in: 0...1)
if randomNumber >= 0.5 {
pairIndices.insert(i/2, at: 0)
} else {
pairIndices.append(i/2)
}
}
for i in 0...maxIndex {
let pairIndex = pairIndices[i]
let content = cardContentFactory(pairIndex)
cards.append(Card(id: i, content: content))
}
}
mutating func choose(card: Card) {
print("card chosen: \(card)")
if let chosenIndex = cards.firstIndex(matching: card), !cards[chosenIndex].isFaceUp, !cards[chosenIndex].isMatched {
// comma here is like a sequential "AND"
if let potentialMatchIndex = indexOfTheOneAndOnlyFaceUpCard {
if cards[chosenIndex].content == cards[potentialMatchIndex].content {
cards[chosenIndex].isMatched = true
cards[potentialMatchIndex].isMatched = true
}
} else {
indexOfTheOneAndOnlyFaceUpCard = chosenIndex
}
self.cards[chosenIndex].isFaceUp = true
}
}
struct Card: Identifiable {
/* Member variable 'id' is essential for the Identifiable protocol */
var id: Int
var isFaceUp: Bool = false
var isMatched: Bool = false
var content: CardContent
}
}
但是,当我按住 alt 并单击变量时,它清楚地显示类型是 String
。 Snapshot: Type Declaration
我当前的项目代码也可以在 Github
为什么会出现错误?我该如何解决?
感谢您的帮助!
在你的struct CardView: View
中,你有
if card.isFaceUp || !card.isMatched {
ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}
在 ZStack
之前添加一个 return
,这应该可以解决您的问题。
if card.isFaceUp || !card.isMatched {
return ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}
背景
我正在关注 Stanfords 的 CS193p iOS 开发在线课程。我使用 Xcode 11.3 和 Swift 5.1.2.
问题
第五讲ViewBuilder + Shape + ViewModifier 结束的时候,我遇到了一个错误,就是Swift编译器报错'Generic parameter 'S' could not be inferred'。 Snapshot: IDE complains about it
代码片段
EmojiMemoryGameView.swift
中的代码
import SwiftUI
struct EmojiMemoryGameView: View {
@ObservedObject var viewModel: EmojiMemoryGame
var body: some View {
Grid(viewModel.cards) { card in
CardView(card: card).onTapGesture(perform: {
self.viewModel.choose(card: card)
})
.padding(5)
}
.padding()
.foregroundColor(Color.orange)
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let game = EmojiMemoryGame()
game.choose(card: game.cards[0])
return EmojiMemoryGameView(viewModel: game)
}
}
struct CardView: View {
var card: MemoryGame<String>.Card
var body: some View {
GeometryReader { geometry in
self.body(for: geometry.size)
}
}
@ViewBuilder
private func body(for size: CGSize) -> some View {
if card.isFaceUp || !card.isMatched {
ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}
}
private func fontSize(for size: CGSize) -> CGFloat {
return min(size.width, size.height) * fontScaleFactor
}
// MARK: - Drawing Constants
private let fontScaleFactor: CGFloat = 0.75
}
}
MemoryGame.swift
中的代码
import Foundation
struct MemoryGame<CardContent> where CardContent: Equatable { // costraints and gains
private(set) var cards: Array<Card>
private var indexOfTheOneAndOnlyFaceUpCard: Int? {
get {
cards.indices.filter { cards[[=14=]].isFaceUp }.only
}
set {
for index in cards.indices {
// newValue is a var only appears in set method
cards[index].isFaceUp = index == newValue
}
}
}
init(numberOfPairsOfCards: Int, cardContentFactory: (Int) -> CardContent) {
cards = Array<Card>()
let maxIndex = 2 * numberOfPairsOfCards - 1
var pairIndices = [Int]()
for i in 0...maxIndex {
let randomNumber = Double.random(in: 0...1)
if randomNumber >= 0.5 {
pairIndices.insert(i/2, at: 0)
} else {
pairIndices.append(i/2)
}
}
for i in 0...maxIndex {
let pairIndex = pairIndices[i]
let content = cardContentFactory(pairIndex)
cards.append(Card(id: i, content: content))
}
}
mutating func choose(card: Card) {
print("card chosen: \(card)")
if let chosenIndex = cards.firstIndex(matching: card), !cards[chosenIndex].isFaceUp, !cards[chosenIndex].isMatched {
// comma here is like a sequential "AND"
if let potentialMatchIndex = indexOfTheOneAndOnlyFaceUpCard {
if cards[chosenIndex].content == cards[potentialMatchIndex].content {
cards[chosenIndex].isMatched = true
cards[potentialMatchIndex].isMatched = true
}
} else {
indexOfTheOneAndOnlyFaceUpCard = chosenIndex
}
self.cards[chosenIndex].isFaceUp = true
}
}
struct Card: Identifiable {
/* Member variable 'id' is essential for the Identifiable protocol */
var id: Int
var isFaceUp: Bool = false
var isMatched: Bool = false
var content: CardContent
}
}
但是,当我按住 alt 并单击变量时,它清楚地显示类型是 String
。 Snapshot: Type Declaration
我当前的项目代码也可以在 Github
为什么会出现错误?我该如何解决?
感谢您的帮助!
在你的struct CardView: View
中,你有
if card.isFaceUp || !card.isMatched {
ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}
在 ZStack
之前添加一个 return
,这应该可以解决您的问题。
if card.isFaceUp || !card.isMatched {
return ZStack {
Pie(startAngle: Angle.degrees(-90),
endAngle: Angle.degrees(-10),
clockwise: true)
.padding(5)
.opacity(0.3)
Text(card.content)
.font(Font.system(size: fontSize(for: size)))
}.cardify(isFaceUp: card.isFaceUp)
//.modifier(Cardify(isFaceUp: card.isFaceUp))
}