shouldAutorotateToInterfaceOrientation not being called in iOS 6
Asked Answered
P

17

66

I'm using MGSplitViewController and I'm usingshouldAutorotateToInterfaceOrientation to control the size of the master view controller on rotation.

It's all working fine on iOS 5 but on iOS 6 (both simulator and iPad) shouldAutorotateToInterfaceOrientation is never called.

Is this a bug that I should expect to be fixed with the final release of iOS 6 or something that I'm not aware of has changed?

Pochard answered 4/9, 2012 at 9:14 Comment(1)
Checkout nice solutionLivonia
O
131

PLEASE READ this CAREFULLY or you could loose 1-2 days of your life with going nuts and fighting, shaking, turning your test device like the chimp in the zoo which grabbed a visitor's mobile! Sooner or later...promise :)

IN iOS 6

shouldAutorotateToInterfaceOrientation:

is deprecated and replaced by

shouldAutorotate

it means iOS 6 will never call shouldAutorotateToInterfaceOrientation:

so if you used the following in your application

BEFORE iOS6 (iOS5,iOS4 etc.)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
// your code for portrait mode

}

return YES;
}

you should use

AFTER iOS 6+

- (BOOL)shouldAutorotate {

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];

if (orientation == UIInterfaceOrientationPortrait) {
// your code for portrait mode

}

return YES;
}

BE AWARE

UIInterfaceOrientation is a property of UIApplication and only contains 4 possibilities which correspond to the orientation of the status bar:

UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,

UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,

UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,

UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft

DO NOT CONFUSE IT WITH

UIDeviceOrientation which is a property of the UIDevice class, and contains 7 possible values:

UIDeviceOrientationUnknown - Can not be determined

UIDeviceOrientationPortrait - Home button facing down

UIDeviceOrientationPortraitUpsideDown - Home button facing up

UIDeviceOrientationLandscapeLeft - Home button facing right

UIDeviceOrientationLandscapeRight - Home button facing left

UIDeviceOrientationFaceUp - Device is flat, with screen facing up

UIDeviceOrientationFaceDown - Device is flat, with screen facing down

even you can theoretically use UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; which returns UIDeviceOrientation - the device actual orientation - BUT you have to know that UIDeviceOrientation is not always equal UIInterfaceOrientation!!! For example, when your device is on a plain table you can receive unexpected value.

You can use UIInterfaceOrientation orientation = self.interfaceOrientation; too which returns UIInterfaceOrientation, the current orientation of the interface, BUT it's a property of UIViewController, so you can access to this one only in UIViewController classes.

If you'd like to support both prior iOS6 (iOS3/4/5) and iOS6 devices - which could be evident - just use both shouldAutorotateToInterfaceOrientation: and shouldAutorotate in your code.

From iOS 6 there are 3 levels and 3 steps which the device checks during app launch, which you have to control if you'd like.

1. Info.plist - Supported Interface Orientations

which you could set graphically in the Summary tab. The sequence of allowed orientations is IMPORTANT, which you can change manually by editing the info.plist, and the device will choose the first when the app is launching! This is critical as the problem always the launch of the app when there is the chance that the [UIDevice currentDevice].orientation is unknown, especially when we test our app on a flat surface.

plist setting in XCode (Info)

BE AWARE There is two other settings possibility with (iPad) or (iPhone) extension, if you use any of them, it will use that setting of the current device or simulator and neglect the general settings without the extension. So if you run an iPhone only app and accidentally you left a "Supported Interface Orientations (iPad)" line somewhere in the plist even without any data, it will neglect the rules you have established earlier in the general settings (in my example for iPhone) and you could get a rejection for your App with a text "We found that your app did not meet the requirements for running on iPad..." even if your app doesn't intend to use a given orientation on iPhone, but iPad will use it which could cause unpredicted errors, as all iPhone apps have to run on iPad too during the submission process.

2. AppDelegate - application:supportedInterfaceOrientationsForWindow

returning a bit mask listing of every orientations you'd like to permit, which override the info.plist settings.This is called at least once every times the device rotates.

3. Top-level view controller or RootViewController - supportedInterfaceOrientations

which gives an intersection with the set of the app and app delegate, which has to have a non zero result to avoid crash. This is called at least once every times the device rotates, except there is an another method installed in our controller:

shouldAutorotate

which interferes with the app's permitted orientations, and gives a BOOL with default YES.

BE CAREFUL when you use `NavigationController`

as the topmost controller in your AppDelegate, like this:

DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:detailViewController];
self.window.rootViewController =nil;
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;

in this case you have to place the following code in your AppDelegate as a category attachment to NavigationController class, as this is the topmost controller, and if you haven't made a subcategory of it, you have no place/code where you can set its orientation settings, so you need to force it to check your real rootViewController in this case the detailViewController for the orientations:

@implementation UINavigationController (OrientationSettings_IOS6)

-(BOOL)shouldAutorotate {
return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations {
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

after this you can set the preferred orientations in your "topmost" ViewController (in my example this is the detailViewController) with any of the methods you have available in iOS 6 for ViewControllers, as below:

1. (BOOL)shouldAutorotate

2. (NSUInteger)supportedInterfaceOrientations

3. (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
Orazio answered 4/9, 2012 at 9:14 Comment(2)
in the last example what is the OrientationSettings_IOS6 in @implementation UINavigationController (OrientationSettings_IOS6)Faceoff
@Faceoff - It's a category definition, you can use any kind of name, it's arbitrary. With the usage of category you could attach methods to other classes especially if you couldn't reach or edit the .m file. Useful phenomenon check it in the literature.Orazio
D
56

Ok, I got it to work in iOS6 iPad Simulator. Yay. Here's what I did:

I just show you before and after, it should be self explanatory:

BEFORE

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

if (interfaceOrientation==UIInterfaceOrientationPortrait) {
 // do some sh!t

}

return YES;
}

AFTER

- (BOOL)shouldAutorotate {

UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];

if (orientation==UIInterfaceOrientationPortrait) {
 // do some sh!t

}

return YES;
}

As for the supported orientation, you can either specify in info.plist as such: Supported Orientation pic

Or use code:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait; // etc
}

Edit: On second thought, if you plan to support lower versions (iOS4.3/5/5.1) as well as 6.0 then just include both methods with the same code content. Works for me (in sim anyways)

Depreciate answered 17/9, 2012 at 8:20 Comment(3)
Not sure about using [[UIDevice currentDevice] orientation]... UIDeviceOrientation is not the same thing as UIInterfaceOrientation.Colonialism
It seems that they are the same.Theology
Just in case no one wants to read my post below, please also be aware that the device may not know it's orientation at the inception of app launch. As such, you may want to also check against if (orientation == UIDeviceOrientationUnknown)Evin
D
20

Setting the app window route controller rather than, just adding it's view as a subview worked for me (as Rocotilos did)

//    [self.window addSubview:self.topLevelNavigationController.view];
self.window.rootViewController = self.topLevelNavigationController;
Discommode answered 21/9, 2012 at 9:35 Comment(1)
This does not work in iOS 6. Try the following: Create a new XCode project and choose the template Single View Application. The template's AppDelegate already contains the line you're suggesting. Then, override shouldAutorotateToInterfaceOrientation in the ViewController, set a breakpoint and debug it. The breakpoint will never be hit (iOS 6).Magdalen
B
18

Here's a solution for iOS 5 and earlier code that doesn't involve duplicating your logic. Simply add this code to your view controller and it generates the supportedInterfaceOrientations from your existing shouldAutorotateToInterfaceOrientation method.

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{
NSInteger mask = 0;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeRight])
    mask |= UIInterfaceOrientationMaskLandscapeRight;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationLandscapeLeft])
    mask |= UIInterfaceOrientationMaskLandscapeLeft;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationPortrait])
    mask |= UIInterfaceOrientationMaskPortrait;
if ([self shouldAutorotateToInterfaceOrientation: UIInterfaceOrientationPortraitUpsideDown])
    mask |= UIInterfaceOrientationMaskPortraitUpsideDown;
return mask;
}
Bastogne answered 16/10, 2012 at 20:5 Comment(3)
This is a nice idea. While I think it is not that hard, to just creating a implementation for the new method, in most situations, you still got an up-vote since this may be best solution when having a unique subclass of UIViewController which used as a base for all your controllers.Temporal
Check out a bit more elegant solutionLivonia
This is NOT the right answer. If you have specific logic built for lets say UIInterfaceOrientationPortraitUp then this code does nothing but walks through the whole direction and keeps calling shouldAutorotateToInterfaceOrientation over and over againNitrous
A
16

A quick fix for me was to add this code on my root view controller

- (BOOL)shouldAutorotate {
    return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}

This way I still use the same logic used for versions prior to iOS 6. Of course, I originally had set my rootViewController in my app delegates didFinishLaunchingWithOptions properly instead of just adding to the windows subviews.

Atalee answered 25/9, 2012 at 9:39 Comment(7)
But again this method is depreciated..Right?Gaylene
Well, shouldAutorotate is not deprecated, but shouldAutorotateToInterfaceOrientation is. However, that only means that the operating system doesn't call it any more. If you have implemented it, and it works you are free to call it. It is not deprecated for you. Of course, this is pertaining to changes in ios 6.Plattdeutsch
shouldAutorotateToInterfaceOrientation is deprecated in iOS6Ichthyoid
Deprecated means that the function is no longer supported and might be removed in the future. If you want your apps to survive updates, don't use deprecated functions.Lithometeor
shouldAutorotate is not deprecated. Really awesome solution, the only solution that worked with meFruitage
I'd personally have the older method call the new one rather than the reverse, but that's just me. People, the deprecation status of the old method should not matter when the implementations is your own.Bendick
From the docs: interfaceOrientation: Convenience property that provides the current orientation of the interface, meaningful only if the view controller is taking up the full screen. Do not use this property for informing layout decisions. Instead, use the statusBarOrientation property.Amaranthine
D
11

And while a number of the responses have the solution indicated -- that being to implement shouldAutorotate and supportedInterfaceOrientations for iOS 6 builds -- you should also be aware that if your view controller is hosted in a navigation controller then none of it will matter since the runtime will call these on the UINavigationController instance and ignore your code otherwise.

Apparently the 'solution' is to subclass UINavigationController and implement these new methods on this sub-class as described here: iOS 6 UITabBarController supported orientation with current UINavigation controller

And then you have the pleasure of changing all of your code where you use a UINavigationController to use this new sub-class instead.

This has to be one of the most pointless and annoying breaking-changes in an iOS release that I have ever seen.

Duane answered 11/10, 2012 at 2:4 Comment(0)
S
10

IOS 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
if (UIInterfaceOrientationLandscapeLeft) {
        return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
    }
    if (UIInterfaceOrientationLandscapeRight) {
        return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
    }
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

IOS 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations:(UIWindow *)window{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2


    //    return UIInterfaceOrientationMaskLandscape;
    return 24;
}
Scotty answered 10/10, 2012 at 6:55 Comment(4)
Use || operators instead of magic numbers. This will make it much easier to read!Temporal
Or UIInterfaceOrientationMaskAllButUpsideDown.Milson
@miho: NSInteger expects a number.Azpurua
I believe supportedInterfaceOrientations:(UIWindow *)window should be supportedInterfaceOrientations.Southland
I
3

This worked for me with iOS6 and Xcode 4.5 GM:

On AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    .....

    //   self.window.rootViewController = self.navigationController;

    [window setRootViewController:navigationController];

    .....

    return YES;
}

on ViewController:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration

{
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation))

    {
      // landscape
    }
    else
    {
      //portrait
    }
}
Inflationism answered 14/9, 2012 at 3:33 Comment(2)
Nope existing code does not work on iOS6. My app works on 5.x but not on iOS 6.Hohenlohe
These comments were useful for me: cocos2d-x.org/boards/6/topics/15447?r=15734Inflationism
T
3

Here's a quote from Apple's iOS SDK, XCode4.5+ (see UIViewController Class Reference, Handling View Rotations):

In iOS 6, your app supports the interface orientations defined in your app’s Info.plist file. A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations. Generally, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate in directly in decisions about what rotations are supported.

Also in iOS6, shouldAutorotateToInterfaceOrientation: method of UIViewController class is already deprecated.

So in your root view controller, you do the ff:

- (BOOL)shouldAutorotate {
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
  return UIInterfaceOrientationMaskPortrait;
}

Btw, "root view controller" is any UIViewController subclass you set as the rootViewController of your appDelegate's window object. You usually do this in the appDelegate's application:didFinishLaunchingWithOptions: method.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  // Override point for customization after application launch.
  self.window.rootViewController = [FFDashboardController create];
  [self.window makeKeyAndVisible];
  return YES;
}

As to using UINavigationController as root VC's, checkout Vladimir's answer.

Tartrazine answered 15/11, 2012 at 14:4 Comment(0)
E
3

In response to @Rocotilos, I've got an addendum that occurred in my code that I've not seen elsewhere in the forums. I ran into a situation where at the very beginning of the app's life cycle, where the orientation was not known in the shouldAutorotate method. This was causing the app to not display the view properly in landscape. After a few rotations in the simulator it was working fine.

My scenario is that there are certain views that get popped on where we would want landscape layout. As such, we would not want shouldAutorotate to return YES. I realize this might be a rare case for some, but I've spent plenty of time diagnosing this and wanted to pass along. Hope this is helpful.

- (BOOL) shouldAutorotate {

    BOOL shouldRotate = NO;
    UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];

    if ([self IsCaseWhereWeDontWantLandscapeAutorotation]) {
        shouldRotate = NO;
    } else if (orientation == UIDeviceOrientationUnknown) {
        //Handle the case where the device's orientation is not yet known
        shouldRotate = YES;
    } else {
        //Handle the normal case
        shouldRotate = (orientation == UIInterfaceOrientationMaskLandscape);
    }

    return shouldRotate;
}
Evin answered 26/11, 2012 at 2:0 Comment(0)
S
2

It turns out that only the root view handles these calls. In my case this was a normal UINavigationController. I had to change this to a subclassed file where I added the methods.

In my case I only wanted the root view portrait, and the rest portrait + landscape.

Appdelegate.h

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    S2MBookAppRootViewController *masterViewController = [[[S2MBookAppRootViewController alloc] initWithNibName:pref.rootNibName bundle:nil] autorelease];
    self.navigationController = [[[S2MBookAppNavController alloc] initWithRootViewController:masterViewController] autorelease];

    self.window.rootViewController = self.navigationController;


    [self.window makeKeyAndVisible];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:YES];

    return YES;
}

And the S2MBookAppNavController (subclass of UINavigationController)

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    if([self.viewControllers count] == 1) return UIInterfaceOrientationMaskPortrait;
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape;
}

UPDATE: When you want to force the orientation (when pushing a new view on the nav controller) try this.

Make your UINavigationController also it's own delegate:

@interface S2MBookAppNavController : UINavigationController <UINavigationControllerDelegate>

@end

And in the .m file

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.delegate = self;
    // Do any additional setup after loading the view.
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if ([UIViewController respondsToSelector:@selector(attemptRotationToDeviceOrientation)]) {
            //present/dismiss viewcontroller in order to activate rotating.
            UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
            [self presentModalViewController:mVC animated:NO];
            [self dismissModalViewControllerAnimated:NO];
        }
}
Schaller answered 23/10, 2012 at 15:1 Comment(1)
That was interesting and pointed me in the right direction. The interface issue was killing me, and my app even got rejected. My app's first version was for ios5 - no issues and approved in appstore. The second version i released with very minor changes was rejected because of orientation issues with ios6. Why does apple have to do this shit! Up-Vote for you :)Geof
C
2

Yes, problem is only window.rootViewController method called to return orientation mask. So supportedInterfaceOrientations method must be implemented in viewController which is set as window.rootViewController. But in most cases this object is not of custom class, e.g. UINavigationController. One possible solution is to subclass UINavigationController. But Apple says: "This class is not intended for subclassing", so I'd rather used another UIViewController to handle orientations and added UINavigationController as child.

MyRootViewController * myRoot = [MyRootViewController new];
self.window.rootViewController = myRoot;
[myRoot addChildViewController:navigationController];
[myRoot.view addSubview:navigationController.view];

and in MyRootViewController implement methods:

- (BOOL)shouldAutorotate {
 return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    // return your mask here e.g.:
    return UIInterfaceOrientationMaskPortrait;
}
Carboloy answered 30/10, 2012 at 11:25 Comment(2)
supportedInterfaceOrientations is called for every view controller in my application, not just the root. shouldAutorotate never seems to get called for the root controller but does get called sometimes for the other controllers.Ity
supportedInterfaceOrientations() is called on all of my UIViewControllers as well. Nevertheless, it seems to take the value of the root ViewController.Anglican
E
1

The notes under the heading UIKit here: http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html%23//apple_ref/doc/uid/TP40012166-CH1-SW19 give some clues to the answer, but it is not the whole picture. I don't have the whole picture yet, but here is what I have found so far for iOS 6.0 RTM.

If you are not really restricting the supported orientations and, instead, you are wanting to do something because the user rotated the device, then you can move the logic in

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

to

- (void)viewWillLayoutSubviews

instead.

This can probably be a direct replacement, but I have not tested in down level iOS versions yet.

If you want to restrict the supported orientations, you should do that at the UIApplicationDelegate level with

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

The documentation states that "The system determines whether an orientation is supported by intersecting the value returned by the app’s supportedInterfaceOrientationsForWindow: method with the value returned by the supportedInterfaceOrientations method of the top-most full-screen controller." but in experimentation I have found that the system ignores my view controllers supported

-(NSUInteger)supportedInterfaceOrientations

return value, even though the method is called.

Eucharis answered 3/10, 2012 at 5:37 Comment(0)
C
1

Apple has deprecated shouldautorate method from ios6 use these methods instead. See your xcode docs

- (BOOL)shouldAutorotate NS_AVAILABLE_IOS(6_0);
- (NSUInteger)supportedInterfaceOrientations NS_AVAILABLE_IOS(6_0);
// Returns interface orientation masks.
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation NS_AVAILABLE_IOS(6_0);
Chimborazo answered 13/11, 2012 at 13:30 Comment(0)
C
1

I have a series of view controllers in a UINavigationController, one of which had to be landscape only. I fixed it by subclassing the UINavigationController and adding the following code:

- (NSUInteger)supportedInterfaceOrientations{
   return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

This ensures that the topmost view controller dictates the orientation.

There is a gotcha, though: if you are moving from a vc that is limited to landscape to one that supports any orientation, the new view will display in landscape regardless of the phone's orientation. To combat this, I put the following code in the unlimited viewControllers:

- (NSUInteger)supportedInterfaceOrientations{
   if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))       
      return UIInterfaceOrientationMaskPortrait;
   else
      return UIInterfaceOrientationMaskLandscape;
}
Chihli answered 23/1, 2013 at 12:45 Comment(0)
R
1
-(BOOL)shouldAutorotate
{
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;

    if (orientation == UIDeviceOrientationUnknown) {
        return YES;
    }

    return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}
Recoup answered 10/5, 2013 at 5:49 Comment(0)
E
0

Its Working for me:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
    if ([self isKindOfClass:[YourViewController class]]) { // Your view class
        orientations |= UIInterfaceOrientationMaskPortraitUpsideDown;
    }
    return orientations;
}

orientations:

orientations |= UIInterfaceOrientationMaskLandscapeLeft;
orientations |= UIInterfaceOrientationMaskLandscapeRight;
Enamelware answered 8/3, 2013 at 10:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.