75142913在线留言
【SwiftUI基础篇】17 各种形状 Circle 圆形、Rectangle矩形、Capsule胶囊形等_IOS开发_网络人

【SwiftUI基础篇】17 各种形状 Circle 圆形、Rectangle矩形、Capsule胶囊形等

Kwok 发表于:2021-04-06 14:06:18 点击:149 评论: 0

SwiftUI为我们提供了很多种图形的绘制,各个形状没有什么特别的地方,只需要根据文档中的构造函数进行初始化就好了, 形状会尽量充满父视图给予的空间,所以可以通过调整父视图或者 .frame 之类的,方式调整他们的形状和尺寸。

SwiftUI为我们提供了五个常用的内置形状:矩形,圆角矩形,圆形,椭圆形和胶囊形。根据提供的尺寸,最后三个尤其在行为上有细微的差别,但是我们可以通过一个示例来演示所有选项:

一、基本使用:

Capsule()//胶囊型:是一种特殊的圆角矩形,其圆角的半径等于变长的一半
Circle()//圆形
Ellipse()//椭圆
Rectangle()//长方形
RoundedRectangle(cornerRadius: 25.0)//圆角矩形
RoundedRectangle(cornerSize: CGSize(width: 25, height: 50))//椭圆角矩形

或者对其进行修改:

ZStack {
    Rectangle()
        .fill(Color.black)
        .frame(width: 200, height: 200)
    
    RoundedRectangle(cornerRadius: 25, style: .continuous)
        .fill(Color.red)
        .frame(width: 200, height: 200)
    
    Capsule()
        .fill(Color.green)
        .frame(width: 100, height: 50)
    
    Ellipse()
        .fill(Color.blue)
        .frame(width: 100, height: 50)
    
    Circle()
        .fill(Color.white)
        .frame(width: 100, height: 50)
}

绘制所有五个形状:两个以200x200绘制,三个以100x50绘制。但是,由于形状的绘制行为不同,因此您会在输出中看到所有五个形状:

  • Rectangle 在您指定的确切尺寸处绘制一个框。
  • RoundedRectangle这样做是一样的,除了现在您可以将拐角处达到一定的数量。它的第二个参数,style确定您是要使用经典的圆角(.circular)还是要使用Apple稍平滑的替代品(.continuous)。
  • Capsule绘制一个框,该框的边缘轴完全变圆,具体取决于高度或宽度是否最大。我们的形状是100x50,因此它的左右边缘将变圆,而上边缘和下边缘则笔直。
  • Ellipse 在您指定的确切尺寸处绘制一个椭圆。
  • Circle 在高度和宽度相等的地方绘制一个椭圆,因此当我们为空间提供100x50时,实际上将得到50x50。

二、对形状美化显示:

为了统一说明,先定义一个可以对图形进行美化的视图结构:

struct ShapeWithLabel: View where Content: View {
    let shape: Content //传入图形
    let label: String //图形的名字显示
    
    var body: some View {
        VStack {
            Text(label)
            shape
                .foregroundColor(.blue)//图形统一设置为蓝色
        }
        .frame(height: 100)
        .padding()
    }
}

下面就可以使用表格排列图片显示了:

LazyVGrid(columns: [GridItem(.adaptive(minimum: 100, maximum: 200))]) {
    ShapeWithLabel(shape: Capsule(), label: "胶囊型")
    ShapeWithLabel(shape: Circle(), label: "圆形")
    ShapeWithLabel(shape: Ellipse(), label: "椭圆")
    ShapeWithLabel(shape: Rectangle(), label: "长方形")
    ShapeWithLabel(shape: RoundedRectangle(cornerRadius: 25.0), label: "圆角矩形")
    ShapeWithLabel(shape: RoundedRectangle(cornerSize: CGSize(width: 25, height: 50)), label: "椭圆角矩形")
}

三、利用路径自定义一个图形

SwiftUI启用具有两种不同类型的自定义绘图:路径和形状。路径是一系列绘制指令,例如“从此处开始,在此处绘制线,然后在此处添加圆”,所有这些指令均使用绝对坐标。相反,形状不知道将在何处使用或将使用多大的形状,而是会要求其在给定的矩形内绘制自身。

有用的是,形状是使用路径构建的,因此一旦了解路径,形状就很容易。而且,就像路径,颜色和渐变一样,形状也是视图,这意味着我们可以将它们与文本视图,图像等一起使用。

SwiftUIShape使用一个必需的方法作为协议来实现:给定以下矩形,您想绘制什么路径?这仍然会像直接使用原始路径一样创建并返回路径,但是由于我们已经掌握了尺寸,因此将使用形状,因为我们确切知道绘制路径的大小–我们不再需要依赖固定的坐标。

例如,以前我们使用来创建了一个三角形Path,但是我们可以将其包装成一个形状以确保它自动占用所有可用空间,如下所示:

//遵循Shape协议就可以画一个三角形
struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()//路径        
        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))        
        return path
    }
}

通过CGRect,该工作变得更加容易,它提供了有用的属性,例如minX(矩形中的最小X值),maxX(矩形中的最大X值)和midX(minX和之间的中点maxX)。

然后,我们可以创建一个精确尺寸的红色三角形,如下所示:

Triangle()
    .fill(Color.red)
    .frame(width: 300, height: 300)

或者:

ShapeWithLabel(shape: Triangle(), label: "三角形")

理解之间的区别的关键Path,并Shape为可重用性:路径的设计做一个具体的东西,而形状具有绘画空间的灵活性,还可以接受的参数让我们进一步对其进行自定义。

为了说明这一点,我们可以创建一个Arc接受三个参数的形状:起始角度,终止角度以及是否顺时针绘制圆弧。这似乎很简单,尤其是因为它Path有一个addArc()方法,但是如您所见,它有几个有趣的怪癖。

让我们从最简单的弧形开始:

struct Arc: Shape {
    var startAngle: Angle
    var endAngle: Angle
    var clockwise: Bool

    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2, startAngle: startAngle, endAngle: endAngle, clockwise: clockwise)

        return path
    }
}

我们现在可以像这样创建一个弧:

Arc(startAngle: .degrees(0), endAngle: .degrees(110), clockwise: true)
    .stroke(Color.blue, lineWidth: 10)
    .frame(width: 300, height: 300)

如果您查看我们弧线的预览,很可能它看起来并不像您期望的那样。我们要求顺时针旋转的弧度是从0度到110度,但逆时针旋转的弧度似乎是从90度到200度。

这里发生了两件事:

  1. 在SwiftUI看来,0度不是笔直向上,而是直接向右。
  2. 形状是从左下角而不是左上角开始测量坐标的,这意味着SwiftUI从一个角度到另一个角度都以相反的方式进行测量。在我看来,这是非常陌生的。

我们可以使用一种新path(in:)方法来解决这两个问题,该新方法将从起始角度和终止角度减去90度,并反转方向,以便SwiftUI遵循自然预期的方式:

func path(in rect: CGRect) -> Path {
    let rotationAdjustment = Angle.degrees(90)
    let modifiedStart = startAngle - rotationAdjustment
    let modifiedEnd = endAngle - rotationAdjustment

    var path = Path()
    path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2, startAngle: modifiedStart, endAngle: modifiedEnd, clockwise: !clockwise)

    return path
}

 充分利用路径可以画出很多漂亮的图标,SVG也是通过这样的方式实现图标渲染的。 

除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/131
标签:图形圆形矩形Kwok最后编辑于:2021-04-06 15:06:59
0
感谢打赏!

《【SwiftUI基础篇】17 各种形状 Circle 圆形、Rectangle矩形、Capsule胶囊形等》的网友评论(0)

本站推荐阅读

热门点击文章