gpt4 book ai didi

Swift:使 UIView 的轮廓看起来像草图

转载 作者:行者123 更新时间:2023-12-02 16:09:56 24 4
gpt4 key购买 nike

我想让 UIView 的轮廓看起来像有人画的那样“波浪状”。

我有这个来自 PowerPoint 的例子,它允许这样做(应该适用于任何尺寸和角半径):

enter image description here

目前这是我拥有的:

myView.layer.borderWidth = 10
myView.layer.borderColor = UIColor.blue.cgColor
myView.layer.cornerRadius = 5 // Optional

感谢

最佳答案

您可以使用 UIBezierPath 结合四边形曲线、直线、圆弧等来创建“波浪”线。

我们将从一条简单的线开始,占 View 宽度的四分之一:

enter image description here

我们的路径将包括:

  • 移动到0,0
  • 将行添加到 80,0

如果我们将其更改为四曲线:

enter image description here

现在我们在做:

  • 移动到0,0
  • 将四边形曲线添加到 80,0,控制点为 40,40

如果我们添加另一个方向相反的四边形曲线:

enter image description here

现在我们在做:

  • 移动到0,0
  • 将四边形曲线添加到 80,0,控制点为 40,40
  • 将四边形曲线添加到 160,0,控制点为 120,-40

我们可以扩展 View 的宽度:

enter image description here

当然,这看起来不像您的“草图”目标,所以让我们将控制点偏移量从 40 更改为 2:

enter image description here

现在它看起来更像是一条手绘“素描”线。

不过,它太统一了,而且它部分超出了 View 的边界,所以让我们将它插入 8 磅,而不是四个 25% 的段,我们将使用(例如)这些宽度的五个段:

0.15, 0.2, 0.2, 0.27, 0.18

enter image description here

如果我们采用相同的方法从右侧向下,返回底部,然后从左侧向上,我们可以得到:

enter image description here

下面是生成该 View 的一些示例代码:

class SketchBorderView: UIView {

let borderLayer: CAShapeLayer = CAShapeLayer()

override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = UIColor.blue.cgColor
layer.addSublayer(borderLayer)
backgroundColor = .yellow
}
override func layoutSubviews() {

let incrementVals: [CGFloat] = [
0.15, 0.2, 0.2, 0.27, 0.18,
]
let lineOffsets: [[CGFloat]] = [
[ 1.0, -2.0],
[-1.0, 2.0],
[-1.0, -2.0],
[ 1.0, 2.0],
[ 0.0, -2.0],
]

let pth: UIBezierPath = UIBezierPath()

// inset bounds by 8-pts so we can draw the "wavy border"
// inside our bounds
let r: CGRect = bounds.insetBy(dx: 8.0, dy: 8.0)

var ptDest: CGPoint = .zero
var ptControl: CGPoint = .zero

// start at top-left
ptDest = r.origin
pth.move(to: ptDest)

// we're at top-left
for i in 0..<incrementVals.count {

ptDest.x += r.width * incrementVals[i]
ptDest.y = r.minY + lineOffsets[i][0]

ptControl.x = pth.currentPoint.x + ((ptDest.x - pth.currentPoint.x) * 0.5)
ptControl.y = r.minY + lineOffsets[i][1]

pth.addQuadCurve(to: ptDest, controlPoint: ptControl)

}

// now we're at top-right
for i in 0..<incrementVals.count {

ptDest.y += r.height * incrementVals[i]
ptDest.x = r.maxX + lineOffsets[i][0]

ptControl.y = pth.currentPoint.y + ((ptDest.y - pth.currentPoint.y) * 0.5)
ptControl.x = r.maxX + lineOffsets[i][1]

pth.addQuadCurve(to: ptDest, controlPoint: ptControl)

}

// now we're at bottom-right
for i in 0..<incrementVals.count {

ptDest.x -= r.width * incrementVals[i]
ptDest.y = r.maxY + lineOffsets[i][0]

ptControl.x = pth.currentPoint.x - ((pth.currentPoint.x - ptDest.x) * 0.5)
ptControl.y = r.maxY + lineOffsets[i][1]

pth.addQuadCurve(to: ptDest, controlPoint: ptControl)

}

// now we're at bottom-left
for i in 0..<incrementVals.count {

ptDest.y -= r.height * incrementVals[i]
ptDest.x = r.minX + lineOffsets[i][0]

ptControl.y = pth.currentPoint.y - ((pth.currentPoint.y - ptDest.y) * 0.5)
ptControl.x = r.minX + lineOffsets[i][1]

pth.addQuadCurve(to: ptDest, controlPoint: ptControl)

}

borderLayer.path = pth.cgPath
}

}

和一个示例 Controller :

class SketchTestVC: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let v = SketchBorderView()
v.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(v)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
v.centerXAnchor.constraint(equalTo: g.centerXAnchor),
v.centerYAnchor.constraint(equalTo: g.centerYAnchor),
v.widthAnchor.constraint(equalToConstant: 320.0),
v.heightAnchor.constraint(equalTo: v.widthAnchor),
])
}

}

但是,使用该代码,我们仍然有太多的统一性,因此在实际使用中,我们希望随机化段的数量、段的宽度和控制点偏移。

当然,要获得“圆角矩形”,您需要在角处添加圆弧。

不过,我希望这能让您顺利上路。

关于Swift:使 UIView 的轮廓看起来像草图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68302030/

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