You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中如何在两个UIView中心点之间添加连线?

在两个UIView中心点之间添加连线的实现方法

下面是两种实用的iOS实现方案,适配布局变化场景:

方案一:用CAShapeLayer实现(推荐,性能更优)

通过形状图层绘制连线,适合需要频繁更新的场景:

// 假设redView、greenView是已存在的目标视图,parentView是它们的共同父视图
func addConnectingLine() {
    let lineLayer = CAShapeLayer()
    lineLayer.strokeColor = UIColor.blue.cgColor
    lineLayer.lineWidth = 2.0
    
    // 转换两个视图的中心点到父视图坐标系
    let redCenter = redView.convert(redView.center, to: parentView)
    let greenCenter = greenView.convert(greenView.center, to: parentView)
    
    // 创建两点连线路径
    let path = UIBezierPath()
    path.move(to: redCenter)
    path.addLine(to: greenCenter)
    lineLayer.path = path.cgPath
    
    parentView.layer.addSublayer(lineLayer)
}

// 处理布局变化(比如屏幕旋转、视图尺寸调整),在父视图的layoutSubviews中更新路径
override func layoutSubviews() {
    super.layoutSubviews()
    guard let lineLayer = self.layer.sublayers?.first(where: { $0 is CAShapeLayer }) as? CAShapeLayer else { return }
    
    let redCenter = redView.convert(redView.center, to: self)
    let greenCenter = greenView.convert(greenView.center, to: self)
    
    let updatedPath = UIBezierPath()
    updatedPath.move(to: redCenter)
    updatedPath.addLine(to: greenCenter)
    lineLayer.path = updatedPath.cgPath
}

方案二:自定义UIView重绘实现

通过重写draw(_:)方法绘制连线,适合简单静态场景:

class ConnectingLineView: UIView {
    var startPoint: CGPoint = .zero
    var endPoint: CGPoint = .zero
    var lineColor: UIColor = .blue
    var lineWidth: CGFloat = 2.0
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        context.setStrokeColor(lineColor.cgColor)
        context.setLineWidth(lineWidth)
        context.move(to: startPoint)
        context.addLine(to: endPoint)
        context.strokePath()
    }
}

// 使用方式
let lineView = ConnectingLineView(frame: parentView.bounds)
lineView.startPoint = redView.convert(redView.center, to: parentView)
lineView.endPoint = greenView.convert(greenView.center, to: parentView)
parentView.addSubview(lineView)

// 布局变化时更新
override func layoutSubviews() {
    super.layoutSubviews()
    lineView.startPoint = redView.convert(redView.center, to: self)
    lineView.endPoint = greenView.convert(greenView.center, to: self)
    lineView.setNeedsDisplay()
}

注意事项

  • 必须通过convert(_:to:)方法转换坐标系,避免因视图层级导致的坐标偏差
  • 如果视图有动态位置变化(比如动画移动),需要在变化完成后重新计算路径并更新

内容的提问来源于stack exchange,提问作者Akash Neeli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:15:38