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
相关产品推荐
相关产品推荐

