2017-01-22 1 views
2

드로잉을 사용하여 UIView를 회전하려고합니다 (원, 사각형 또는 선).내부에서 드로잉을 사용하여 UIView를 회전하는 중 문제가 발생했습니다.

: 내가보기를 회전 및 도면 (I 도면의 일부 속성을 변경할 때 즉, IR 필요) 도면 뷰를 따르지 않는를 새로 고칠 때 문제가

UIView의 회전없이입니다 ... 회전

UIView without rotation

의 UIView :

다음

UIView rotated and drawing distortion

가 내 간단한 코드 (원래의 코드에서 작은 발췌) :

홈페이지의 ViewController

class TestRotation: UIViewController { 

// MARK: - Properties 

var drawingView:DrawingView? 

// MARK: - Actions 

@IBAction func actionSliderRotation(_ sender: UISlider) { 

    let degrees = sender.value 
    let radians = CGFloat(degrees * Float.pi/180) 
    drawingView?.transform = CGAffineTransform(rotationAngle: radians) 

    drawingView?.setNeedsDisplay() 
} 

// MARK: - Init 

override func viewDidLoad() { 
    super.viewDidLoad() 

    drawingView = DrawingView(frame:CGRect(x:50, y:50, width: 100, height:75)) 

    self.view.addSubview(drawingView!) 

    drawingView?.setNeedsDisplay() 
} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

} 

의 UIView는

class DrawingView: UIView { 

override func draw(_ rect: CGRect) { 

    let start = CGPoint(x: 0, y: 0) 
    let end = CGPoint(x: self.frame.size.width, y: self.frame.size.height) 

    drawCicrle(start: start, end: end) 
} 

func drawCicrle(start:CGPoint, end:CGPoint) { 

    //Contexto 
    let context = UIGraphicsGetCurrentContext() 

    if context != nil { 

     //Ancho 
     context!.setLineWidth(2) 

     //Color 
     context!.setStrokeColor(UIColor.black.cgColor) 
     context!.setFillColor(UIColor.orange.cgColor) 

     let rect = CGRect(origin: start, size: CGSize(width: end.x-start.x, height: end.y-start.y)) 

     let path = UIBezierPath(ovalIn: rect) 

     path.lineWidth = 2 
     path.fill() 
     path.stroke() 

    } 
} 

// MARK: - Init 

override init(frame: CGRect) { 
    super.init(frame: frame) 

    self.backgroundColor = UIColor.gray 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
} 

} 

내가 회전 후보기를 새로 고침하지 않는 경우 문제가 일시적으로 해결 될 것으로 보인다 ,하지만 나중에 다른 이유로 (속성이 변경된) 새로 고침해야하는 경우 문제가 다시 나타납니다.

어떻게해야합니까? 미리 감사드립니다.

답변

3

bounds을 사용해야 할 때 frame을 사용하고 있습니다.

frameview을 포함하는 사각형입니다. viewsuperview 좌표계에 지정되어 있고 view을 회전 할 때 frame이 변경됩니다 (회전 된 사각형이 회전되지 않은 사각형보다 X 및 Y 방향으로 더 확장되기 때문에).

boundsview의 내용을 포함하는 사각형입니다. view 자체의 좌표계에 지정되며 view이 회전하거나 이동하면 바뀌지 않습니다. 당신이 당신의 draw(_:) 기능에 boundsframe을 변경하는 경우

, 당신이 예상대로 작동합니다

override func draw(_ rect: CGRect) { 

    let start = CGPoint(x: 0, y: 0) 
    let end = CGPoint(x: self.bounds.size.width, y: self.bounds.size.height) 

    drawCicrle(start: start, end: end) 
} 

여기에 슬라이더 이동으로 다시 그려되는 타원을 보여주는 데모입니다.

class DrawingView: UIView { 

    var fillColor = UIColor.orange { 
     didSet { 
      setNeedsDisplay() 
     } 
    } 

    override func draw(_ rect: CGRect) { 

     let start = CGPoint(x: 0, y: 0) 
     let end = CGPoint(x: self.bounds.size.width, y: self.bounds.size.height) 

     drawCircle(start: start, end: end) 
    } 

    func drawCircle(start:CGPoint, end:CGPoint) { 

     //Contexto 
     let context = UIGraphicsGetCurrentContext() 

     if context != nil { 

      //Ancho 
      context!.setLineWidth(2) 

      //Color 
      context!.setStrokeColor(UIColor.black.cgColor) 
      context!.setFillColor(fillColor.cgColor) 

      let rect = CGRect(origin: start, size: CGSize(width: end.x-start.x, height: end.y-start.y)) 

      let path = UIBezierPath(ovalIn: rect) 

      path.lineWidth = 2 
      path.fill() 
      path.stroke() 

     } 
    } 

    // MARK: - Init 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     self.backgroundColor = UIColor.gray 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

} 

@IBAction func actionSliderRotation(_ sender: UISlider) { 

    let degrees = sender.value 
    let radians = CGFloat(degrees * Float.pi/180) 
    drawingView?.transform = CGAffineTransform(rotationAngle: radians) 

    drawingView?.fillColor = UIColor(hue: CGFloat(degrees)/360.0, saturation: 1.0, brightness: 1.0, alpha: 1.0) 

} 
+0

감사 :

Rotate Oval demo


다음은 변경된 코드입니다! 나는 많은 싸움을 한 후에 당신의 답을 보았고, 내가 그것을보기 전에 rect vs bounds에 관한 이슈를 발견했습니다 ...;) –

관련 문제