如何让CGMutablePath的X、Y适配视图边界?动态视图虚线绘制需求
适配动态高度视图的垂直虚线绘制方案
我来帮你调整代码,让垂直虚线能完全适配视图的动态高度,而且位置精准贴合视图边界~
首先要解决两个核心问题:一是替换固定的40为视图的动态高度值,二是让虚线的起始/终点坐标和视图的bounds绑定。另外,因为你的视图是通过约束动态改变高度的,必须在视图布局更新时同步更新虚线路径,否则视图高度变化后虚线不会跟着调整。
修改后的完整UIView扩展代码
import UIKit private var shapeLayerAssociationKey = "shapeLayerAssociationKey" extension UIView { // 用关联属性存储CAShapeLayer,避免重复创建子图层 private var dashedLineLayer: CAShapeLayer? { get { objc_getAssociatedObject(self, &shapeLayerAssociationKey) as? CAShapeLayer } set { objc_setAssociatedObject(self, &shapeLayerAssociationKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } /// 添加垂直虚线,可自定义水平位置 /// - Parameter xPosition: 虚线的水平坐标(基于视图自身坐标系,默认左边缘) func addVerticalDashedLine(atXPosition xPosition: CGFloat = 0) { // 先移除已存在的虚线图层,避免重复添加 dashedLineLayer?.removeFromSuperlayer() let layer = CAShapeLayer() layer.strokeColor = UIColor.black.cgColor layer.lineWidth = 3 layer.lineDashPattern = [4, 3] self.dashedLineLayer = layer self.layer.addSublayer(layer) // 初始化虚线路径 updateVerticalDashedLinePath(atXPosition: xPosition) } /// 更新虚线路径,适配当前视图bounds private func updateVerticalDashedLinePath(atXPosition xPosition: CGFloat) { guard let layer = dashedLineLayer else { return } let path = CGMutablePath() // 起始点:指定水平位置,视图顶部边界 let startPoint = CGPoint(x: xPosition, y: bounds.minY) // 终点:指定水平位置,视图底部边界 let endPoint = CGPoint(x: xPosition, y: bounds.maxY) path.addLines(between: [startPoint, endPoint]) layer.path = path } // 重写布局方法,每次视图约束更新后同步更新虚线 override open func layoutSubviews() { super.layoutSubviews() // 保留原来的水平位置,更新垂直路径 let currentX = dashedLineLayer?.path?.boundingBox.minX ?? 0 updateVerticalDashedLinePath(atXPosition: currentX) } }
关键改动说明
- 关联属性存储图层:避免每次布局都创建新的
CAShapeLayer,减少性能消耗和图层冗余 - 绑定视图bounds:用
bounds.minY和bounds.maxY替代固定数值,让虚线从视图顶部延伸到底部,完全适配动态高度 - 布局时自动更新:重写
layoutSubviews方法,每次视图约束生效、高度变化时,自动重新计算虚线路径 - 可自定义水平位置:通过
atXPosition参数可以灵活设置虚线的水平位置,比如传bounds.midX就是居中垂直虚线,传bounds.maxX就是右边缘虚线
使用示例
假设你有一个通过顶部/底部约束动态调整高度的视图,直接调用方法即可:
let dynamicHeightView = UIView() dynamicHeightView.backgroundColor = .lightGray view.addSubview(dynamicHeightView) // 设置动态高度约束 dynamicHeightView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ dynamicHeightView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), dynamicHeightView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20), dynamicHeightView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), dynamicHeightView.widthAnchor.constraint(equalToConstant: 150) ]) // 添加左边缘的垂直虚线 dynamicHeightView.addVerticalDashedLine(atXPosition: 0)
这样不管视图高度怎么变化,垂直虚线都会自动适配,始终铺满整个视图的高度。
内容的提问来源于stack exchange,提问作者dypbrg
相关产品推荐
相关产品推荐

