You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中屏幕旋转时保持BezierPath位置与对齐的方法

解决SwiftUI中BezierPath横竖屏对齐问题

问题核心在于原ScaledBezier的路径是左上角对齐容器缩放,加上第二个路径的独立缩放变换,导致横竖屏切换时对齐关系失效。我们需要让路径始终居中于容器,确保两个路径的变换基准一致。

修改后的完整代码

struct TestView: View {
    var body: some View {
        ZStack {
            // 基础路径
            ScaledBezier(bezierPath: .logo)
                .stroke(lineWidth: 1.0)
            // 放大2倍的路径,线宽除以2保持视觉一致
            ScaledBezier(bezierPath: .logo)
                .stroke(lineWidth: 0.5)
                .scaleEffect(2)
        }
    }
}

struct ScaledBezier: Shape {
    let bezierPath: UIBezierPath

    func path(in rect: CGRect) -> Path {
        let path = Path(bezierPath.cgPath)
        let pathBounds = path.boundingRect
        
        // 1. 将路径中心平移到原点,统一变换基准
        let centerToOrigin = CGAffineTransform(translationX: -pathBounds.midX, y: -pathBounds.midY)
        let centeredPath = path.applying(centerToOrigin)
        
        // 2. 计算等比例缩放倍数,确保路径不超出容器
        let scale = min(rect.width / pathBounds.width, rect.height / pathBounds.height)
        
        // 3. 先缩放,再平移到容器中心
        let finalTransform = CGAffineTransform(scaleX: scale, y: scale)
            .translatedBy(x: rect.midX, y: rect.midY)
        
        return centeredPath.applying(finalTransform)
    }
}

extension UIBezierPath {
    static var logo: UIBezierPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0.534, y: 0.5816))
        path.addCurve(to: CGPoint(x: 0.1877, y: 0.088), controlPoint1: CGPoint(x: 0.534, y: 0.5816), controlPoint2: CGPoint(x: 0.2529, y: 0.4205))
        path.addCurve(to: CGPoint(x: 0.9728, y: 0.8259), controlPoint1: CGPoint(x: 0.4922, y: 0.4949), controlPoint2: CGPoint(x: 1.0968, y: 0.4148))
        path.addCurve(to: CGPoint(x: 0.0397, y: 0.5431), controlPoint1: CGPoint(x: 0.7118, y: 0.5248), controlPoint2: CGPoint(x: 0.3329, y: 0.7442))
        path.addCurve(to: CGPoint(x: 0.6211, y: 0.0279), controlPoint1: CGPoint(x: 0.508, y: 1.1956), controlPoint2: CGPoint(x: 1.3042, y: 0.5345))
        path.addCurve(to: CGPoint(x: 0.6904, y: 0.3615), controlPoint1: CGPoint(x: 0.7282, y: 0.2481), controlPoint2: CGPoint(x: 0.6904, y: 0.3615))
        return path
    }
}

关键修改点

  • 路径居中处理:先将路径的中心平移到原点,确保缩放变换的基准点统一为路径中心,再平移到容器中心,避免横竖屏切换时位置偏移。
  • 线宽调整:由于scaleEffect(2)会同时缩放路径和线宽,将第二个路径的线宽设置为0.5(原线宽的1/2),保持视觉上的线宽一致。
  • 等比例缩放:使用min(rect.width / pathBounds.width, rect.height / pathBounds.height)计算缩放倍数,确保路径始终按比例适配容器,不会被拉伸或裁剪。

这样修改后,无论屏幕如何旋转,两个BezierPath都会保持中心对齐的相对位置关系。

内容的提问来源于stack exchange,提问作者micah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 11:55:20