use*_*170 1 cs193p swift swiftui
我正在学习斯坦福大学的 CS193p 开发 iOS 应用程序在线课程。\n我使用的是 Xcode 11.5。(我没有更新,因为这是课程讲师(Paul Heagarty)正在使用的版本。)
\n我正在尝试做作业3(设定游戏)。目前(为了避免重复代码)我正在尝试替换此片段:
\n VStack {\n ForEach(0..<numberOfShapes) { index in\n if self.card.shape == .diamond {\n ZStack {\n Diamond().fill()\n .opacity(self.opacity)\n Diamond().stroke(lineWidth: self.shapeEdgeLineWidth)\n }\n }\n if self.card.shape == .squiggle {\n ZStack {\n Rectangle().fill()\n Rectangle().stroke(lineWidth: self.shapeEdgeLineWidth)\n }\n }\n if self.card.shape == .oval {\n ZStack {\n Ellipse().fill()\n Ellipse().stroke(lineWidth: self.shapeEdgeLineWidth)\n }\n }\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n有了这个片段:
\n VStack {\n ForEach(0..<numberOfShapes) { index in\n ZStack {\n shape(self.card.shape).opacity(self.opacity)\n shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type \'some View\' has no member \'stroke\'\n }\n }\n }\n\nRun Code Online (Sandbox Code Playgroud)\n这个 @ViewBuilder 函数:
\n@ViewBuilder\nfunc shape(_ shape: SetGameModel.Card.Shape) -> some View {\n if shape == .diamond {\n Diamond()\n } else if shape == .squiggle {\n Rectangle()\n } else {\n Ellipse()\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n这是完整的查看代码:
\nimport SwiftUI\n\nstruct SetGameView: View {\n @ObservedObject var viewModel: SetGameViewModel\n \n var body: some View {\n Grid(viewModel.cards) { card in\n CardView(card: card).onTapGesture {\n self.viewModel.choose(card: card)\n }\n .padding(5)\n }\n .padding()\n .foregroundColor(Color.orange)\n }\n}\n\nstruct CardView: View {\n var card: SetGameModel.Card\n\n var numberOfShapes: Int {\n switch card.numberOfShapes {\n case .one:\n return 1\n case .two:\n return 2\n case .three:\n return 3\n }\n }\n \n var opacity: Double {\n switch card.shading {\n case .open:\n return 0.0\n case .solid: // filled\n return 1.0\n case .striped: // you can use a semi-transparent color to represent the \xe2\x80\x9cstriped\xe2\x80\x9d shading.\n return 0.33\n }\n }\n \n var color: Color {\n switch card.color {\n case .green:\n return Color.green\n case .purple:\n return Color.purple\n case .red:\n return Color.red\n }\n }\n \n var body: some View {\n ZStack {\n RoundedRectangle(cornerRadius: cornerRadius).fill(Color.white)\n RoundedRectangle(cornerRadius: cornerRadius)\n .stroke(lineWidth: card.isChosen ? chosenCardEdgeLineWidth : normalCardEdgeLineWidth)\n .foregroundColor(card.isChosen ? Color.red : Color.orange)\n VStack {\n ForEach(0..<numberOfShapes) { index in\n ZStack {\n shape(self.card.shape).opacity(self.opacity)\n shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type \'some View\' has no member \'stroke\'\n }\n }\n }\n .foregroundColor(self.color)\n .padding()\n }\n .aspectRatio(cardAspectRatio, contentMode: .fit)\n }\n \n // MARK: - Drawing Constants\n let cornerRadius: CGFloat = 10.0\n let chosenCardEdgeLineWidth: CGFloat = 6\n let normalCardEdgeLineWidth: CGFloat = 3\n let shapeEdgeLineWidth: CGFloat = 2.5\n let cardAspectRatio: CGSize = CGSize(width: 2, height: 3) // 2/3 aspectRatio\n}\n\n@ViewBuilder\nfunc shape(_ shape: SetGameModel.Card.Shape) -> some View {\n if shape == .diamond {\n Diamond()\n } else if shape == .squiggle {\n Rectangle()\n } else {\n Ellipse()\n }\n}\n\nstruct ContentView_Previews: PreviewProvider {\n static var previews: some View {\n SetGameView(viewModel: SetGameViewModel())\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n我有这个错误:
\nValue of type \'some View\' has no member \'stroke\'\nRun Code Online (Sandbox Code Playgroud)\n我无法弄清楚,这是怎么回事?我该如何修复它?
\n请尝试帮助我以某种方式修复它,我作为初学者会理解
\n顺便说一句,Diamond() 是我的自定义 Shape(如 Rectangle())。\n如果您还需要 ViewModel、Model 或其他一些文件来帮助我修复它,请告诉我:-)
\nstroke是在 上定义的Shape,而不是在上定义的,View并且您返回的是Shapes,而不仅仅是Views。您需要将返回类型更改shape为some Shape。
遗憾的@ViewBuilder是,需要返回类型为some View,而不是some Shape,因此您需要删除该@ViewBuilder属性并确保您的函数Shape从每个分支返回相同的值。为了实现这一点,您可以实现一个类型擦除的Shape,AnyShape类似于AnyViewfor的调用View,并返回每个的类型擦除版本Shape。
struct AnyShape: Shape {
init<S: Shape>(_ wrapped: S) {
_path = { rect in
let path = wrapped.path(in: rect)
return path
}
}
func path(in rect: CGRect) -> Path {
return _path(rect)
}
private let _path: (CGRect) -> Path
}
func shape(_ shape: SetGameModel.Card.Shape) -> some Shape {
if shape == .diamond {
return AnyShape(Diamond())
} else if shape == .squiggle {
return AnyShape(Rectangle())
} else {
return AnyShape(Ellipse())
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6577 次 |
| 最近记录: |