如何重新绘制可移动的两个 UIView 之间连接的线

Posted

技术标签:

【中文标题】如何重新绘制可移动的两个 UIView 之间连接的线【英文标题】:How to re-draw line connected between moveable two UIView 【发布时间】:2019-03-18 11:42:36 【问题描述】:

我想根据 UIView 的位置重新绘制两个可移动 UIView 之间的线。

所以我找到了this。但是,此方法使用“平移手势”重新绘制线条,具体取决于手势的位置。

也找到了setNeedsDisplay(),不过这​​是请求重绘,不是实时事件函数。

我想找到的方法不是用手势重画线,而是实时重画线。

更详细一点,我将“UIColisionBehavior”应用于我创建的所有 UIV 视图。应用的 UIView 会在敲击时改变位置,并根据改变的位置重新绘制线条。

好像 UIView 是这样移动的,连线根据移动的位置重新绘制:

下面是我在 Playground 中试验的代码。执行代码可以看到,第一条连接的紫色线与下降的UIView相连,并没有脱落:

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MoveAbleView : UIView 
    var outGoingLine : CAShapeLayer?
    var inComingLine : CAShapeLayer?

    override init(frame: CGRect) 
        super.init(frame: frame)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

    func lineTo(connectedView: MoveAbleView) -> CAShapeLayer 
        let path = UIBezierPath()
        path.move(to: self.center)
        path.addLine(to: connectedView.center)

        let line = CAShapeLayer()
        line.path = path.cgPath
        line.lineWidth = 5
        line.strokeColor = UIColor.purple.cgColor
        connectedView.inComingLine = line
        outGoingLine = line
        return line
    


class MyViewController : UIViewController 
    var dynamicAnimator = UIDynamicAnimator()
    var collisionBehavior = UICollisionBehavior()
    var gravityBehavior = UIGravityBehavior()

    override func loadView() 
        let view = UIView()
        view.backgroundColor = .white
        self.view = view

        let viw = MoveAbleView(frame: CGRect(x: 100, y: 200, width: 50, height: 50))
        viw.backgroundColor = UIColor.red
        self.view.addSubview(viw)

        let viw2 = MoveAbleView(frame: CGRect(x: 300, y: 100, width: 50, height: 50))
        viw2.backgroundColor = UIColor.orange
        self.view.addSubview(viw2)

        let gravityViw = MoveAbleView(frame: CGRect(x: 100, y: 0, width: 50, height: 50))
        gravityViw.backgroundColor = UIColor.green
        self.view.addSubview(gravityViw)

        let gravityViw2 = MoveAbleView(frame: CGRect(x: 300, y: -200, width: 50, height: 50))
        gravityViw2.backgroundColor = UIColor.blue
        self.view.addSubview(gravityViw2)

        collisionBehavior.addItem(viw)
        collisionBehavior.addItem(viw2)
        collisionBehavior.addItem(gravityViw)
        collisionBehavior.addItem(gravityViw2)

        gravityBehavior.addItem(gravityViw)
        gravityBehavior.addItem(gravityViw2)

        dynamicAnimator.addBehavior(collisionBehavior)
        dynamicAnimator.addBehavior(gravityBehavior)
    self.view.layer.addSublayer(viw.lineTo(connectedView: viw2))
    

// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

当UIView敲击移动时,如何实时重绘连线?

【问题讨论】:

@Allen R 我需要你的帮助。 【参考方案1】:

实际上,您所需要的只是另一个 UIView 来表示线条并使用附件行为。例如,两个附加对象之间有一条线。

类 MyViewController : UIViewController

override func loadView() 

    let view = UIView()


    view.backgroundColor = .white
    self.view = view
    dynamicAnimator = UIDynamicAnimator(referenceView: view)

    let viw = MoveAbleView(frame: CGRect(x: 100, y: 200, width: 50, height: 50))
    viw.backgroundColor = UIColor.red
    self.view.addSubview(viw)

    let viw2 = MoveAbleView(frame: CGRect(x: 300, y: 200, width: 50, height: 50))
    viw2.backgroundColor = UIColor.orange
    self.view.addSubview(viw2)

    let gravityViw = MoveAbleView(frame: CGRect(x: 100, y: 0, width: 50, height: 50))
    gravityViw.backgroundColor = UIColor.green
    self.view.addSubview(gravityViw)



    let line1 = MoveAbleView(frame: CGRect(x: 125, y: 225, width: 200, height: 10))
    line1.backgroundColor = UIColor.purple
    self.view.addSubview(line1)


    let l1 =    UIAttachmentBehavior.init(item: viw, offsetFromCenter: UIOffset.zero, attachedTo: line1, offsetFromCenter: UIOffset.init(horizontal: -100, vertical: 0))
    let l2 =    UIAttachmentBehavior.init(item: viw2, offsetFromCenter: UIOffset.zero, attachedTo: line1, offsetFromCenter: UIOffset.init(horizontal: 100, vertical: 0))

    collisionBehavior.addItem(viw)
    collisionBehavior.addItem(viw2)
    collisionBehavior.addItem(gravityViw)


    gravityBehavior.addItem(gravityViw)

     dynamicAnimator.addBehavior(l1)
     dynamicAnimator.addBehavior(l2)

    dynamicAnimator.addBehavior(collisionBehavior)
    dynamicAnimator.addBehavior(gravityBehavior)

   


  

【讨论】:

谢谢。这是我一直在寻找的真正答案。

以上是关于如何重新绘制可移动的两个 UIView 之间连接的线的主要内容,如果未能解决你的问题,请参考以下文章

Qt,C++ 在 2 个对象之间绘制连接线

在两个可移动的 uiviews 之间画线

如何在 UIView 上绘制点?

在 UIView 中绘制以及 addSubview

在两个 UIView 之间应用混合模式的最简单/最快的方法

iOS:在两个动画视图之间画线