【问题标题】:Rotation methods deprecated, equivalent of 'didRotateFromInterfaceOrientation'?不推荐使用旋转方法,相当于“didRotateFromInterfaceOrientation”?
【发布时间】:2014-07-27 02:40:18
【问题描述】:

我正在尝试实现 iOS 8 中引入的新 viewWillTransitionToSize 方法(所有其他轮换方法都已弃用)。我想知道didRotateFromInterfaceOrientation 现在的等价物是什么,因为我们需要执行许多清理任务,而且我看不到可以分配给UIViewControllerTransitionCoordinator 以便在何时调用的块“过渡”到新尺寸完成。谢谢。

【问题讨论】:

    标签: ios iphone objective-c ios8


    【解决方案1】:

    好的找到了,只需要在传递的UIViewControllerTransitionCoordinator上使用animateAlongsideTransition:completion:方法即可。

    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
    {   
        [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
        {
            UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
            // do whatever
        } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
        { 
    
        }];
    
        [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
    }
    

    【讨论】:

    • 会像 didRotateFromInterfaceOrientation 一样每次旋转时调用这个方法吗?能否请您分享一下您使用的方法。谢谢
    • 会的。这就是我所做的:- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id&lt;UIViewControllerTransitionCoordinator&gt;)coordinator { [coordinator animateAlongsideTransition:^(id&lt;UIViewControllerTransitionCoordinatorContext&gt; context) { UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; // do whatever } completion:^(id&lt;UIViewControllerTransitionCoordinatorContext&gt; context) { }]; [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator]; }
    • 谢谢 - 我将添加一个快速版本作为答案以节省人们一些时间
    • statusbarorientation 在 iOS 9 中已弃用。还有什么选择?
    • @DeepakSharma 我参加聚会有点晚了,但你可以使用[UIDevice currentDevice].orientation。您也可以将其通过管道传输到 UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)。希望这会有所帮助!
    【解决方案2】:

    奇怪的答案的 Swift 版本

    override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    
        coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
    
            let orient = UIApplication.sharedApplication().statusBarOrientation
    
            switch orient {
            case .Portrait:
                println("Portrait")
                // Do something
            default:
                println("Anything But Portrait")
                // Do something else
            }
    
            }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
                println("rotation completed")
        })
    
        super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
    }
    

    【讨论】:

    • 这很奇怪,因为我把它放在了我的 ViewController 中,而我的日志中没有 print 任何东西。我猜是因为没有调用此方法。你能想出其他需要插入的东西才能让它工作吗?
    • 我只是将它添加到一个空项目(通用应用程序)中,无需添加任何内容即可正常工作。也许在方法的最开始放一条日志语句,看看它是否被调用。我想不出您需要添加的任何内容。你运行的是什么 iOS?
    • @DogCoffee ..它没有被调用。跟模拟器有关系吗?
    • @Saty 也可以在模拟器中工作 - 然后再次检查。按预期工作。
    • statusbarorientation 在 iOS 9 中已弃用。还有什么选择?
    【解决方案3】:

    iOS 10.3 和 Swift 3

    override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
    
            coordinator.animate(alongsideTransition: { (_) in
                let orient = newCollection.verticalSizeClass
    
                switch orient {
                case .compact:
                    print("Lanscape")///Excluding iPads!!!
    
                default:
                    print("Portrait")
                }
            }, completion: { _ in
                print("rotation completed")
            })
    
            super.willTransition(to: newCollection, with: coordinator)
        }
    

    【讨论】:

    • 为什么需要动画?您不能立即检查“newCollection”吗?
    • @cyanide 与我的动画同步
    【解决方案4】:

    Swift 3 中接受的答案:

    override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animate(alongsideTransition: { (_) in
            let orient = UIApplication.shared.statusBarOrientation
    
            switch orient {
            case .portrait:
                print("Portrait")
            // Do something
            default:
                print("Anything But Portrait")
                // Do something else
            }
        }, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
          print("rotation completed")
        })
    
        super.willTransition(to: newCollection, with: coordinator)
    }
    

    对我来说很好用?

    【讨论】:

    • 在 iOS 10 上对我不起作用——它打印的是旧方向,而不是新方向。
    • @VaddadiKartick 因为你应该使用let orient = newCollection.verticalSizeClass switch orient { case .compact: print("Lanscape") // Do something default: print("Portrait") // Do something else }
    【解决方案5】:

    因为问题是:didRotateFromInterfaceOrientation 的等价物是什么

    我想我会贡献以下代码:

    @implementation ViewController
    - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
        [super traitCollectionDidChange:previousTraitCollection];
        if (previousTraitCollection.verticalSizeClass == UIUserInterfaceSizeClassRegular) {
            NSLog(@"User has rotated to landscape");
        } else if (previousTraitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
            NSLog(@"User has rotated to portrait");
        }
    }
    @end
    

    我在模拟器中的 iPhone 上进行测试,但如果我使用 iPad 进行测试,我的打印语句将不会运行,因为 traitsCollection 不会改变。

    这很奇怪,因为这正是 Apple recommends:

    - (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
        [super traitCollectionDidChange: previousTraitCollection];
        if ((self.traitCollection.verticalSizeClass != previousTraitCollection.verticalSizeClass)
            || self.traitCollection.horizontalSizeClass != previousTraitCollection.horizontalSizeClass)) {
            // your custom implementation here
        }
    }
    

    【讨论】:

    • 第二个代码sn-p中缺少括号
    • 这可以在 iPad 上使用吗?在 iPad 上,垂直和水平类都是全屏显示的常规类?
    • 你的代码和苹果的不一样,你只是在测试垂直尺寸类。
    • 好久不见,链接的内容好像变了。
    【解决方案6】:

    [[UIApplication sharedApplication] statusBarOrientation] 在 iOS9 中已弃用,您必须针对各种设备测试 UITraitCollection

      override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    
        if newCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: .Regular)) {
          ...
        }
      }
    

    【讨论】:

    • 只有 setter 被弃用。一位 Apple 员工发帖称:“不推荐读取状态栏方向,仅写入即可。如果您在 getter 上看到此标题,这可能是我们构建标题的方式有误。” (forums.developer.apple.com/thread/12937)
    • 虽然吸气剂不是也被弃用了。根据documentation 是这样的。
    【解决方案7】:

    在 Ipad 上,特征集合没有变化,所以这里是您如何检测从开始到完成的旋转。这是 Swift 5 的语法:

    override func viewWillTransition(to size: CGSize, with coordinator: 
    UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
    
        coordinator.animate(alongsideTransition: { [unowned self] _ in
    
            self.view.backgroundColor = UIColor.blue
            print("rotation in progress")
    
        }) { [unowned self] _ in
            self.view.backgroundColor = UIColor.green
            print("rotation complete")
    
    
        }
    }
    

    【讨论】: