【问题标题】:How to scale Path in SwiftUI?如何在 SwiftUI 中缩放路径?
【发布时间】:2021-03-08 11:28:35
【问题描述】:

我在根据我的目的缩放Path 时遇到一些问题。我从 API 获取一些我想在视图中绘制的 SVG 数据。为了简单起见,假设这是我从 API 中得到的:

extension UIBezierPath {
    static var rectangle: UIBezierPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 200, y: 100))
        path.addLine(to: CGPoint(x: 100, y: 300))
        path.addLine(to: CGPoint(x: 300, y: 300))
        path.addLine(to: CGPoint(x: 200, y: 100))
        return path
    }
}

当我在视图中显示此路径时,一切正常。

由于来自 API 的 SVG 坐标有偏移并且有时比 iPhone 的显示屏大,因此我需要将它们缩小/放大到特定大小并在我的视图中居中。为了做到这一点,我尝试了这种转换:

struct ScaledShapeView: Shape {
    let bezier: UIBezierPath

    func path(in rect: CGRect) -> Path {
        let bounds = bezier.bounds
        let scaleX = rect.size.width/bounds.size.width
        let scaleY = rect.size.height/bounds.size.height
        let scale = max(scaleX, scaleY)
        return Path(bezier.cgPath).applying(CGAffineTransform(scaleX: scale, y: scale))
    }
}

并在我看来使用它:

struct TestView: View {    
    var body: some View {
            ScaledShapeView(bezier: .rectangle)
                .frame(width: 100, height: 100)
    }
}

但这是我的结果:

我不确定到底是什么问题。我想实现形状在框架的中间。

@SwiftPunk:

当我尝试时

var body: some View {
    Path(UIBezierPath.logo1.cgPath)
            .frame(width: 100, height: 100)
            .scaleEffect(CGSize(width: 0.5, height: 0.5))
}

我得到这个结果:

【问题讨论】:

  • 使用 CGPath 和 UIBezierPath 不是更好吗?似乎 SwiftUI 代码应该尽可能保持 UIKit 代码的清洁。

标签: swiftui uibezierpath


【解决方案1】:

标准化每个 X 和 Y 位置以绘制 0 和 1 之间的点,其中 0 表示上边缘或前边缘,1 表示下边缘或后边缘。

此外,我们将找到宽度和高度的最小值,以便我们可以按比例缩放贝塞尔路径,使其在增长时保持相同的形状。

import SwiftUI


extension UIBezierPath{
    static var rectangle: UIBezierPath {
        let path = UIBezierPath()
        path.move(to: CGPoint(x: 0.5, y: 0.2))
        path.addLine(to: CGPoint(x: 0.2, y: 0.8))
        path.addLine(to: CGPoint(x: 0.8, y: 0.8))
        path.addLine(to: CGPoint(x: 0.5, y: 0.2))
        return path
    }
}

struct ScaledShapeView:Shape{
    var bezier:UIBezierPath
    func path(in rect: CGRect) -> Path {
        let path = Path(bezier.cgPath)
        let multiplier = min(rect.width,rect.height)
       
        let transform = CGAffineTransform(scaleX:multiplier , y: multiplier)
        
        return path.applying(transform)
    }
}

struct TestView: View {
    @State private var endAmount: CGFloat = 0
    var body: some View {
        ScaledShapeView(bezier: UIBezierPath.rectangle)
            .frame(width: 300, height: 300)
        }
    }

输出-:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-28
    • 2021-09-02
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2020-04-08
    • 1970-01-01
    相关资源
    最近更新 更多