gpt4 book ai didi

ios - Swift 中可拖动连接的 UIView

转载 作者:搜寻专家 更新时间:2023-10-31 22:01:20 24 4
gpt4 key购买 nike

我正在尝试创建一些由线连接的可拖动 UIView。见下图:

enter image description here

我可以通过创建一个 UIView 的子类并重写绘制函数来创建可拖动的圆圈

override func draw(_ rect: CGRect) {
let path = UIBezierPath(ovalIn: rect)
let circleColor:UIColor

switch group {
case .forehead:
circleColor = UIColor.red
case .crowsFeetRightEye:
circleColor = UIColor.green
case .crowsFeetLeftEye:
circleColor = UIColor.blue
}

circleColor.setFill()
path.fill()
}

然后为拖动添加一个平移手势识别器

func initGestureRecognizers() {
let panGR = UIPanGestureRecognizer(target: self, action: #selector(DragPoint.didPan(panGR:)))
addGestureRecognizer(panGR)
}

@objc func didPan(panGR: UIPanGestureRecognizer) {

if panGR.state == .changed {
self.superview!.bringSubview(toFront: self)
let translation = panGR.translation(in: self)

self.center.x += translation.x
self.center.y += translation.y

panGR.setTranslation(CGPoint.zero, in: self)

}

}

但是,我完全不知道如何处理连接线以及如何在拖动时将起点/终点指向相应的圆圈。有没有人可以帮助我或指出正确的方向?

最佳答案

您想使用 CAShapeLayersUIBezier 路径来绘制圆圈之间的线,然后在用户移动 View 时更改路径。

这是一个显示实现的 Playground 。您可以将其复制并粘贴到 playground 中以查看实际效果。

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class CircleView : UIView {

var outGoingLine : CAShapeLayer?
var inComingLine : CAShapeLayer?
var inComingCircle : CircleView?
var outGoingCircle : CircleView?

override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = self.frame.size.width / 2
}

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

func lineTo(circle: CircleView) -> CAShapeLayer {
let path = UIBezierPath()
path.move(to: self.center)
path.addLine(to: circle.center)

let line = CAShapeLayer()
line.path = path.cgPath
line.lineWidth = 5
line.strokeColor = UIColor.red.cgColor
circle.inComingLine = line
outGoingLine = line
outGoingCircle = circle
circle.inComingCircle = self
return line
}
}

class MyViewController : UIViewController {

let circle1 = CircleView(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
let circle2 = CircleView(frame: CGRect(x: 100, y: 200, width: 50, height: 50))
let circle3 = CircleView(frame: CGRect(x: 100, y: 300, width: 50, height: 50))
let circle4 = CircleView(frame: CGRect(x: 100, y: 400, width: 50, height: 50))

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

circle1.backgroundColor = .red
view.addSubview(circle1)

circle2.backgroundColor = .red
view.addSubview(circle2)

circle3.backgroundColor = .red
view.addSubview(circle3)

circle4.backgroundColor = .red
view.addSubview(circle4)

circle1.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:))))

circle2.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:))))

circle3.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:))))

circle4.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(didPan(gesture:))))

view.layer.addSublayer(circle1.lineTo(circle: circle2))
view.layer.addSublayer(circle2.lineTo(circle: circle3))
view.layer.addSublayer(circle3.lineTo(circle: circle4))
}

@objc func didPan(gesture: UIPanGestureRecognizer) {
guard let circle = gesture.view as? CircleView else {
return
}
if (gesture.state == .began) {
circle.center = gesture.location(in: self.view)
}
let newCenter: CGPoint = gesture.location(in: self.view)
let dX = newCenter.x - circle.center.x
let dY = newCenter.y - circle.center.y
circle.center = CGPoint(x: circle.center.x + dX, y: circle.center.y + dY)


if let outGoingCircle = circle.outGoingCircle, let line = circle.outGoingLine, let path = circle.outGoingLine?.path {

let newPath = UIBezierPath(cgPath: path)
newPath.removeAllPoints()
newPath.move(to: circle.center)
newPath.addLine(to: outGoingCircle.center)
line.path = newPath.cgPath
}

if let inComingCircle = circle.inComingCircle, let line = circle.inComingLine, let path = circle.inComingLine?.path {

let newPath = UIBezierPath(cgPath: path)
newPath.removeAllPoints()
newPath.move(to: inComingCircle.center)
newPath.addLine(to: circle.center)
line.path = newPath.cgPath
}
}
}

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

gif showing the code working

关于ios - Swift 中可拖动连接的 UIView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48915295/

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