SwiftUI 教程中的角被切断

问题描述 投票:0回答:1

Apple SwiftUI 教程:绘制路径和形状中,完成第 2 部分第 8 步后,将徽章的两个顶角和底角切掉。在添加渐变之前,形状完全正常(第 2 节第 8 步),但随后角被切断。Xcode 中预览的图像

这是我的代码,我仔细检查了教程:

import SwiftUI

struct BadgeBackground: View {
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                var width: CGFloat = min(geometry.size.width, geometry.size.height)
                let height = width
                let xScale: CGFloat = 0.832
                let xOffset = (width * (1.0 - xScale)) / 2.0
                width *= xScale
                path.move(
                    to: CGPoint(
                        x: width * 0.95 + xOffset,
                        y: height * (0.20 + HexagonParameters.adjustment)
                    )
                )
                
                HexagonParameters.segments.forEach { segment in
                    path.addLine(
                        to: CGPoint(
                            x: width * segment.line.x + xOffset,
                            y: height * segment.line.y
                        )
                    )
                    
                    path.addQuadCurve(
                        to: CGPoint(
                            x: width * segment.curve.x + xOffset,
                            y: height * segment.curve.y
                        ),
                        control: CGPoint(
                            x: width * segment.control.x + xOffset,
                            y: height * segment.control.y
                        )
                    )
                }
            }
            .fill(.linearGradient(
                Gradient(colors: [Self.gradientStart, Self.gradientEnd]),
                startPoint: UnitPoint(x: 0.5, y: 0),
                endPoint: UnitPoint(x: 0.5, y: 0.6)
            ))
        }
        .aspectRatio(1, contentMode: .fit)
    }
    static let gradientStart = Color(red: 239.0 / 255, green: 120.0 / 255, blue: 221.0 / 255)
    static let gradientEnd = Color(red: 239.0 / 255, green: 172.0 / 255, blue: 120.0 / 255)
}

#Preview {
    BadgeBackground()
}

完成第 2 部分后,我注意到角落不见了。我回顾了我的步骤,发现只有当我在步骤 8 中添加渐变时,角才被切断。

ios swift swiftui
1个回答
0
投票

如果在线性渐变之前添加额外的

.fill()
语句,就会变得很有趣:

Path { path in
    // ...
}
.fill() // 👈 HERE
.fill(.linearGradient(
    // ...
))

这就是你所看到的:

Screenshot

一个可能的解释如下:

  • 本例中的渐变是垂直渐变,从顶部边缘的中心
    (x: 0.5, y: 0)
    开始,到高度的6/10
    (x: 0.5, y: 0.6)
  • 为了确定梯度如何拟合形状,梯度填充算法需要知道形状中最小点和最大点的绝对位置。
  • 似乎找到最小点和最大点的方法只是检查路径中点的坐标。
  • 不幸的是,这样做并没有考虑四边形曲线的控制点。控制点导致路径中的曲线高于最小 y 值并低于最大 y 值。

→ 所以这似乎是一个错误。

如果您对解决方法感兴趣,您可以使用实心填充表单作为

.mask
而非
LinearGradient
。然而,即使在这里,也需要在填写的表格中添加
.geometryGroup()
,否则会出现相同的错误。

LinearGradient(
    colors: [Self.gradientStart, Self.gradientEnd],
    startPoint: .top,
    endPoint: UnitPoint(x: 0.5, y: 0.6)
)
.mask {
    GeometryReader { geometry in
        Path { path in
            // ... as before
        }
        .fill()
    }
    .geometryGroup() // ⚠️ IMPORTANT
}
.aspectRatio(1, contentMode: .fit)

Screenshot

© www.soinside.com 2019 - 2024. All rights reserved.