美文网首页SwiftUI
SwiftUI - 图形绘制

SwiftUI - 图形绘制

作者: 西西的一天 | 来源:发表于2020-02-01 18:29 被阅读0次

    在UIKit中的图形绘制大多都是基于Quartz2D的,它的API使用起来较为繁琐,使用不当时还会导致性能问题。SwiftUI在这方面做了改进,使得绘制图形变成一件简单的事情。

    通过几个例子来了解一下常用API,其中包括,基础图形,直线,曲线。

    基础图形

    使用方法很简单,初始化一个Rectangle,在添加一个frame修饰符,在添加一个fill修饰符用于填充颜色即可。为了达到演示的效果,我们稍微丰富一下,使用几个额外的修饰符,代码如下:

    GeometryReader { geometry in
        ZStack {
            ForEach(0..<3) { i in
                Rectangle()
                    .fill(
                        LinearGradient(gradient: .init(colors: [.green, .blue]), startPoint: .init(x: 0, y: 1), endPoint: .init(x: 1, y: 0))
                    )
                    .frame(width: geometry.size.width * 0.7, height: geometry.size.width * 0.7)
                    .rotationEffect(.degrees(Double(i) * 60))
            }
            Image("baymax-white")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: geometry.size.width * 0.5)
        }
    }
    

    效果图如下所示:


    rectangle.png

    其中,fill可以传入一个颜色,或如示例中的渐变色;ForEach可以遍历生成一组view,在示例中生成了三个矩形,每个矩形根据当前index和rotationEffect旋转一定的角度。比较特别的是一个容器对象GeometryReader,通过这个容器,可以得到容器内部元素的size。其他的形状如:Circle,Ellipse,Rounded Rectangle,Capsule可以如法炮制。

    Path

    1. 直线
      当内建的形状不能满足需求时,可以使用Path来自己绘制一个图形,示例代码中通过Path绘制了一个简单的梯形:
    Path { path in
        path.move(to: CGPoint(x: 120, y: 20))
        path.addLine(to: CGPoint(x: 180, y: 180))
        path.addLine(to: CGPoint(x: 20, y: 180))
        path.addLine(to: CGPoint(x: 80, y: 20))
    }
    

    看一个稍微复杂一点的实例:

    GeometryReader { geometry in
        ZStack {
            Path { path in
                let size = min(geometry.size.width, geometry.size.height)
                let nearLine = size * 0.1
                let farLine = size * 0.9
                path.move(to: CGPoint(x: size / 2 + nearLine, y: nearLine))
                path.addLine(to: CGPoint(x: farLine, y: farLine))
                path.addLine(to: CGPoint(x: nearLine, y: farLine))
                path.addLine(to: CGPoint(x: size / 2 - nearLine, y: nearLine))
            }
            .fill(Color.init(red: 0.4, green: 0.4, blue: 0.4))
            
            Path { path in
                let size = min(geometry.size.width, geometry.size.height)
                let nearLine = size * 0.1
                let farLine = size * 0.9
                let middle = size / 2
                path.move(to: .init(x: middle, y: farLine))
                path.addLine(to: .init(x: middle, y: nearLine))
            }
            .stroke(Color.white, style: .init(lineWidth: 3.0, dash: [geometry.size.width / 20, geometry.size.width / 30], dashPhase: 0))
            
            Image(systemName: "car.fill")
                .resizable()
                .frame(width: geometry.size.width / 4, height: geometry.size.width / 4)
                .foregroundColor(Color.white)
                .offset(x: -geometry.size.width / 6.72, y: -geometry.size.width / 2.75)
        }
    }
    

    示例代码的效果图如下所示:


    path.png
    1. 曲线
      绘制曲线同样使用Path,不同的是将addLine改为addQuadCurve,在addQuadCurve中除了指定终点外,还需要一个control point,示例代码如下所示:
    GeometryReader { geometry in
        HStack {
            Path { path in
                let size = min(geometry.size.width, geometry.size.height)
                let nearLine = size * 0.1
                let farLine = size * 0.9
                let mid = size / 2
                path.move(to: .init(x: mid, y: nearLine))
                path.addQuadCurve(to: .init(x: farLine, y: mid), control: .init(x: size, y: 0))
                path.addQuadCurve(to: .init(x: mid, y: farLine), control: .init(x: size, y: size))
                path.addQuadCurve(to: .init(x: nearLine, y: mid), control: .init(x: 0, y: size))
                path.addQuadCurve(to: .init(x: mid, y: nearLine), control: .init(x: 0, y: 0))
            }
            .fill(Color.yellow)
        }
    }
    

    绘制的结果如下图所示:


    curv.png

    题外话

    当使用Image元素时,会发现它不受frame修饰符的控制,在屏幕上始终显示图片的原始大小。若希望将它约束在frame所指定的范围内时,需要添加resizable修饰符,此时它的长宽比例将随frame的宽高改变,呈现一个stretch状态。若想继续保留原有比例,则需要另一个修饰符aspectRatio

    相关文章

      网友评论

        本文标题:SwiftUI - 图形绘制

        本文链接:https://www.haomeiwen.com/subject/yxsxxhtx.html