UIAlertController:supportedInterfaceOrientations was invoked recursively
Asked Answered
M

7

39

When two alert present one by one, i means one alert present and over them another alert presenting and app crashing. I have used UIAlertController to display alert. App crashing only in iOS 9 device.

Please help me at this point.

Multifoil answered 14/7, 2015 at 12:38 Comment(0)
M
76

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
    }
}
Mak answered 14/8, 2015 at 12:48 Comment(5)
@Mak You should not be overriding a method using a category, it is undefined which method will be called, Apple strongly recommends against this.Thanasi
In Xcode 7 and Swift 2.1 seems like we need supportedInterfaceOrientations to return UIInterfaceOrientationMask instead of Int. Then you also don't have to cast the return value.Drosophila
Looks like it's no longer an issue with newer SDKs (as of iOS 10 and 11). And in fact, once you bump up Deployment target from iOS 8 to iOS 9, the solution here will cause issues like keyboard being pulled up from side when the app is actually in landscape mode.Avunculate
@CodePlumber I've just started seeing this issue on Xcode 9.4.1, iOS 11 so don't think it's been fixed. Deployment target is iOS 10.Agminate
@OscarGomez I had a similar issue in my app when overriding methods in an extensions. I'm struggling to find apple documentation that says we should not do this. Could you point me in the right direction?Masaryk
H
16

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
Huerta answered 18/9, 2015 at 8:42 Comment(0)
G
6

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
    }
}
Gregggreggory answered 7/4, 2016 at 12:34 Comment(0)
P
3

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
       }
}
Passementerie answered 22/9, 2015 at 13:33 Comment(0)
M
2

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

Multifoil answered 26/9, 2015 at 13:25 Comment(8)
It isn't fixed in 9.0.1… :-(Jetty
Do you have tried in iOS 9.0? which apple released on 9th SepMultifoil
Yep! I've found the bug in iOS 9.0.1… See screenshotJetty
Still occurs in 9.3Cahier
Still occurs in 10Divinize
Still occurs in 11Grammalogue
Still occurs in 12Anemography
Still occurs in 14Norland
F
0

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.

Flagler answered 12/1, 2016 at 23:2 Comment(0)
E
0

In my project i have various screens which support various orientations, for this reason one universal extension is not enough.

My solution (Swift 5.2):

import UIKit

class UIAlertControllerWithOrientationSupport : UIAlertController {

    var fixSupportedInterfaceOrientations: UIInterfaceOrientationMask = .allButUpsideDown
    var fixShouldAutorotate: Bool = true

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return fixSupportedInterfaceOrientations
    }

    override var shouldAutorotate: Bool {
        return fixShouldAutorotate
    }

}
Eba answered 9/3, 2020 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.