0

我正在设计一个 iPad/iPhone 应用程序,其中的界面设计为横向和纵向一样好,并且我希望界面在启动时在一个方向和另一个方向上一样优雅地出现。同时,我需要能够在不同时间启用/禁用自动旋转。我想我知道如何做这两件事,但它们似乎不能很好地结合在一起。

我可以在 Xcode 项目中设置允许的设备方向,这似乎在项目 info.plist 中创建了几个数组项:“支持的界面方向(iPad)”和“支持的界面方向(iPhone)”列出了允许的方向对于每种类型的设备。这些项目的存在使得从启动屏幕的过渡在所有方向上都像丝绸一样平滑。

我可以通过在我的根视图控制器中覆盖 shouldAutorotate 来启用/禁用自动旋转(目前只有一个控制器)。问题是 info.plist 中 Supported Interface 项的存在似乎抑制了对 shouldAutorotate 的所有调用,从而导致对自动旋转的控制无效。

class   RootController: UIViewController
  {
    var allowAutorotation = true    //  My autorotation switch.
      { didSet    { guard   allowAutorotation   else  { return }
                    UIViewController.attemptRotationToDeviceOrientation()
                    /*  Do other stuff.   */ }   }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask
      { NSLog ("RootController: supportedInterfaceOrientations")
        return .allButUpsideDown  }

    override var shouldAutorotate: Bool
      { NSLog ("RootController: shouldAutorotate")
        return allowAutorotation  }

    override func viewDidLoad()
      { allowAutorotation = true
        super.viewDidLoad()  }

         }

我正在使用 viewDidLoad 尽早调用尝试RotationToDeviceOrientation()。如果我不这样做,即使设备处于横向,应用程序屏幕也会以纵向显示。(对于 Portrait,它显示正确,但 Portrait 不正确。)我尝试从其他地方进行类似的调用,包括应用程序委托中的 didFinishLaunchingWithOptions,我认为这可能是最合乎逻辑的地方,但它没有t 似乎有所作为。

如果我从 info.plist 中删除 Supported Orientation 项,并在代码中定义允许的方向,如图所示,我可以从我的 NSLog 提示中看到,对 shouldAutorotate 的调用确实发生在适当的时刻,但是在横向启动时看起来有点尴尬。在启动屏幕中,状态栏的方向是错误的:沿着垂直边缘之一而不是在顶部,当过渡到应用程序屏幕时,它通常会从水平方向倾斜约 10-20°。它会立即变为水平状态(实际上它是如此之快,以至于有时很难看到),然后状态栏正确地位于顶部,从那一刻开始一切看起来都很好,但效果似乎仍然有点不专业。

由于它只是暂时发生,并且只在启动时发生一次,我想我可以忍受它(我不能没有自动旋转控制)但我希望有人能提出一种方法来让 shouldAutorotate 调用即使在定义的方向上也能工作信息.plist。或者也许其他一些策略?

4

1 回答 1

0

我想我有解决这些问题的方法。为了消除启动屏幕淡出时的异常旋转动画,我使用 CATransactions 禁用隐式动画,直到应用程序第一次变为活动状态:

class RootController: UIViewController  {

private var appIsLaunching = true  //  Set false when app first becomes active. Never set true again.

func appDidBecomeActive()
  { if appIsLaunching  { appIsLaunching = false; CATransaction.setDisableActions (false) } } 

override func viewWillTransition (to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
  { if appIsLaunching  { CATransaction.setDisableActions (true) } 
    super.viewWillTransition (to: size, with: coordinator) }

        }

在 appDelegate 中:

func applicationDidBecomeActive ( _ application: UIApplication )
  { let root = window!.rootViewController as! RootController; root.appDidBecomeActive() }

我相信这是可行的,因为默认 CATransaction 始终有效,即使没有显式事务也是如此。从启动屏幕到第一个视图的交叉溶解似乎很完美。

启动屏幕中的状态栏仍以错误的方向显示。我已经得出结论,最好将其关闭,无论是在项目设置中还是通过设置状态栏最初隐藏在 info.plist 中。不理想,但可以接受。

于 2019-10-23T22:51:15.630 回答