修改endcap .round样式,显然是圆形的,与此处显示的示例图像不同

问题描述 投票:0回答:2

我刚刚了解到标准苹果.round端盖

let l = CAShapeLayer()
l.path = .. just a straight line, say 50 long
l.lineWidth = wahtever, say "20"
l.lineCap = .round

实际上不是圆形的。>。

仔细一看,就会看到。

更像是“屁股”。

因此,对于例如20的线宽,端盖的高度约为7或8

-对于“精确的半圆”,它不是10,正如您所期望的。 >上限。

如果我要“精确的半圆”端盖,该怎么办?

[我很欣赏我可以建立自己的“线”(即“外部”或线)并填充它,然后我可以完全按照自己的意愿设置端盖。

但是有某种方法可能以某种方式将“ endcap”子类化吗?!

如果可以将“线条/厚度”隐喻保留在形状图层中,而不是仔细绘制线条轮廓,则容易得多。

如果你说= .myHappyEndcapMode,那将是神奇的>

enter image description here

我们如何解决这种令人震惊的情况?

enter image description here

enter image description here

enter image description here

您可以看到这里有多远:

enter image description here

[我刚刚了解到,标准的Apple .round端帽让l = CAShapeLayer()l.path = ..只是一条直线,例如50长l.lineWidth = wahtever,说“ 20” l.lineCap = .round实际上不是圆的。...

无法对子帽形状进行“分类”。如果需要其他帽形,则必须手动构造形状的轮廓。

圆帽已经和CGPath(ellipseIn:)创建的圆完全一样。

这是在半径稍大的圆上绘制的圆形线,放大了8倍:

zoomed image

线帽的曲率恰好在圆的水平中心开始。

这里是代码:

import UIKit
import PlaygroundSupport

let lineWidth: CGFloat = 20
let circleRadius = lineWidth / 2 + 1

let lineLayer = CAShapeLayer()
lineLayer.position = .init(x: 30, y: 30)
let path = CGMutablePath()
path.move(to: .zero)
path.addLine(to: .init(x: 30, y: 0))
lineLayer.path = path
lineLayer.lineWidth = lineWidth
lineLayer.lineCap = .round
lineLayer.strokeColor = UIColor.gray.cgColor
lineLayer.fillColor = nil

let circleLayer = CAShapeLayer()
circleLayer.position = lineLayer.position
circleLayer.path = CGPath(ellipseIn: CGRect.zero.insetBy(dx: -circleRadius, dy: -circleRadius), transform: nil)
circleLayer.fillColor = UIColor.blue.cgColor

let view = UIView(frame: .init(x: 0, y: 0, width: 100, height: 80))
view.layer.backgroundColor = UIColor.white.cgColor
view.layer.addSublayer(circleLayer)
view.layer.addSublayer(lineLayer)
PlaygroundPage.current.liveView = view
 

我想知道您是否看到我们不是...

这里是行尾,宽度为8点(在iPhone 8上以16像素渲染),放大到3200%

enter image description here

如您所见,圆形的端盖的半径为精确

8个像素。

这是我用来获得上述放大图像的实际屏幕截图。线宽从1到10:

enter image description here


编辑

Hmmm ...好像是A)

它是光学的,您没有在放大的图像中算出所有抗锯齿像素(也就是说,当端盖is圆时,只是没有[[look向您舍去),或B)也许您正在缩放/拉伸图像/图层?[这里有几张示例图像-这次,我使用CAShapeLayer作为覆盖在CAGradientLayer上的UIImageView上的遮罩:

enter image description here

enter image description here

用于放大图像的屏幕盖:

enter image description here

和生成该视图的源,如果您想使用它:

class GradientView: UIView { override open class var layerClass: AnyClass { return CAGradientLayer.classForCoder() } lazy var gradientLayer: CAGradientLayer = { return self.layer as! CAGradientLayer }() override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() } func commonInit() -> Void { if let l = layer as? CAGradientLayer { let c1 = UIColor(rgb: 0x6119D2) let c2 = UIColor(rgb: 0x7E1CC6) l.colors = [c1.cgColor, c2.cgColor] l.startPoint = CGPoint(x: 0.0, y: 0.0) l.endPoint = CGPoint(x: 1.0, y: 0.0) } } override func layoutSubviews() { super.layoutSubviews() let l = CAShapeLayer() let bez = UIBezierPath() let xOffset = bounds.size.height * 0.5 + 4 bez.move(to: CGPoint(x: xOffset, y: bounds.size.height * 0.5)) bez.addLine(to: CGPoint(x: bounds.size.width - xOffset, y: bounds.size.height * 0.5)) l.lineCap = .round l.lineWidth = bounds.size.height l.strokeColor = UIColor.black.cgColor l.path = bez.cgPath self.layer.mask = l } } class EndCapViewController: UIViewController { let gView: GradientView = { let v = GradientView() v.translatesAutoresizingMaskIntoConstraints = false return v }() let imgView: UIImageView = { let v = UIImageView() v.translatesAutoresizingMaskIntoConstraints = false v.contentMode = .scaleAspectFit return v }() override func viewDidLoad() { super.viewDidLoad() if let img = UIImage(named: "clouds") { imgView.image = img } view.addSubview(imgView) view.addSubview(gView) let lineThickness: CGFloat = 8.0 NSLayoutConstraint.activate([ imgView.centerXAnchor.constraint(equalTo: view.centerXAnchor), imgView.centerYAnchor.constraint(equalTo: view.centerYAnchor), imgView.widthAnchor.constraint(equalToConstant: 128.0), imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: 1.0), gView.widthAnchor.constraint(equalTo: imgView.widthAnchor, multiplier: 1.0), gView.heightAnchor.constraint(equalToConstant: lineThickness), gView.centerXAnchor.constraint(equalTo: imgView.centerXAnchor), gView.centerYAnchor.constraint(equalTo: imgView.centerYAnchor), ]) } } extension UIColor { convenience init(red: Int, green: Int, blue: Int) { assert(red >= 0 && red <= 255, "Invalid red component") assert(green >= 0 && green <= 255, "Invalid green component") assert(blue >= 0 && blue <= 255, "Invalid blue component") self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) } convenience init(rgb: Int) { self.init( red: (rgb >> 16) & 0xFF, green: (rgb >> 8) & 0xFF, blue: rgb & 0xFF ) } }

ios uikit cashapelayer swift5
2个回答
1
投票

无法对子帽形状进行“分类”。如果需要其他帽形,则必须手动构造形状的轮廓。


1
投票

我想知道您是否看到我们不是...

这里是行尾,宽度为8点(在iPhone 8上以16像素渲染),放大到3200%

© www.soinside.com 2019 - 2024. All rights reserved.