我有一个简单的应用程序,其中包含一个非常小的视图层次结构:
ViewController
(DrawingView
的子类)和三个UIView
(每个都是ImageViews
的子类)。在 DrawingView
内部,我重写了
DrawingView
以生成依赖于每个 draw(_:)
中心的图形(具体来说,是一个顶点为图像中心的多边形)。同时,ImageView
位置由用户通过拖动手势控制。手势处理动作是ImageView
的方法。我希望 ViewController
随着
DrawingView
位置的变化而实时更新。为了实现这一点,我在手势处理程序中调用了 ImageView
。然而,这种方法仅离散地更新 DrawingView.setNeedsDisplay()
,并且似乎直到下一个手势开始才更新(无论调用出现在 DrawingView
语句中的位置)。我的问题:我应该在哪里/如何调用switch gesture.state
才能顺利(实时)更新到
setNeedsDisplay
?或者有更好的方法吗?这是我的类定义:
DrawingView
class ViewController: UIViewController {
@IBOutlet var drawingView: DrawingView!
@IBOutlet var majorVertex1: UIImageView!
@IBOutlet var majorVertex2: UIImageView!
@IBOutlet var majorVertex3: UIImageView!
var majorVertices: [UIImageView]!
@IBOutlet var majorVertex1XConstraint: NSLayoutConstraint!
@IBOutlet var majorVertex1YConstraint: NSLayoutConstraint!
@IBOutlet var majorVertex2XConstraint: NSLayoutConstraint!
@IBOutlet var majorVertex2YConstraint: NSLayoutConstraint!
@IBOutlet var majorVertex3XConstraint: NSLayoutConstraint!
@IBOutlet var majorVertex3YConstraint: NSLayoutConstraint!
var majorVertexXConstraints: [NSLayoutConstraint]!
var majorVertexYConstraints: [NSLayoutConstraint]!
static var majorVertexXOffsets: [Double]?
static var majorVertexYOffsets: [Double]?
override func viewDidLoad() {
super.viewDidLoad()
majorVertices = [majorVertex1, majorVertex2, majorVertex3]
majorVertexXConstraints = [majorVertex1XConstraint, majorVertex2XConstraint, majorVertex3XConstraint]
majorVertexYConstraints = [majorVertex1YConstraint, majorVertex2YConstraint, majorVertex3YConstraint]
ViewController.majorVertexXOffsets = majorVertexXConstraints.map {(constraint) -> Double in return constraint.constant}
ViewController.majorVertexYOffsets = majorVertexYConstraints.map {(constraint) -> Double in return constraint.constant}
}
@IBAction func handlePan(_ gesture: UIPanGestureRecognizer) {
guard let majorVertices = majorVertices,
let gestureView = gesture.view
else {return}
guard let parentView = gestureView.superview,
let gestureViewIndex = majorVertices.firstIndex(of: gestureView as! UIImageView)
else {return}
let translation = gesture.translation(in: parentView)
switch gesture.state {
case .began:
ViewController.majorVertexXOffsets = majorVertexXConstraints.map {(constraint) -> Double in return constraint.constant}
ViewController.majorVertexYOffsets = majorVertexYConstraints.map {(constraint) -> Double in return constraint.constant}
break
case .changed:
majorVertexXConstraints[gestureViewIndex].constant = ViewController.majorVertexXOffsets![gestureViewIndex] + translation.x
majorVertexYConstraints[gestureViewIndex].constant = ViewController.majorVertexYOffsets![gestureViewIndex] + translation.y
drawingView.setNeedsDisplay()
break
case .ended, .cancelled:
majorVertexXConstraints[gestureViewIndex].constant = gestureView.center.x - parentView.frame.size.width / 2.0
majorVertexYConstraints[gestureViewIndex].constant = gestureView.center.y - parentView.frame.size.height / 2.0
break
default:
break
}
}
}
class DrawingView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
func setupView() {
backgroundColor = .clear
}
override func draw(_ rect: CGRect) {
super.draw(rect)
drawTriangle(rect)
}
internal func drawTriangle(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext(),
let majorVertexXOffsets = ViewController.majorVertexXOffsets,
let majorVertexYOffsets = ViewController.majorVertexYOffsets
else {return}
let majorVertexXCenters = majorVertexXOffsets.map {(x) -> Double in return x + rect.width / 2.0}
let majorVertexYCenters = majorVertexYOffsets.map {(y) -> Double in return y + rect.height / 2.0}
context.setStrokeColor(UIColor.lightGray.cgColor)
context.setLineWidth(3)
context.move(to: CGPoint(x: majorVertexXCenters[0], y: majorVertexYCenters[0]))
context.addLine(to: CGPoint(x: majorVertexXCenters[1], y: majorVertexYCenters[1]))
context.addLine(to: CGPoint(x: majorVertexXCenters[2], y: majorVertexYCenters[2]))
context.addLine(to: CGPoint(x: majorVertexXCenters[0], y: majorVertexYCenters[0]))
context.strokePath()
}
}
变量做一些相当时髦的事情,这需要直接引用特定的类...并且,尚不完全清楚您如何设置相对于视图的约束,但是...
您没有看到“实时”绘制更新的原因是因为您更改了约束常量而没有更新 X 和 Y 偏移量数组。
static