为什么这个自定义形状会占据整个垂直 space?

Why does this custom shape take up the entire vertical space?

我想知道为什么这个只是一个字母模板的自定义形状会占据整个 space 视图?我从来没有画过一条需要那么垂直的线 space 所以我想知道发生了什么事。

这是它的外观示例。

您可以看到图像在垂直方向几乎翻了一番。

这是带有父视图的形状的代码

 import SwiftUI
    
    struct ParentView: View {
       var body: some View {
       VStack {
           Spacer()
           LetterPreviewShape()
       }
    }

}


    struct LetterPreviewShape: Shape {
        func path(in rect: CGRect) -> Path {
            let startingPoint = CGPoint(x: rect.minX, y: rect.minY)
            let paragraphStartingPoint = CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.1)
            
            var path = Path()
            
            //Letter outline
            path.move(to: startingPoint)
            path.addLine(to: CGPoint(x: rect.maxX, y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.minX, y: rect.midY))
            path.closeSubpath()
            
            //Greeting Line
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.07))
            path.addLine(to: CGPoint(x: rect.maxX * 0.3, y: rect.maxY * 0.07))
            
            
            //Body Strokes
            path.move(to: paragraphStartingPoint)
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.1))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.11))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.11))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.12))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.12))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.13))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.13))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.14))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.14))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.15))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.15))
            
            path.move(to: CGPoint(x: rect.maxX * 0.1, y: rect.maxY * 0.16))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.16))
            
           //Signature Line
            path.move(to: CGPoint(x: rect.maxX * 0.7, y: rect.maxY * 0.18))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.18))
            
            path.move(to: CGPoint(x: rect.maxX * 0.7, y: rect.maxY * 0.19))
            path.addLine(to: CGPoint(x: rect.maxX * 0.9, y: rect.maxY * 0.19))
            
            return path
        }
    }
SwiftUI 中的

Shapes 总是填充可用的 space。它与您绘制内容的位置没有任何关系。

您也可以看到这种行为与非自定义系统形状一起复制——如果您只使用 RectangleCircle,它们也会填充可用的 space.

要限制它,给它一个 frame -- 如果你需要它基于可用大小,可以与 GeometryReader 一起使用。

例如:

struct ContentView : View {
    var body: some View {
        GeometryReader { geometry in
            VStack {
                Spacer().frame(height: geometry.size.height / 2)
                Rectangle().fill(Color.red).frame(height: geometry.size.height / 2)
            }
        }
    }
}

Shape 没有自己的框架,所以你必须在外部给它一个框架(或者它填充所有可用的东西),比如

struct ParentView: View {
    var body: some View {
       VStack {
           Spacer()
           LetterPreviewShape()
              .frame(height: 200)   // << this goes in `func path(in rect: CGRect) -> Path`
       }
    }
}