【问题标题】:Problems rotating UIView with drawing inside使用内部绘图旋转 UIView 的问题
【发布时间】:2017-01-22 11:33:27
【问题描述】:

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

不带旋转的 UIView:

带有旋转的 UIView:

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

主视图控制器

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

}

界面视图

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

}

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

我能做什么?提前致谢

【问题讨论】:

    标签: ios swift uiview rotation drawrect


    【解决方案1】:

    当你应该使用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)
    }
    

    这是一个演示,显示了随着滑块移动而重绘椭圆形。


    这是修改后的代码:

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

    【讨论】:

    • 谢谢!经过多次战斗,我已经看到了你的答案,在我看到它之前,我发现了关于 rect vs bounds 的问题...... ;)
    • 我假设框架高度/宽度等于边界高度/宽度,但这在旋转时似乎是错误的。致所有阅读者:确保将所有代码使用 frame 替换为 bounds
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多