我已经包装了两个形状结构。 一个工作,另一个编译和运行 - 但总是在屏幕上呈现一个空白区域。然而,我没有看到这两个结构的功能有任何关键区别......阻止它呈现为视图的AnyShape_AlwaysBlank
有什么不同?
import SwiftUI
import PlaygroundSupport
struct AnyShape_Working: Shape {
private let someShapePath: (CGRect) -> Path
// required to conform to Shape
public func path(in rect: CGRect) -> Path {
someShapePath(rect)
}
init<S: Shape>(_ someShape: S) {
someShapePath = { rect in
someShape.path(in: rect)
}
}
}
struct AnyShape_AlwaysBlank: Shape {
private let someShapePath: Path
// required to conform to Shape
public func path(in rect: CGRect) -> Path {
someShapePath
}
init<S: Shape>(_ someShape: S) {
let rect = CGRect()
someShapePath = someShape.path(in: rect)
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Circle will appear below")
AnyShape_Working( Circle() )
Text("Blank area will appear below")
AnyShape_AlwaysBlank( Circle() )
}
}
}
PlaygroundPage.current.setLiveView( ContentView() )
在第一种情况下,当调用path(in rect: CGRect) -> Path
时,它实际上使用传递rect
来创建Path
。
在第二种情况下,您使用空CGRect
CGRect()
预先创建了Path
,因此返回的路径适合空rect
。 然后,当调用path(in rect: CGRect) -> Path
时,您将忽略rect
参数,而只是返回预先创建的Path
。
另一种方法是使结构通用,然后存储Shape
:
struct AnyShape<S: Shape>: Shape {
private let someShape: S
// required to conform to Shape
public func path(in rect: CGRect) -> Path {
someShape.path(in: rect)
}
init(_ someShape: S) {
self.someShape = someShape
}
}
注意:如果要使用AnyShape
将所有Shape
统一为单个类型,则此泛型版本不会这样做,因为它为每个输入形状返回不同的类型:AnyShape<Circle>
表示Circle
,AnyShape<Rectangle>
表示Rectangle
等。 在这种情况下,我会坚持使用使用闭包来捕获Shape
的AnyShape
,或者如果您希望从函数返回多个Shape
类型,则可以将func
@ViewBuilder
。