ViewController в изменении ориентации UINavigationController
у меня есть следующая иерархия:
UINavigationController
--> RootViewController (UIViewController
) -->UITableViewController
--> DetailViewController (UIViewController
)
Я хочу заблокировать ориентацию на RootViewController только для портрета, но оставить все ориентации для остальных контроллеров вида.
если я поставлю это в подкласс UINavigationController
:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
все контроллеры вида затем заблокированы для портрета.
мой вопрос в том, есть ли способ заблокировать только RootViewController для портрета, но оставить все варианты для других контроллеров представления?
5 ответов
проверьте ссылку здесь для фиксации авторотации в iOS 6 и установите поддержку ориентации на основе просмотра: http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
вот что вы могли бы сделать:
-
создайте пользовательский контроллер навигации, который является подклассом
UINavigationController
, в Вашему .файл м:- (BOOL)shouldAutorotate { return self.topViewController.shouldAutorotate; } - (NSUInteger)supportedInterfaceOrientations { return self.topViewController.supportedInterfaceOrientations; }
-
в своем
AppDelegate.h
,@interface AppDelegate : UIResponder <UIApplicationDelegate> { UINavigationController *navigationController; ViewController *viewController; } @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController;
и в
AppDelegate.m
,- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // set initial view self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; viewController = [[ViewController alloc] initWithNibName:@"RootViewController" bundle:nil]; navigationController = [[CustomNavigationController alloc] initWithRootViewController:viewController]; // iOS 6 autorotation fix [navigationController setNavigationBarHidden:YES animated:NO]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window setRootViewController:navigationController]; // iOS 6 autorotation fix //[self.window addSubview:navigationController.view]; [self.window makeKeyAndVisible]; return YES; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window // iOS 6 autorotation fix { return UIInterfaceOrientationMaskAll; }
-
в вашем rootViewController, для любого события нажмите второй контроллер представления, сделайте следующее:
- (IBAction)pushSecondViewController:(id)sender { // push second view controller SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self.navigationController pushViewController:secondViewController animated:YES]; }
-
в каждом контроллере вида добавьте
- (BOOL)shouldAutorotate{} - (NSUInteger)supportedInterfaceOrientations{}
для iOS 6 Вы можете установить каждый контроллер вида независимо от поддержки ориентации, которую вы хотите индивидуально.
для iOS 5 и ниже вы можете установить
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{}
все кредиты идут Джону Дисальво кто написал пример приложения в ссылке.
надеюсь, что это помогает.
в Singleton
-(void)setOrientationSupport:(BOOL)flag{
flag_orientationSupport_ = flag;
}
-(BOOL)getOrientationSupport{
return flag_orientationSupport_;
}
в appdelegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([singleton getOrientationSupport])
return UIInterfaceOrientationMaskAll;
else
return UIInterfaceOrientationMaskPortrait;
}
добавьте следующий код в viewwillappear
для viewcontroller вы хотите ориентацию поддержки
[singleton setOrientationSupport:YES];
для тех контроллеров, которые вы хотите отключить ориентацию
[singleton setOrientationSupport:NO];
поместите это в свой навигационный контроллер:
- (BOOL)shouldAutorotate
{
return self.topViewController.shouldAutorotate;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
теперь добавьте это в свой контроллер корневого представления:
- (BOOL)shouldAutorotate
{
return NO;
}
Это должно сделать это!
чтобы делегировать ответственность за определение разрешенных ориентаций подвидам UINavigationController, можно использовать свойство visibleViewController контроллера навигации, чтобы сделать навигационный контроллер "спросить" это дочерние представления для их поддерживаемых ориентаций. Должен работать следующий код (Swift):
-
суб-класс навигационного контроллера:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { if let visibleView = self.visibleViewController { return visibleView.supportedInterfaceOrientations() } else { return UIInterfaceOrientationMask.All } }
-
под-вид (корневой вид) nav контроллер:
// Restrict to portrait override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.Portrait }
Я искал решение в течение нескольких часов!
Итак, после реализации необходимых методов везде. shouldAutorotate
Не нужно устанавливать в YES
потому что он уже установлен по умолчанию:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
когда пришло время показать UIViewController
который нуждается в ориентации, отличной от других представлений, я создал UIStoryboardSegue
С этой реализацией внутри:
#import "Showing.h"
@implementation Showing
- (void)perform{
NSLog(@"Showing");
UIViewController *sourceVC = self.sourceViewController;
UIViewController *presentingVC = self.destinationViewController;
[sourceVC.navigationController presentViewController:presentingVC
animated:YES
completion:nil];
}
@end
внутри UIStoryboard
я связал представления с этим сегментом (показывает):
это просто важно, что вы используете
presentViewController:animated:completion:
И НЕ
pushViewController:animated:
в противном случае ориентация не определена.
Я пробовал такие вещи, как
[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
или этот внутри UIViewController
где ориентация должна измениться, и я также попытался вызвать ее внутри моего пользовательского UIStoryboardSegues
до presentingViewController
и dismissViewController
:
[UIViewController attemptRotationToDeviceOrientation];
или
NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];
Я также попытался использовать AppDelegate
метод и всегда определять ориентацию внутри этого метода после поиска правильного UIInterfaceOrientation
реальных visibleViewController
но тогда иногда случалось сбой при переключении от одной ориентации к другой. Поэтому мне все еще интересно, почему это так сложно, и, похоже, нет никакой документации, где это объясняется правильно.
Даже после эта часть не помочь меня.