ios 如何在Swift中旋转UIAlertController

9q78igpj  于 2023-01-10  发布在  iOS
关注(0)|答案(4)|浏览(203)

我有一个正在工作的UIAlertController,但我想将alert.view向左旋转90度。
我该怎么做?我的代码如下:

let alert = UIAlertController(title: "", message: "Message Sample", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay", style: .Default){(action)->() in })
presentViewController(alert, animated: true) {}

我试着补充道:

alert.view.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))

但它不起作用。
谢谢大家!

pod7payv

pod7payv1#

使用此代码:

let alert = UIAlertController(title: "", message: "Message Sample", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Okay", style: .Default){(action)->() in })

self.presentViewController(alert, animated: true, completion: {() -> Void in
      alert.view.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))

})
    • 快速3**
let alert = UIAlertController(title: "", message: "Message Sample", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Okay", style: .default){(action)->() in })

    self.present(alert, animated: true, completion: {() -> Void in
        alert.view.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi/2) )

    })

您可以实现这一点:

    • 更新答复**
self.presentViewController(alert, animated: true, completion: {() -> Void in
         // alert.view.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))

        UIView.animateWithDuration(1.0, delay: 0, options: .CurveLinear, animations: { () -> Void in
            alert.view.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
        }) { (finished) -> Void in
          // do something if you need
        }

    })
1wnzp6jl

1wnzp6jl2#

我认为这可能会在FaceID中出现得更频繁。我必须解决这个问题,因为我有一个横向模式的应用程序,但当用户在iPhone上启动应用程序时,或者当他们必须使用FaceID验证应用程序时,他们通常处于纵向模式。因此,我希望根据用户手持手机的方式显示警报。我的解决方案是如下扩展UIAlertController类:

extension UIAlertController {
    open override func viewWillAppear(_ animated: Bool) {
        view.isHidden = true
    }
    override open func viewDidAppear(_ animated: Bool) {
        let appDirection = UIApplication.shared.statusBarOrientation
        let deviceDirection = UIDevice.current.orientation
        var direction:CGFloat = 0
        if deviceDirection == .portrait {
            if appDirection == .landscapeLeft {
                direction = 1.0
            } else if appDirection == .landscapeRight {
                direction = -1.0
            }
        } else if deviceDirection == .portraitUpsideDown {
            if deviceDirection == .landscapeLeft {
                direction = -1.0
            } else if appDirection == .landscapeRight {
                direction = 1.0
            }
        }
        if direction != 0 {
           view.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2) * direction);
        }
        view.isHidden = false
    }
    open override func viewWillDisappear(_ animated: Bool) {
        view.isHidden = true
    }
}
eagi6jfj

eagi6jfj3#

如果您的应用程序支持landscaneRight、landscaneLeft和default(作为纵向),则可以尝试以下操作

self.present(alertController, animated: false, completion: {
            switch UIDevice.current.orientation {
            case .landscapeRight:
                self.alertController.view.transform=CGAffineTransform(rotationAngle: CGFloat(-Double.pi / 2))
            case .landscapeLeft:
                self.alertController.view.transform=CGAffineTransform(rotationAngle: CGFloat(Double.pi / 2))
            default:
                self.alertController.view.transform=CGAffineTransform.identity
            }
        })

这将根据屏幕旋转来旋转警报视图,而不会产生任何UI动画问题。

oymdgrw7

oymdgrw74#

Nico Nierenberg的回答启发了我,但我用一些Core Animation逻辑对它进行了扩充,这个额外的逻辑是使警报在其显示和消除动画期间旋转所必需的(Nico最初的实现只是隐藏警报,这与为animated传递false的外观相同)。
我还添加了一个通知侦听器,它可以在设备方向改变时调整旋转。
这个实现假设你的原始演示是纵向的,如果你的演示控制器可以在其他方向,你需要修复radians方法。
以下是整个课程:

import UIKit

class RotatingAlertController : UIAlertController {
    
    private static let animationKey = "rotationHack"
    private static let animationDuration: TimeInterval = 0.3
    private var currentOrientation: UIDeviceOrientation = .portrait
    
    private func radians(for orientation: UIDeviceOrientation) -> CGFloat {
        switch orientation {
        case .landscapeLeft: return CGFloat.pi*0.5
        case .portraitUpsideDown: return CGFloat.pi*1
        case .landscapeRight: return CGFloat.pi*1.5
        default: return 0
        }
    }
    
    private func applyCoreAnimationRotation() {
        let rotationValue = radians(for: currentOrientation)
        let anim = CABasicAnimation(keyPath: "transform.rotation.z")
        anim.duration = 9999
        anim.toValue = rotationValue
        anim.fromValue = rotationValue
        view.layer.add(anim, forKey: RotatingAlertController.animationKey)
    }
    
    private func animatedApplyDeviceRotation() {
        let deviceOrientation = UIDevice.current.orientation
        guard deviceOrientation != currentOrientation &&
              deviceOrientation != .unknown &&
              deviceOrientation != .faceDown &&
              deviceOrientation != .faceUp
        else {
            return
        }
        UIView.animate(withDuration: RotatingAlertController.animationDuration, delay: 0) {
            self.view.transform = CGAffineTransform(rotationAngle: self.radians(for: deviceOrientation))
        }
        currentOrientation = deviceOrientation
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        currentOrientation = UIDevice.current.orientation
        applyCoreAnimationRotation()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        view.layer.removeAnimation(forKey: RotatingAlertController.animationKey)
        self.view.transform = CGAffineTransform(rotationAngle: self.radians(for: currentOrientation))
        animatedApplyDeviceRotation()
        NotificationCenter.default.addObserver(forName: UIDevice.orientationDidChangeNotification,
                                               object: nil,
                                               queue: nil) { [weak self] _ in
            self?.animatedApplyDeviceRotation()
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        NotificationCenter.default.removeObserver(self)
        applyCoreAnimationRotation()
    }
}

您可以像这样调用它:

let alert = RotatingAlertController(title: "Title", message: "Message", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)

相关问题