为啥绘图路径的笔画会随着设备旋转动画而变形

Posted

技术标签:

【中文标题】为啥绘图路径的笔画会随着设备旋转动画而变形【英文标题】:Why does the drawing path's stroke become warped with device rotation animation为什么绘图路径的笔画会随着设备旋转动画而变形 【发布时间】:2020-06-21 11:04:44 【问题描述】:

当设备旋转动画发生时,是什么导致路径的笔触变形?有什么方法可以防止它发生?

就在动画开始之前,路径看起来像是用书法笔绘制的,然后在旋转完成时又看起来正常了。

绘图视图

class DrawingView: UIView 

    override func draw(_ rect: CGRect) 

        let strokeW: CGFloat = 10

        let center = CGPoint(x: self.bounds.midX, y: self.bounds.midY)

        let path = UIBezierPath(ovalIn: self.bounds.insetBy(dx: strokeW/2, dy: strokeW/2))
        path.lineWidth = strokeW
        path.stroke()

        path.move(to: center)
        path.addLine(to: CGPoint(x: 0, y: 0))
        path.stroke()
    

视图控制器

extension NSLayoutConstraint 
    func setPriority(_ priority: UILayoutPriority) -> NSLayoutConstraint 
        self.priority = priority
        return self
    


extension UILayoutPriority 
    static var high: UILayoutPriority 
        return UILayoutPriority(rawValue: 751)
    


class ViewController: UIViewController 

    var drawingView = DrawingView()

    var safeArea = UILayoutGuide()
    var lg = UILayoutGuide()
    var wConstraint: NSLayoutConstraint!
    var hConstraint: NSLayoutConstraint!

    override func loadView() 
        super.loadView()
        drawingView.backgroundColor = .systemTeal
        self.view.addSubview(drawingView)
    

    override func viewDidLoad() 
        super.viewDidLoad()

        self.drawingView.translatesAutoresizingMaskIntoConstraints = false

        applyConstraints()
        updateOrientation()
    

    func updateOrientation() 
        if self.view.bounds.width < self.view.bounds.height 
            self.wConstraint.constant = 180
            self.hConstraint.constant = 320
         else 
            self.wConstraint.constant = 320
            self.hConstraint.constant = 180
        
    

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) 

        super.viewWillTransition(to: size, with: coordinator)

        coordinator.animate(alongsideTransition: _ in

            self.updateOrientation()
            self.view.layoutIfNeeded()
            self.drawingView.setNeedsDisplay()
        )
    

    func applyConstraints() 

        safeArea = self.view.safeAreaLayoutGuide
        self.view.addLayoutGuide(lg)

        wConstraint = lg.widthAnchor.constraint(equalToConstant: 180)
        hConstraint = lg.heightAnchor.constraint(equalToConstant: 320)
        NSLayoutConstraint.activate([wConstraint, hConstraint])

        // layout guide constraints
        let lgConstraints: [NSLayoutConstraint] = ([
            lg.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor),
            lg.centerYAnchor.constraint(equalTo: safeArea.centerYAnchor),
            lg.leadingAnchor.constraint(greaterThanOrEqualTo: safeArea.leadingAnchor, constant: 10),
            lg.trailingAnchor.constraint(lessThanOrEqualTo: safeArea.trailingAnchor, constant: 10),
            lg.topAnchor.constraint(greaterThanOrEqualTo: safeArea.topAnchor, constant: 10),
            lg.bottomAnchor.constraint(lessThanOrEqualTo: safeArea.bottomAnchor, constant: 10),

            lg.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor, constant: 10).setPriority(.high),
            lg.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor, constant: 10).setPriority(.high),
            lg.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 10).setPriority(.high),
            lg.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: 10).setPriority(.high),
        ])
        NSLayoutConstraint.activate(lgConstraints)

        // drawingView constraints
        let drawingViewConstraints: [NSLayoutConstraint] = ([
            drawingView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
            drawingView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
            drawingView.topAnchor.constraint(equalTo: lg.topAnchor),
            drawingView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
        ])
        NSLayoutConstraint.activate(drawingViewConstraints)
    

【问题讨论】:

【参考方案1】:

UIView 的默认 contentMode 属性是.scaleToFill

将其更改为.scaleAspectFit 可防止笔画的宽度变形。

我从问题的示例代码中将self.drawingView.contentMode = .scaleAspectFit 设置为loadView() 以获得此结果。

【讨论】:

以上是关于为啥绘图路径的笔画会随着设备旋转动画而变形的主要内容,如果未能解决你的问题,请参考以下文章

CSS基础之过渡,动画,变形,旋转,缩放

Unity模型添加旋转动画就变形,怎么回事?

设备旋转后动画点重新定位

动画文本跟随路径[关闭]

css3中的属性 变形(transform)过渡(transtion)动画(animation)

Android属性动画之旋转动画