旋转方法已被弃用,'didRotateFromInterfaceOrientation'的等效方法是什么?

142
我正在尝试实现iOS 8中引入的新方法viewWillTransitionToSize(所有其他旋转方法均已弃用)。我想知道didRotateFromInterfaceOrientation现在对应的是什么,因为我们需要执行一些清理任务,而我无法找到可以分配给UIViewControllerTransitionCoordinator的块,以便在“过渡”到新大小完成时调用它们。谢谢。
7个回答

263

好的,找到了,只需要在传递的 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];
}

2
会的。这是我的做法:`- (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; // 做你想做的事 } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { }]; [super viewWillTransitionToSize: size withTransitionCoordinator: coordinator];}` - strange
1
谢谢 - 我会添加一个Swift版本作为答案,以节省大家的时间。 - DogCoffee
有没有办法去除动画效果? - Jessica
3
"statusbarorientation在iOS 9中已过时。还有其他选择吗?" - Deepak Sharma
1
@DeepakSharma 我来晚了,但你可以使用 [UIDevice currentDevice].orientation。你还可以将其输入到 UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) 中。希望这能帮助到你! - Jeff
显示剩余7条评论

72

strange 的回答的 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中,但它没有在我的日志中打印任何东西。我猜是因为这个方法没有被调用。你能想到还需要插入什么才能使它工作吗? - Trip
我刚把它添加到一个空项目(通用应用程序)中,而且它可以正常工作,无需添加任何内容。也许在方法的开头加上一个日志语句,看看它是否被调用。我想不出你需要添加什么。你运行的是哪个iOS版本? - DogCoffee
@DogCoffee..它没有被调用。这与模拟器有关吗? - Saty
@Saty 在模拟器上也可以工作 - 我刚刚再次检查过了。表现如预期。 - DogCoffee
有没有一种方法可以在不使用子类化UIVIewController的情况下完成这个操作,因为我们正在进行MVVM-C? - Andrius Steponavičius
1
statusbarorientation在iOS 9中已被弃用。还有什么其他的选项? - Deepak Sharma

10

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
@cyanide 同步动画与我的。 - Mike Glukhov

7

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上对我不起作用——它打印的是旧方向,而不是新方向。 - Kartick Vaddadi
1
@VaddadiKartick 因为你应该使用 `let orient = newCollection.verticalSizeClass switch orient { case .compact: print("横屏") // 做一些事情 default: print("竖屏") // 做其他事情 }` - Mike Glukhov

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不会改变。

这很奇怪,因为这正是苹果推荐的做法:

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

第二个代码片段中缺少一个括号。 - Anton Duzenko
这个程序在iPad上能否正常工作,即使全屏时垂直和水平类别都是“常规”? - Deepak Sharma
你的代码与苹果公司的不同,你只是在测试垂直大小类。 - ADG
好久不见了,看起来链接的内容已经改变了。 - NYC Tech Engineer

3

[[UIApplication sharedApplication] statusBarOrientation]在iOS9中已经被弃用,你需要针对不同的设备测试UITraitCollection

  override func willTransitionToTraitCollection(newCollection: UITraitCollection, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    if newCollection.containsTraitsInCollection(UITraitCollection(verticalSizeClass: .Regular)) {
      ...
    }
  }

6
只有setter被弃用了。一位苹果员工发帖表示:"获取状态栏方向并没有被弃用,只是写入方式被弃用了。如果你在getter上看到这个问题,那可能是我们构造标题时出现了错误。"(https://forums.developer.apple.com/thread/12937) - Graham Perks
但是getter方法也被弃用了,根据文档的说明。 - Groot

1
在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")


    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接