如果创建的形状没有特定大小,它将自动扩展以占据所有可用空间。例如,这将创建一个填充我们视图的圆,并为其提供40点蓝色边框:

struct ContentView: View {

var body: some View {

Circle()

.stroke(Color.blue, lineWidth: 40)

}

}

stroke() 绘制

仔细观察边框的左右边缘——您注意到边框是怎么被切掉的吗?

您在这里看到的是SwiftUI在形状周围绘制边框的方式的副作用。如果您递给某人一个圆的铅笔轮廓,并要求他们用粗笔在该圆上画线,他们将绘制出该圆的精确线——大约一半的笔在该线的内部,一半在该线的外部。这就是SwiftUI为我们所做的,但是当形状到达屏幕边缘时,则意味着边框的外部最终超出了屏幕边缘。

现在尝试改用这个圆:

Circle()

.strokeBorder(Color.blue, lineWidth: 40)

strokeBorder() 绘制

这将stroke()更改为strokeBorder(),现在我们得到了更好的结果:我们的所有边框都是可见的,因为Swift在圆的内部绘制而不是将圆作为绘制的中心。

之前我们建立了一个如下的弧形:

struct Arc: Shape {

var startAngle: Angle

var endAngle: Angle

var clockwise: Bool

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

}

}

就像Circle一样,它会自动占用所有可用空间。但是,这种代码不起作用:

Arc(startAngle: .degrees(-90), endAngle: .degrees(90), clockwise: true)

.strokeBorder(Color.blue, lineWidth: 40)

如果您打开Xcode的错误消息,则会看到它显示“Value of type 'Arc' has no member 'strokeBorder'''——也就是说,arc中不存在strokeBorder()修饰符。

SwiftUI的Circle和我们的Arc之间有一个微小但重要的区别:两者均符合Shape协议,但Circle也符合名为InsettableShape的第二种协议。该形状可以嵌入(向内减小)一定距离以产生另一个形状。它产生的插图形状可以是任何其他类型的插图形状,但实际上,它应该是一个有相同形状的较小的矩形。

为了使Arc符合InsettableShape,我们需要为其添加一个额外的方法:inset(by :)。这将获得插入量(笔画的线宽的一半),并应返回一种新的可插入形状——在我们的实例中,这意味着我们应该创建一个插入弧型。问题是我们不知道圆弧的实际大小,因为尚未调用path(in :)。

事实证明,解决方案非常简单:如果我们为Arc形状提供一个默认为0的新insetAmount属性,则只要调用inset(by :)就可以添加该属性。添加到inset允许我们在需要时多次调用inset(by :),例如,如果我们想手动调用一次,则使用strokeBorder()。

首先,将此新属性添加到Arc:

var insetAmount: CGFloat = 0

现在给它这个inset(by :)方法:

func inset(by amount: CGFloat) -> some InsettableShape {

var arc = self

arc.insetAmount += amount

return arc

}

传入的数量参数应应用于所有边缘,这在圆弧的情况下意味着我们应使用它减小绘制半径。因此,将path(in :)内部的addArc()调用更改为:

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

通过该更改,我们现在可以使Arc符合InsettableShape,如下所示:

struct Arc: InsettableShape {

自定义 Arc 使用 strokeBorder() 绘制

注意:InsettableShape实际上是基于Shape构建的,因此无需在其中添加两者。

赏我一个赞吧~~~

android 带边框的arc,SwiftUI:自定义 Shape 使用 InsettableShape 协议实现向内绘制边框...相关推荐

  1. 18在protel DXP中PCB图中给电路板绘制边框、安装孔的方法介绍成都电路板设计

    SO单片机开发指南之18 万丈高楼平地起,辉煌只能靠自己, 能不辉煌不要紧,进步收获有就行. 边走边取,本文介绍在Protel DXP中PCB图纸中给电路板绘制边框.安装孔和标注的方法. 1.给电路板 ...

  2. Android自定义Shape

    1.圆角控件 首先,定义形状: drawable/roundctrl.xml <?xml version="1.0" encoding="UTF-8"?& ...

  3. 自定义Android带图片的按钮

    自定义Android带图片的按钮 前言 现在移动设备的按钮设计讲究大图标小文字,希望用户只要一看到图标便能知道这个按钮是干嘛的,但又要有必要的文字提示,最常见的就数搜索按钮了,上面一个大大的放大镜图标 ...

  4. android shape 自定义,Android自定义shape的使用

    MainActivity如下: package cn.testshape; import android.os.Bundle; import android.app.Activity; /** * D ...

  5. android带边框的RelativeLayout

    android带边框的RelativeLayout 概述 代码实现 概述 这个是小众需求,主要用于某些需要手动控制边框线是否显示的场景,例如底层通过数据参数的形式,配置边框显示的形式.多用于基于c语言 ...

  6. 自定义Android带图片和文字的ImageButton

    自定义Android带图片的按钮 前言 现在移动设备的按钮设计讲究大图标小文字,希望用户只要一看到图标便能知道这个按钮是干嘛的,但又要有必要的文字提示,最常见的就数搜索按钮了,上面一个大大的放大镜图标 ...

  7. Android进阶——AIDL详解之使用远程服务AIDL实现进程间带远程回调接口和自定义Bean的较复杂通信小结(二)

    文章大纲 引言 一.远程回调AIDL接口的应用 1.封装基本的父类和一些工具类 2. 创建服务端的AIDL 2.1.定义回调AIDL接口 2.2.定义业务AIDL接口 3.实现服务端对应AIDL的带有 ...

  8. Android带参数回传的自定义dialog

    Android带参数回传的自定义dialog 1.首先,建立一个属于dialog的style样式: <style name="MessageListDialog" paren ...

  9. android shape 绘制气泡图,气泡图-自定义 shape

    源码复制成功复制失败全屏 复制 运行 气泡图-自定义 shape // 自定义 shape, 支持图片形式的气泡 var Shape = G2.Shape; Shape.registerShape(' ...

最新文章

  1. API HTTP 请求调试:Postman
  2. Entity Framework 基础
  3. 访问vue实例中的数据
  4. 3-5 获取命令行参数
  5. mysql 非等值条件 索引_慢SQL简述与定位
  6. 初始化java工具失败,“初始化 Java 工具”期间发生了内部错误, java.lang.NullPointerException...
  7. Eclipse2020版本:pom.xml第一行报错:Could not initialize class org.apache.maven.plugin.war.
  8. 【script】python自定义时间格式的几种情况
  9. qt设置顶层窗口_Python快速入门系列:PyQt5 快速开发GUI-窗口类型以及主窗口创建...
  10. Python练习:站队顺序输出
  11. 毕设日志——TensorFlow安装的numpy覆盖?掉了pytorch的numpy
  12. LeetCode_Rotate List
  13. asp.net在动态网页中的使用技巧
  14. .net 委托 +lamda表达式
  15. 数学建模:传染病模型
  16. 苹果和亚马逊因疑似侵犯云端同步功能专利而被提起美国337调查
  17. HTML 图书销售排行榜
  18. 数藏2.0故事中,元境开启“元宇宙丝绸之路”
  19. 我对职业规划和未来发展的一些思考
  20. Markdown中图片左对齐

热门文章

  1. 计算平均值,保留小数点后一位
  2. 使用rpm安装telnet软件并实现远程登录
  3. 物联网小程序定制开发解决方案
  4. android投屏 电视软件,爱投屏电视端下载-爱投屏电视版v2.2.7 安卓版-速游网
  5. 面向服务方法与传统方法的区别
  6. 前端js获取图片大小 扩展名_JS获取文件大小方法小结
  7. 星河战神显示服务器异常,腾讯星河战神黑屏闪退怎么解决
  8. windows下启动mysql服务的命令行启动和手动启动方法
  9. 配置NVIDIA Jetson AGX Xavier
  10. canvas 的动画卡顿问题(运行一段时间卡顿)