I’m using a drawingView which is simply a VC’s view to draw a rectangle that rotates depending on a pan gesture. I apply 3 transforms on it. I translate the rectangle half it’s width left to put the top center of the rectangle at 0,0; rotate it some multiple of 45º and then translate it to the position of the gesture begin. This works perfectly.
When the pan gesture ends I want to drop an image view of the same size exactly where the rectangle is. The code for the drawing view are the save as the VC with the exception that in the drawing view the CGAffineTransform is applied to the path
func addImageView(_ x: CGFloat, _ y: CGFloat, _ direction: Direction) {
let myImageView = MyImageView(frame: CGRect(x: 0, y: 0, width: 116, height: 200))
myImageView = UIColor.systemBlue
var viewTransform = CGAffineTransform.identity
viewTransform = viewTransform.translatedBy(x: -58, y: 0)
var angle: CGFloat?
let pi = CGFloat.pi
switch direction {
case .up:
angle = 0
case .upRight:
angle = pi / 4.0
case .right:
angle = pi / 2.0
case .downRight:
angle = 3 * pi / 4.0
case .down:
angle = pi
case .downLeft:
angle = 5 * pi / 4.0
case .left:
angle = 3 * pi / 2.0
case .upLeft:
angle = 7 * pi / 4.0
default:
angle = nil
}
if angle != nil {
viewTransform = viewTransform.rotated(by: angle!)
}
viewTransform = viewTransform.translatedBy(x: x, y: y)
myImageView = viewTransform
view.addSubview(myImageView)
print("myImageView: \(myImageView)")
}
If there is no rotation the imageView drops perfectly. If there is rotation it (in all but one case) vanishes off the screen. In one case it basically draws (at the correct angle) but in a very wrong position.
I’m not sure what the image view is rotating “About” and have had no luck tracking down the correct mathematical changes.
Edit: When doing just the initial translate and the rotation; everything is fine and the UIImage rotates around the center of the frame. When I then add a translate after the rotation; it changes the point around which the view rotates making a bigger circle.
So the problem is moving the rotated view into place after the rotation is done.
Drawing code for drawing view
class DraggingView: UIView {
var currVector:(origin: CGPoint, direction: Direction)?
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
guard currVector != nil else {
return
}
let drawRect: CGRect = CGRect(x: 0, y: 0,
width: 116, height: 200)
let drawPath = UIBezierPath(roundedRect: drawRect, cornerRadius: 10.0)
drawPath.apply(CGAffineTransform(translationX: -58, y: 0))
var transform: CGAffineTransform?
let pi = 3.1415927
switch currVector!.direction {
case .downLeft:
transform = CGAffineTransform(rotationAngle: pi / 4.0)
case .downRight:
transform = CGAffineTransform(rotationAngle: -pi / 4.0)
case .left:
transform = CGAffineTransform(rotationAngle: pi / 2.0)
case .right:
transform = CGAffineTransform(rotationAngle: -pi / 2.0)
case .up:
transform = CGAffineTransform(rotationAngle: pi)
case .upLeft:
transform = CGAffineTransform(rotationAngle: 3 * pi / 4.0)
case .upRight:
transform = CGAffineTransform(rotationAngle: -3 * pi / 4.0)
default:
transform = nil
}
if transform != nil {
drawPath.apply(transform!)
}
drawPath.apply(CGAffineTransform(translationX: currVector!.origin.x, y: currVector!.origin.y))
UIColor.label.setStroke()
drawPath.stroke()
}
public func setVector(origin: CGPoint, direction: Direction) {
currVector = (origin, direction)
self.setNeedsDisplay()
}
public func clearVector() {
currVector = nil
}
}

