UIAlertController:supportedInterfaceOrientations was invoked recursively

自古美人都是妖i 提交于 2019-11-29 22:08:04
Annie

This is a bug in iOS 9 that it failed to retrieve the supportedInterfaceOrientations for UIAlertController. And it seems it dropped to an infinite recursion loop in looking for the supportedInterfaceOrientations for UIAlertController (e.g., it tracks back to UIAlertControler -> UIViewController -> UINavigationController -> UITabBarController -> UIAlertController -> ...), while the call to UIAlertController:supportedInterfaceOrientations actually is not implemented/overridden in the source code.

In my solution, I just added the following piece of code:

extension UIAlertController {     
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
    public override func shouldAutorotate() -> Bool {
        return false
    }
}

Then UIAlertController will directly return the supported orientation value without infinite loop. Hope it helps.

Edit: Swift 3.0.1

extension UIAlertController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.portrait
    }  
    open override var shouldAutorotate: Bool {
        return false
    }
}
Jim Holland

My solution is an Objective-C category for UIAlertViewController. Simply include UIAlertController+supportedInterfaceOrientations.h in any classes that use UIAlertController

UIAlertController+supportedInterfaceOrientations.h

//
//  UIAlertController+supportedInterfaceOrientations.h

#import <UIKit/UIKit.h>
@interface UIAlertController (supportedInterfaceOrientations)
@end

UIAlertController+supportedInterfaceOrientations.m

//
//  UIAlertController+supportedInterfaceOrientations.m

#import "UIAlertController+supportedInterfaceOrientations.h"

@implementation UIAlertController (supportedInterfaceOrientations)

#if __IPHONE_OS_VERSION_MAX_ALLOWED < 90000
- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
#else
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
#endif

@end
Greg

As an update to Roland Keesom's answer, above, this is what worked for me. The main difference is that the supportedInterfaceOrientations function actually returns a UIInterfaceOrientationMask rather than an Int.

And in this variant all orientations are supported.

extension UIAlertController {

    public override func shouldAutorotate() -> Bool {
        return true
    }

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.All
    }
}

Writing an extension seemed logical to me but I got

Overriding 'shouldAutorotate' must be as available as declaration it overrides

error while was implementing it. But I found another solution. I wrote a class which extends UIAlertController and overrided supportedInterfaceOrientations and shouldAutorotate functions in that class. Hope this helps.

class MyUIAlertController : UIAlertController {

       override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
              return [UIInterfaceOrientationMask.Portrait,UIInterfaceOrientationMask.PortraitUpsideDown]
       }

       override func shouldAutorotate() -> Bool {
            return false
       }
}

I was facing this issue in iOS 9 beta version(s). But seems like apple has resolved in final release of iOS 9.

timgcarlson

This can also be solved by always displaying the alert controller in a newly created UIWindow. See this SO answer on how to create a category that allows you to always display your alerts this way.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!