提问者:小点点

为什么绘制路径的笔画在设备旋转动画中变得扭曲


是什么原因导致路径的笔划在设备旋转动画发生时变得扭曲? 有什么方法可以避免它的发生?

就在动画开始之前,路径看起来像是用书法笔画的,然后到旋转结束时,它又看起来正常了。

绘图视图

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可以防止笔画的宽度失真。

我从问题的示例代码中在LoadView()中设置self.DrawingView.contentMode=.ScaleaspectFit以获得此结果。