2015-06-01 3 views
1

Приведенный ниже код рисует прямые линии между точками на UIImageView. Рисунки визуализируются быстро и хорошо выглядят, но могут быть намного лучше, поэтому я хочу изменить код для создания плавных кривых линий. Я исследовал ряд примеров в Swift за последние шесть недель с нулевым успехом.Как нарисовать гладкие линии внутри UIImageView с Swift?

Какие разделы нижеследующего кода я должен изменить (и как) для достижения этого, пожалуйста? Мне сказали, что при вызове нижеприведенного фрагмента вместо CGContextAddLineToPoint() (в // 2 ниже) должен сделать трюк, но я не понимаю, как его вызвать и как он относится к текущему коду целиком.

SNIPPET:

func drawQuadLineWithPoints(firstPoint: CGPoint, secondPoint: CGPoint, thirdPoint: CGPoint, inContext: CGContext) { 
    CGContextMoveToPoint(context, 0.5 * (firstPoint.x + secondPoint.x), 0.5 * (firstPoint.y + secondPoint.y)); 
    CGContextAddQuadCurveToPoint(context, secondPoint.x, secondPoint.y, 0.5 * (secondPoint.x + thirdPoint.x), 0.5 * (secondPoint.y + thirdPoint.y)); 
} 

КОД:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
    swiped = false 
    if let touch = touches.anyObject() as? UITouch { 
     lastPoint = touch.locationInView(self.view) 
    } 
    } 

    func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) { 

    // 1 
    UIGraphicsBeginImageContext(view.frame.size) 
    let context = UIGraphicsGetCurrentContext() 
    tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) 

    // 2 
    CGContextMoveToPoint(context, fromPoint.x, fromPoint.y) 
    CGContextAddLineToPoint(context, toPoint.x, toPoint.y) 

    // 3 
    CGContextSetLineCap(context, kCGLineCapRound) 
    CGContextSetLineWidth(context, brushWidth) 
    CGContextSetRGBStrokeColor(context, red, green, blue, 1.0) 
    CGContextSetBlendMode(context, kCGBlendModeNormal) 

    // 4 
    CGContextStrokePath(context) 

    // 5 
    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() 
    tempImageView.alpha = opacity 
    UIGraphicsEndImageContext() 

    } 

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) { 
    // 6 
    swiped = true 
    if let touch = touches.anyObject() as? UITouch { 
     let currentPoint = touch.locationInView(view) 
     drawLineFrom(lastPoint, toPoint: currentPoint) 

     // 7 
     lastPoint = currentPoint 
    } 
    } 

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) { 

    if !swiped { 
     // draw a single point 
     drawLineFrom(lastPoint, toPoint: lastPoint) 
    } 

    // Merge tempImageView into mainImageView 
    UIGraphicsBeginImageContext(mainImageView.frame.size) 
    mainImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0) 
    tempImageView.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: opacity) 
    mainImageView.image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    tempImageView.image = nil 
    } 

ответ

4

Посмотрите ответ на THIS

Это грубый перевод Свифта я использовал:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 


    if let touch = touches.first as? UITouch{ 

     prevPoint1 = touch.previousLocationInView(self.view) 

     prevPoint2 = touch.previousLocationInView(self.view) 

     lastPoint = touch.locationInView(self.view) 

    } 

} 



override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) { 


    if let touch = touches.first as? UITouch{ 

     let currentPoint = touch.locationInView(view) 



     prevPoint2 = prevPoint1 

     prevPoint1 = touch.previousLocationInView(self.view) 





     UIGraphicsBeginImageContext(view.frame.size) 

     let context = UIGraphicsGetCurrentContext() 

     TempImage.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) 



     var mid1 = CGPointMake((prevPoint1.x + prevPoint2.x)*0.5, (prevPoint1.y + prevPoint2.y)*0.5) 

     var mid2 = CGPointMake((currentPoint.x + prevPoint1.x)*0.5, (currentPoint.y + prevPoint1.y)*0.5) 



     CGContextMoveToPoint(context, mid1.x, mid1.y) 

     CGContextAddQuadCurveToPoint(context, prevPoint1.x, prevPoint1.y, mid2.x, mid2.y) 

     //CGContextAddLineToPoint(context, toPoint.x, toPoint.y) 



     CGContextSetLineCap(context, kCGLineCapRound) 

     CGContextSetLineWidth(context, brushWidth) 

     CGContextSetRGBStrokeColor(context, red, green,blue, 1.0) 

     CGContextSetBlendMode(context, kCGBlendModeNormal) 



     CGContextStrokePath(context) 



     TempImage.image = UIGraphicsGetImageFromCurrentImageContext() 

     TempImage.alpha = opacity 

     UIGraphicsEndImageContext() 



     lastPoint = currentPoint 

    } 

} 



override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) { 



    UIGraphicsBeginImageContext(MainImage.frame.size) 

    MainImage.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: 1.0) 

    TempImage.image?.drawInRect(CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height), blendMode: kCGBlendModeNormal, alpha: opacity) 

    MainImage.image = UIGraphicsGetImageFromCurrentImageContext() 

    UIGraphicsEndImageContext() 



    TempImage.image = nil 

} 
+0

Замечательно! Большое спасибо за Вашу помощь. Ваш ответ помог установить контекст, в котором необходимо было внести изменения в предыдущий код. Будучи программистом вкл/выкл, Swift является новым для меня (начало 2015 года), и я все еще участвую. Это была не простая копия, так как я, кажется, использую Swift 1.1 (я очень скоро обновляюсь!), Но по строкам я мог видеть необходимые изменения и реализовывать их. Лучше всего, решение получается гладким и быстрым. Еще раз спасибо, очень признательны! Проголосовать! – user4806509

+0

Я рад, что я облако справился :) – Bjqn

0

Для Swift 3.0

func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 
    swiped = false 
    if let touch = touches.first as? UITouch { 
     lastPoint = touch.location(in: self.view) 
    } 
} 
func drawLineFrom(fromPoint: CGPoint, toPoint: CGPoint) { 

    UIGraphicsBeginImageContext(view.frame.size) 
    let context = UIGraphicsGetCurrentContext() 
    tempImageView.image?.draw(in: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) 


    context?.move(to: fromPoint) 
    context?.addLine(to: toPoint) 

    context?.setLineCap(CGLineCap.round) 
    context?.setLineWidth(brushWidth) 
    context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0) 
    context?.setBlendMode(CGBlendMode.normal) 
    context?.strokePath() 


    tempImageView.image = UIGraphicsGetImageFromCurrentImageContext() 
    tempImageView.alpha = opacity 
    UIGraphicsEndImageContext() 

} 

func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) { 
    swiped = true 
    if let touch = touches.first as? UITouch { 
     let currentPoint = touch.location(in: view) 
     drawLineFrom(fromPoint: lastPoint, toPoint: currentPoint) 

     lastPoint = currentPoint 
    } 
} 
1

Обновление для Swift 4

 
import UIKit 
class ViewController: UIViewController { 
    @IBOutlet weak var imageView: UIImageView! 
    var prevPoint1: CGPoint! 
    var prevPoint2: CGPoint! 
    var lastPoint:CGPoint! 

    var width: CGFloat! 
    var red:CGFloat! 
    var green:CGFloat! 
    var blue:CGFloat! 
    var alpha: CGFloat! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     width = 3.0 
     red = (0.0/255.0) 
     green = (0.0/255.0) 
     blue = (0.0/255.0) 
     alpha = 1.0 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 

    override func touchesBegan(_ touches: Set, with event: UIEvent?) { 
     if let touch = touches.first { 
      prevPoint1 = touch.previousLocation(in:self.view) 
      prevPoint2 = touch.previousLocation(in:self.view) 
      lastPoint = touch.location(in:self.view) 
     } 
    } 

    override func touchesMoved(_ touches: Set, with event: UIEvent?) { 
     if let touch = touches.first { 
      let currentPoint = touch.location(in: view) 
      prevPoint2 = prevPoint1 
      prevPoint1 = touch.previousLocation(in: self.view) 

      UIGraphicsBeginImageContext(imageView.frame.size) 
      guard let context = UIGraphicsGetCurrentContext() else { 
       return 
      } 

      context.move(to:prevPoint2) 
      context.addQuadCurve(to: prevPoint1, control: prevPoint2) 
      context.setLineCap(.butt) 
      context.setLineWidth(width) 
      context.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0) 
      context.setBlendMode(.normal) 
      context.strokePath() 

      imageView.image?.draw(in: CGRect(x: 0, y: 0, width: imageView.frame.size.width, height: imageView.frame.size.height), blendMode: .overlay, alpha: 1.0) 
      imageView.image = UIGraphicsGetImageFromCurrentImageContext() 

      UIGraphicsEndImageContext() 
      lastPoint = currentPoint 
     } 
    } 
} 
Смежные вопросы