I’ve a easy app with a single ViewController
containing a really minimal view hierarchy: DrawingView
(a subclass of UIView
), and three ImageViews
(that are every youngsters of DrawingView
).
Inside DrawingView
, I’ve overridden draw(_:)
to provide graphics which rely on the middle of every ImageView
(particularly, a polygon whose vertices are the picture facilities). In the meantime, the ImageView
positions are managed by the person by way of drag gestures. The gesture dealing with motion is a technique of ViewController
.
I might like for DrawingView
to replace in real-time because the ImageView
positions change. To perform this, I’ve referred to as DrawingView.setNeedsDisplay()
contained in the gesture handler. Nonetheless, this method solely updates DrawingView
discretely, and seemingly not till the following gesture begins (no matter the place the decision seems within the change gesture.state
assertion).
My query: the place/how ought to I name setNeedsDisplay
to be able to obtain a clean (and real-time) replace to DrawingView
? Or is there a greater method?
Listed below are my class definitions:
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() {
tremendous.viewDidLoad()
majorVertices = [majorVertex1, majorVertex2, majorVertex3]
majorVertexXConstraints = [majorVertex1XConstraint, majorVertex2XConstraint, majorVertex3XConstraint]
majorVertexYConstraints = [majorVertex1YConstraint, majorVertex2YConstraint, majorVertex3YConstraint]
ViewController.majorVertexXOffsets = majorVertexXConstraints.map {(constraint) -> Double in return constraint.fixed}
ViewController.majorVertexYOffsets = majorVertexYConstraints.map {(constraint) -> Double in return constraint.fixed}
}
@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)
change gesture.state {
case .started:
ViewController.majorVertexXOffsets = majorVertexXConstraints.map {(constraint) -> Double in return constraint.fixed}
ViewController.majorVertexYOffsets = majorVertexYConstraints.map {(constraint) -> Double in return constraint.fixed}
break
case .modified:
majorVertexXConstraints[gestureViewIndex].fixed = ViewController.majorVertexXOffsets![gestureViewIndex] + translation.x
majorVertexYConstraints[gestureViewIndex].fixed = ViewController.majorVertexYOffsets![gestureViewIndex] + translation.y
drawingView.setNeedsDisplay()
break
case .ended, .cancelled:
majorVertexXConstraints[gestureViewIndex].fixed = gestureView.middle.x - parentView.body.measurement.width / 2.0
majorVertexYConstraints[gestureViewIndex].fixed = gestureView.middle.y - parentView.body.measurement.top / 2.0
break
default:
break
}
}
}
class DrawingView: UIView {
override init(body: CGRect) {
tremendous.init(body: body)
setupView()
}
required init?(coder aDecoder: NSCoder) {
tremendous.init(coder: aDecoder)
setupView()
}
func setupView() {
backgroundColor = .clear
}
override func draw(_ rect: CGRect) {
tremendous.draw(rect)
drawTriangle(rect)
}
inside 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.top / 2.0}
context.setStrokeColor(UIColor.lightGray.cgColor)
context.setLineWidth(3)
context.transfer(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()
}
}