在 SwiftUI 中,我有两个结构来包装形状,一个有效,一个无效,但我没有看到两者有任何功能差异



我已经包装了两个形状结构。 一个工作,另一个编译和运行 - 但总是在屏幕上呈现一个空白区域。然而,我没有看到这两个结构的功能有任何关键区别......阻止它呈现为视图的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

在第二种情况下,您使用空CGRectCGRect()预先创建了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>表示CircleAnyShape<Rectangle>表示Rectangle等。 在这种情况下,我会坚持使用使用闭包来捕获ShapeAnyShape,或者如果您希望从函数返回多个Shape类型,则可以将func@ViewBuilder

相关内容

最新更新