ios - 内部绘图旋转 UIView 时出现问题

标签 ios swift uiview rotation drawrect

我想旋转一个内部有绘图(圆形、矩形或直线)的 UIView。问题是当我旋转 View 并刷新绘图时(当我更改绘图的某些属性时需要 ir,即)绘图不跟随 View ...

没有旋转的 UIView:

UIView without rotation

带旋转的 UIView:

UIView rotated and drawing distortion

这是我的简单代码(原始代码的一小部分摘录):

主视图 Controller

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.
}

}

界面 View

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)
}

}

如果我旋转后不刷新 View ,似乎问题暂时解决了,但如果由于其他原因(属性更改)稍后必须刷新,问题再次出现。

我能做什么?提前致谢

最佳答案

当您应该使用 bounds 时,您正在使用 frame

frame 是包含view 的矩形。在viewsuperview的坐标系中指定,旋转viewframe发生变化>(因为旋转的正方形比未旋转的正方形在 X 和 Y 方向上延伸得更远)。

bounds 是包含view 内容的矩形。它在 view 本身的坐标系中指定,并且不会随着 view 旋转或移动而改变。

如果您在 draw(_:) 函数中将 frame 更改为 bounds,它将按您预期的那样工作:

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)
}

这是一个演示,显示了随着 slider 移动而重新绘制的椭圆。

Rotate Oval demo


修改后的代码:

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)

}

关于ios - 内部绘图旋转 UIView 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41790361/

相关文章:

ios - MKAnnotationView 标注的自定义字体

python - 从用 Swift 编写的现有项目中调用 Python 代码

ios - CGAffineTransformMakeRotation 在 3D 中旋转

ios - UIView transitionWithView 不起作用

iPhone 如何将 View Controller 的 View 添加到另一个 View Controller 的 View ?

ios - 谷歌退出 iOS

ios - 为什么我需要声明一个 AVAudioSession 实例?

ios - 当我们的应用程序在 iPad 中打开时,我们可以禁用日历事件通知弹出窗口吗?

swift - 将 unicode 字符串截断为最大字节

ios - 无法分配给 ""中的 'self'