我在UIView的自动旋转中遇到问题,它只是一条红线,其宽度为4,高度为横向模式下超级视图高度的一半,而在纵向模式下,高度为4点,宽度为超级视图宽度的一半。您可以在gif中看到问题。当我从横向旋转到纵向时,自动旋转的效果并不平滑且会变形。

ios - UIView自动旋转问题-LMLPHP

这是代码。我究竟做错了什么?

private var myView:UIView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    myView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width/2, height: 4))
    myView.backgroundColor = UIColor.red
    view.addSubview(myView)

    myView.center = CGPoint(x: view.bounds.width/2, y: view.bounds.height/2)


}

private func layoutMyView() {

    let orientation = UIApplication.shared.statusBarOrientation

    if orientation == .landscapeLeft || orientation == .landscapeRight {
        myView.frame = CGRect(x: 0, y: 0, width: view.bounds.width/2, height: 4)
    } else {
        myView.frame = CGRect(x: 0, y: 0, width: 4, height: view.bounds.height/2)
    }

    myView.center = CGPoint(x: view.bounds.width/2, y: view.bounds.height/2)
}


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

    let orientation = UIApplication.shared.statusBarOrientation

    NSLog("View will transition to \(size), \(orientation.rawValue)")

    if size.width < size.height {
        NSLog("Portrait mode")
    } else {
        NSLog("Landscape mode")
    }

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

    coordinator.animate(alongsideTransition: { [unowned self] (_) in

        let orient = UIApplication.shared.statusBarOrientation

         self.layoutMyView()

        }, completion: { [unowned self] (UIViewControllerTransitionCoordinatorContext) -> Void in

            let orient = UIApplication.shared.statusBarOrientation
            self.layoutMyView()
            NSLog("rotation completed to \(orient.rawValue), \(self.myView.frame)")
    })
}

最佳答案

有一些潜在的选择:


animate(alongsideTransition:completion:)中,执行关键帧动画以设置动画中间点,这样您就不会最终获得那种好奇的盒子感动画。例如。缩小到4x4的盒子

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

    let origin = CGPoint(x: (view.bounds.midX + view.bounds.midY) / 2 - 2,
                         y: (view.bounds.midX + view.bounds.midY) / 2 - 2)

    coordinator.animate(alongsideTransition: { _ in
        UIView.animateKeyframes(withDuration: coordinator.transitionDuration, delay: 0, animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) {
                self.myView.frame = CGRect(origin: origin, size: CGSize(width: 4, height: 4))
            }

            UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
                self.layoutMyView()
            }
        })
    })
}


这个主题有许多可能的变化。这仍然使视图具有生气勃勃的效果,但是却赋予了它一种“蓄意”的氛围,并且不会失去其“线条”感。

ios - UIView自动旋转问题-LMLPHP
使用UIView并更新其CAShapeLayer而不是使用path绘制“线”。
您可以在过渡过程中运行CADisplayLink,然后随着动画的进行将帧更新为所需的帧。
除了为frame设置动画之外,还可以为该视图的transform设置动画,并可能以与视图旋转相反的方向旋转它。

10-08 06:26
查看更多