gpt4 book ai didi

iOS 使用 CAShapeLayer 绘制自定义形状

转载 作者:行者123 更新时间:2023-11-28 14:41:45 27 4
gpt4 key购买 nike

我想绘制一个类似于下图的自定义形状。

Aim


  1. 一 strip 倒圆角的线
  2. 空心圆
  3. 后面的另一行

I achieved this in Android in the following way.

float radiusClear = halfWidth - strokeSize / 2f; // 1
canvas.drawRect(0, 0, width, radiusClear, rootPaint); // 2
canvas.drawCircle(0, radiusClear, radiusClear, clearPaint); // 3
canvas.drawCircle(width, radiusClear, radiusClear, clearPaint); // 4
canvas.drawLine(halfWidth, 0, halfWidth, halfHeight, rootPaint); // 5
canvas.drawLine(halfWidth, halfHeight, halfWidth, height, iconPaint); // 6
canvas.drawCircle(halfWidth, halfHeight, halfWidth, iconPaint); // 7
canvas.drawCircle(halfWidth, halfHeight, thirdWidth, clearPaint); // 8
  • 其中 (1) 计算距离。
  • (2) 在顶部画一个矩形

Top Rect

  • (3) (4) 绘制两个清除矩形的圆圈,使其看起来像两条弧线

Arc1 Arc2

  • 然后其余的调用以类似的方式绘制剩余的 View 。

在 swift 上有什么等效或更好的方法?

最佳答案

//
// ConnectorView.swift
//
// Created by harsh vishwakrama on 5/24/18.
//

import UIKit

private let grayColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
private let purpleColor = UIColor(red: 0.387, green: 0.416, blue: 0.718, alpha: 1.000)


@IBDesignable
class ConnectorView: UIView {

var mode: Mode = .end{
didSet{
let width = bounds.width
let height = bounds.height
let halfWidth = bounds.width / 2
let halfHeight = bounds.height / 2
let thirdWidth = bounds.width / 3
let strokeWidth = width / 5
let midPoint = CGPoint(x: bounds.midX, y: bounds.midY)

switch mode {
case .start:
drawStart(width, thirdWidth, halfWidth, halfHeight, midPoint,strokeWidth)
case .node:
drawNode(halfWidth, thirdWidth, halfHeight, midPoint,strokeWidth)
case .end:
drawEnd(halfWidth, thirdWidth, halfHeight, midPoint,strokeWidth)
case .only:
drawOnly(width, thirdWidth, halfWidth, halfHeight, strokeWidth, midPoint)
}
layoutSubviews()
}
}



required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
clipsToBounds = true
}

enum Mode {
case start, node, end, only
}
}
extension ConnectorView{
fileprivate func drawStart(_ width: CGFloat, _ thirdWidth: CGFloat, _ halfWidth: CGFloat, _ halfHeight: CGFloat, _ midPoint: CGPoint, _ strokeWidth: CGFloat) {
layer.sublayers?.forEach{ layer in
layer.removeFromSuperlayer()
}
let linePathTop = UIBezierPath()
linePathTop.move(to: CGPoint(x: -width, y: -thirdWidth))
linePathTop.addCurve(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth), controlPoint1: CGPoint(x: halfWidth, y: -thirdWidth ), controlPoint2: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: 2 * width, y: -thirdWidth))
linePathTop.addCurve(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth), controlPoint1: CGPoint(x: halfWidth, y: -thirdWidth ), controlPoint2: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: 0, y: -thirdWidth))
linePathTop.addLine(to: CGPoint(x: width, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.addLine(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth))
linePathTop.close()

let shapeLayerTop = CAShapeLayer()
shapeLayerTop.path = linePathTop.cgPath
shapeLayerTop.fillColor = UIColor.clear.cgColor
shapeLayerTop.strokeColor = purpleColor.cgColor
shapeLayerTop.lineWidth = strokeWidth
layer.addSublayer(shapeLayerTop)

let shapeLayerBottom = CAShapeLayer()
let linePathBottom = UIBezierPath()
linePathBottom.move(to: CGPoint(x: halfWidth, y: halfHeight + thirdWidth))
linePathBottom.addLine(to: CGPoint(x: halfWidth, y: bounds.height))
linePathBottom.close()

shapeLayerBottom.path = linePathBottom.cgPath
shapeLayerBottom.strokeColor = grayColor.cgColor
shapeLayerBottom.fillColor = UIColor.clear.cgColor
shapeLayerBottom.lineWidth = strokeWidth
layer.addSublayer(shapeLayerBottom)

let shapeLayerMid = CAShapeLayer()
let circlePath = UIBezierPath(arcCenter: midPoint , radius: thirdWidth, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
shapeLayerMid.path = circlePath.cgPath
shapeLayerMid.strokeColor = grayColor.cgColor
shapeLayerMid.fillColor = UIColor.clear.cgColor
shapeLayerMid.lineWidth = strokeWidth
layer.addSublayer(shapeLayerMid)
}

fileprivate func drawEnd(_ halfWidth: CGFloat, _ thirdWidth: CGFloat, _ halfHeight: CGFloat, _ midPoint: CGPoint,_ strokeWidth: CGFloat) {
layer.sublayers?.forEach{ layer in
layer.removeFromSuperlayer()
}
let linePath = UIBezierPath()
linePath.move(to: CGPoint(x: halfWidth, y: -thirdWidth))
linePath.addLine(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth))
linePath.close()

let shapeLayerLine = CAShapeLayer()
shapeLayerLine.fillColor = UIColor.clear.cgColor
shapeLayerLine.strokeColor = grayColor.cgColor
shapeLayerLine.lineWidth = strokeWidth
shapeLayerLine.path = linePath.cgPath
layer.addSublayer(shapeLayerLine)

let shapeLayerMid = CAShapeLayer()
let circlePath = UIBezierPath(arcCenter: midPoint , radius: thirdWidth, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
shapeLayerMid.path = circlePath.cgPath
shapeLayerMid.strokeColor = grayColor.cgColor
shapeLayerMid.fillColor = UIColor.clear.cgColor
shapeLayerMid.lineWidth = strokeWidth
layer.addSublayer(shapeLayerMid)
}

fileprivate func drawNode(_ halfWidth: CGFloat, _ thirdWidth: CGFloat, _ halfHeight: CGFloat, _ midPoint: CGPoint,_ strokeWidth: CGFloat) {
layer.sublayers?.forEach{ layer in
layer.removeFromSuperlayer()
}
let linePath = UIBezierPath()
linePath.move(to: CGPoint(x: halfWidth, y: -thirdWidth))
linePath.addLine(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth))

linePath.move(to: CGPoint(x: halfWidth, y: halfHeight + thirdWidth))
linePath.addLine(to: CGPoint(x: halfWidth, y: bounds.height))
linePath.close()

let shapeLayerLine = CAShapeLayer()
shapeLayerLine.fillColor = UIColor.clear.cgColor
shapeLayerLine.strokeColor = grayColor.cgColor
shapeLayerLine.lineWidth = strokeWidth
shapeLayerLine.path = linePath.cgPath
layer.addSublayer(shapeLayerLine)

let shapeLayerMid = CAShapeLayer()
let circlePath = UIBezierPath(arcCenter: midPoint , radius: thirdWidth, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
shapeLayerMid.path = circlePath.cgPath
shapeLayerMid.strokeColor = grayColor.cgColor
shapeLayerMid.fillColor = UIColor.clear.cgColor
shapeLayerMid.lineWidth = strokeWidth
layer.addSublayer(shapeLayerMid)
}

fileprivate func drawOnly(_ width: CGFloat, _ thirdWidth: CGFloat, _ halfWidth: CGFloat, _ halfHeight: CGFloat, _ strokeWidth: CGFloat, _ midPoint: CGPoint) {
layer.sublayers?.forEach{ layer in
layer.removeFromSuperlayer()
}
let linePathTop = UIBezierPath()
linePathTop.move(to: CGPoint(x: -width, y: -thirdWidth))
linePathTop.addCurve(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth), controlPoint1: CGPoint(x: halfWidth, y: -thirdWidth ), controlPoint2: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: 2 * width, y: -thirdWidth))
linePathTop.addCurve(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth), controlPoint1: CGPoint(x: halfWidth, y: -thirdWidth ), controlPoint2: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: 0, y: -thirdWidth))
linePathTop.addLine(to: CGPoint(x: width, y: -thirdWidth))
linePathTop.move(to: CGPoint(x: halfWidth, y: -thirdWidth))
linePathTop.addLine(to: CGPoint(x: halfWidth, y: halfHeight - thirdWidth))
linePathTop.close()

let shapeLayerTop = CAShapeLayer()
shapeLayerTop.path = linePathTop.cgPath
shapeLayerTop.fillColor = UIColor.clear.cgColor
shapeLayerTop.strokeColor = purpleColor.cgColor
shapeLayerTop.lineWidth = strokeWidth
layer.addSublayer(shapeLayerTop)

let shapeLayerMid = CAShapeLayer()
let circlePath = UIBezierPath(arcCenter: midPoint , radius: thirdWidth, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
shapeLayerMid.path = circlePath.cgPath
shapeLayerMid.strokeColor = grayColor.cgColor
shapeLayerMid.fillColor = UIColor.clear.cgColor
shapeLayerMid.lineWidth = strokeWidth
layer.addSublayer(shapeLayerMid)
}
}

这是我能够想出的第一个解决方案。可能需要一些调整,但这对我有用。我需要将 UI 的 3 个阶段放置在 UITableViewCell 中。一个用于第一个单元格,一个用于最后一个单元格,另一个用于其余单元格。

结果是这样的

enter image description here

关于iOS 使用 CAShapeLayer 绘制自定义形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50501197/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com