Error: Value of type 'some View' has no member 'stroke'
Error: Value of type 'some View' has no member 'stroke'
我正在关注 Stanfords' CS193p Developing Apps for iOS online course。
我正在使用 Xcode 11.5。 (我没有更新,因为那是课程讲师 (Paul Heagarty) 使用的版本。)
我正在尝试 Assignment 3 (Set Game)。目前(为了避免重复代码)我正在尝试替换这个片段:
VStack {
ForEach(0..<numberOfShapes) { index in
if self.card.shape == .diamond {
ZStack {
Diamond().fill()
.opacity(self.opacity)
Diamond().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
if self.card.shape == .squiggle {
ZStack {
Rectangle().fill()
Rectangle().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
if self.card.shape == .oval {
ZStack {
Ellipse().fill()
Ellipse().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
}
}
有了这个片段:
VStack {
ForEach(0..<numberOfShapes) { index in
ZStack {
shape(self.card.shape).opacity(self.opacity)
shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type 'some View' has no member 'stroke'
}
}
}
还有这个@ViewBuilder 函数:
@ViewBuilder
func shape(_ shape: SetGameModel.Card.Shape) -> some View {
if shape == .diamond {
Diamond()
} else if shape == .squiggle {
Rectangle()
} else {
Ellipse()
}
}
这是完整的查看代码:
import SwiftUI
struct SetGameView: View {
@ObservedObject var viewModel: SetGameViewModel
var body: some View {
Grid(viewModel.cards) { card in
CardView(card: card).onTapGesture {
self.viewModel.choose(card: card)
}
.padding(5)
}
.padding()
.foregroundColor(Color.orange)
}
}
struct CardView: View {
var card: SetGameModel.Card
var numberOfShapes: Int {
switch card.numberOfShapes {
case .one:
return 1
case .two:
return 2
case .three:
return 3
}
}
var opacity: Double {
switch card.shading {
case .open:
return 0.0
case .solid: // filled
return 1.0
case .striped: // you can use a semi-transparent color to represent the “striped” shading.
return 0.33
}
}
var color: Color {
switch card.color {
case .green:
return Color.green
case .purple:
return Color.purple
case .red:
return Color.red
}
}
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: cornerRadius).fill(Color.white)
RoundedRectangle(cornerRadius: cornerRadius)
.stroke(lineWidth: card.isChosen ? chosenCardEdgeLineWidth : normalCardEdgeLineWidth)
.foregroundColor(card.isChosen ? Color.red : Color.orange)
VStack {
ForEach(0..<numberOfShapes) { index in
ZStack {
shape(self.card.shape).opacity(self.opacity)
shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type 'some View' has no member 'stroke'
}
}
}
.foregroundColor(self.color)
.padding()
}
.aspectRatio(cardAspectRatio, contentMode: .fit)
}
// MARK: - Drawing Constants
let cornerRadius: CGFloat = 10.0
let chosenCardEdgeLineWidth: CGFloat = 6
let normalCardEdgeLineWidth: CGFloat = 3
let shapeEdgeLineWidth: CGFloat = 2.5
let cardAspectRatio: CGSize = CGSize(width: 2, height: 3) // 2/3 aspectRatio
}
@ViewBuilder
func shape(_ shape: SetGameModel.Card.Shape) -> some View {
if shape == .diamond {
Diamond()
} else if shape == .squiggle {
Rectangle()
} else {
Ellipse()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
SetGameView(viewModel: SetGameViewModel())
}
}
我有这个错误:
Value of type 'some View' has no member 'stroke'
我搞不懂,怎么了?我该如何解决?
请尝试以某种方式帮助我修复它,作为初学者我会理解
顺便说一下,Diamond() 是我的自定义形状(如 Rectangle())。
如果您还需要 ViewModel、Model 或其他一些文件来帮助我修复它,请告诉我:-)
stroke
是在 Shape
上定义的,而不是 View
并且您正在 returning Shape
s,而不仅仅是 View
s。您需要将 shape
的 return 类型更改为 some Shape
。
遗憾的是 @ViewBuilder
需要 return 类型为 some View
,而不是 some Shape
,因此您需要删除 @ViewBuilder
属性并确保您的每个分支的功能 return 与 Shape
相同。为此,您可以实现类型擦除的 Shape
,称为 AnyShape
,类似于 AnyView
用于 View
和 return 每个 [= 的类型擦除版本12=].
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())
}
}
我正在关注 Stanfords' CS193p Developing Apps for iOS online course。 我正在使用 Xcode 11.5。 (我没有更新,因为那是课程讲师 (Paul Heagarty) 使用的版本。)
我正在尝试 Assignment 3 (Set Game)。目前(为了避免重复代码)我正在尝试替换这个片段:
VStack {
ForEach(0..<numberOfShapes) { index in
if self.card.shape == .diamond {
ZStack {
Diamond().fill()
.opacity(self.opacity)
Diamond().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
if self.card.shape == .squiggle {
ZStack {
Rectangle().fill()
Rectangle().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
if self.card.shape == .oval {
ZStack {
Ellipse().fill()
Ellipse().stroke(lineWidth: self.shapeEdgeLineWidth)
}
}
}
}
有了这个片段:
VStack {
ForEach(0..<numberOfShapes) { index in
ZStack {
shape(self.card.shape).opacity(self.opacity)
shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type 'some View' has no member 'stroke'
}
}
}
还有这个@ViewBuilder 函数:
@ViewBuilder
func shape(_ shape: SetGameModel.Card.Shape) -> some View {
if shape == .diamond {
Diamond()
} else if shape == .squiggle {
Rectangle()
} else {
Ellipse()
}
}
这是完整的查看代码:
import SwiftUI
struct SetGameView: View {
@ObservedObject var viewModel: SetGameViewModel
var body: some View {
Grid(viewModel.cards) { card in
CardView(card: card).onTapGesture {
self.viewModel.choose(card: card)
}
.padding(5)
}
.padding()
.foregroundColor(Color.orange)
}
}
struct CardView: View {
var card: SetGameModel.Card
var numberOfShapes: Int {
switch card.numberOfShapes {
case .one:
return 1
case .two:
return 2
case .three:
return 3
}
}
var opacity: Double {
switch card.shading {
case .open:
return 0.0
case .solid: // filled
return 1.0
case .striped: // you can use a semi-transparent color to represent the “striped” shading.
return 0.33
}
}
var color: Color {
switch card.color {
case .green:
return Color.green
case .purple:
return Color.purple
case .red:
return Color.red
}
}
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: cornerRadius).fill(Color.white)
RoundedRectangle(cornerRadius: cornerRadius)
.stroke(lineWidth: card.isChosen ? chosenCardEdgeLineWidth : normalCardEdgeLineWidth)
.foregroundColor(card.isChosen ? Color.red : Color.orange)
VStack {
ForEach(0..<numberOfShapes) { index in
ZStack {
shape(self.card.shape).opacity(self.opacity)
shape(self.card.shape).stroke(lineWidth: 2.5) // ERROR here: Value of type 'some View' has no member 'stroke'
}
}
}
.foregroundColor(self.color)
.padding()
}
.aspectRatio(cardAspectRatio, contentMode: .fit)
}
// MARK: - Drawing Constants
let cornerRadius: CGFloat = 10.0
let chosenCardEdgeLineWidth: CGFloat = 6
let normalCardEdgeLineWidth: CGFloat = 3
let shapeEdgeLineWidth: CGFloat = 2.5
let cardAspectRatio: CGSize = CGSize(width: 2, height: 3) // 2/3 aspectRatio
}
@ViewBuilder
func shape(_ shape: SetGameModel.Card.Shape) -> some View {
if shape == .diamond {
Diamond()
} else if shape == .squiggle {
Rectangle()
} else {
Ellipse()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
SetGameView(viewModel: SetGameViewModel())
}
}
我有这个错误:
Value of type 'some View' has no member 'stroke'
我搞不懂,怎么了?我该如何解决?
请尝试以某种方式帮助我修复它,作为初学者我会理解
顺便说一下,Diamond() 是我的自定义形状(如 Rectangle())。 如果您还需要 ViewModel、Model 或其他一些文件来帮助我修复它,请告诉我:-)
stroke
是在 Shape
上定义的,而不是 View
并且您正在 returning Shape
s,而不仅仅是 View
s。您需要将 shape
的 return 类型更改为 some Shape
。
遗憾的是 @ViewBuilder
需要 return 类型为 some View
,而不是 some Shape
,因此您需要删除 @ViewBuilder
属性并确保您的每个分支的功能 return 与 Shape
相同。为此,您可以实现类型擦除的 Shape
,称为 AnyShape
,类似于 AnyView
用于 View
和 return 每个 [= 的类型擦除版本12=].
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())
}
}