Reputation: 157
Using Swift to draw lines, it keeps moving up the longer I continue to draw. Or maybe it's rotating back, like it's on a ball? The pictures show me starting out with a line, then as I draw, you can see that it reaches the top of the square. It's so weird! Why is that happening? How can I stop it? Code below.
var context: CGContext?
var adjustedImageViewRect: CGRect?
var adjustedImageView: UIImageView?
var lastPoint = CGPoint.zero
var firstPoint = CGPoint.zero
var brushWidth: CGFloat = 10.0
var opacity: CGFloat = 1.0
var swiped = false
var undermineArray: [CGPoint] = []
@IBOutlet weak var drawLineImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
drawLineImageView.image = UIImage(named: "layer")
}
override func viewDidAppear(_ animated: Bool) {
let rect = AVMakeRect(aspectRatio: drawLineImageView.image!.size, insideRect: drawLineImageView.bounds)
adjustedImageViewRect = rect
adjustedImageView = UIImageView(frame: rect)
self.view.addSubview(adjustedImageView!)
self.view.bringSubview(toFront: adjustedImageView!)
}
func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
if let adjImgView = adjustedImageView {
if let adjImgViewRect = adjustedImageViewRect {
UIGraphicsBeginImageContextWithOptions(adjImgViewRect.size, false, 0)
adjImgView.image?.draw(in: adjImgView.bounds)
context = UIGraphicsGetCurrentContext()
context?.move(to: fromPoint)
context?.addLine(to: toPoint)
context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(UIColor.red.cgColor)
context?.setBlendMode(CGBlendMode.normal)
context?.strokePath()
adjImgView.image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//clear out previous line
firstPoint = CGPoint.zero
lastPoint = CGPoint.zero
undermineArray.removeAll()
adjustedImageView?.image = UIImage()
swiped = false
if let touch = touches.first {
if let rect = adjustedImageViewRect {
if (touch.location(in: self.adjustedImageView).y < 0
|| touch.location(in: self.adjustedImageView).y > rect.height) {
adjustedImageView?.image = UIImage()
return
}
}
firstPoint = touch.location(in: self.adjustedImageView)
lastPoint = touch.location(in: self.adjustedImageView)
undermineArray.append(firstPoint)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
swiped = true
if let touch = touches.first {
var currentPoint = touch.location(in: adjustedImageView)
if let rect = adjustedImageViewRect {
if (touch.location(in: self.adjustedImageView).y < 0) {
currentPoint.y = 0
}
if (touch.location(in: self.adjustedImageView).y > rect.height) {
currentPoint.y = rect.height
}
}
undermineArray.append(currentPoint)
drawLine(from: lastPoint, to: currentPoint)
lastPoint = currentPoint
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let rect = adjustedImageViewRect {
if (firstPoint.y < 0 || firstPoint.y > rect.height) {
adjustedImageView?.image = UIImage()
return
}
}
if let touch = touches.first {
if let rect = adjustedImageViewRect {
if (touch.location(in: self.adjustedImageView).y < 0) {
lastPoint.y = 0
}
if (touch.location(in: self.adjustedImageView).y > rect.height) {
lastPoint.y = rect.height
}
}
}
if !swiped {
self.drawLine(from: lastPoint, to: lastPoint)
}
}
Upvotes: 1
Views: 388
Reputation: 157
AH I got it. It turns out that UIImage's draw() function draws the image, and unbeknownst to me until now, "scales it as needed to fit."
So, we'll use something else. We'll just use drawAsPattern().
Change
adjImgView.image?.draw(in: adjImgView.bounds)
to
adjImgView.image?.drawAsPattern(in: adjImgView.bounds)
and voilà, no crazy scaling/spinning/shrinking going on.
Upvotes: 3