Как принудительно или отключить ориентацию интерфейса для некоторых, но не для всех UIViewController?
У меня есть приложение с 9-10 экранами. Я вложил UINavigationController
в свой контроллер представления. У меня есть несколько контроллеров просмотра, которые я хочу установить только портретную ориентацию: это означает, что вращение устройства не должно поворачивать эти контроллеры представлений в ландшафтном режиме. Я пробовал следующие решения:
первый:
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
но экран по-прежнему вращается в альбомной ориентации.
Второе:
Я создал настраиваемый класс контроллера вида PortraitViewController
и добавил код ниже в PortraitViewController.m
@interface PortraitViewController ()
@end
@implementation PortraitViewController
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
//Here check class name and then return type of orientation
return UIInterfaceOrientationMaskPortrait;
}
@end
После этого я реализовал PortraitViewController.h
как базовый класс
#import <UIKit/UIKit.h>
#import "PortraitViewController.h"
@interface Login : PortraitViewController
@end
Он вообще не работает, по-прежнему позволяет контроллеру просмотра вращаться в ландшафтном режиме.
Есть ли какое-либо другое решение, использующее iOS 8 и не хочу, чтобы viewcontroller вращался в ландшафтном режиме?
EDIT:
Возможно ли иметь ориентацию ландшафта только для некоторых контроллеров просмотра и заставить ориентацию других диспетчеров виджетов придерживаться "Портрет"?
Ответы
Ответ 1
Попробуйте подклассифицировать UINavigationController
, который вы используете, потому что по умолчанию UINavigationController
не пересылает метод shouldAutorotate
для вашего viewcontroller.
Внесите следующий метод в подкласс UINavigationController
- (BOOL)shouldAutorotate
{
return [self.visibleViewController shouldAutorotate];
}
Теперь UINavigationController
перенаправляет вызов метода на его текущий видимый UIViewController
, поэтому вам нужно реализовать shouldAutorotate
там индивидуально, чтобы получить желаемый эффект.
Ответ 2
Ваш PortraitViewController в порядке, и я не знаю вашу конфигурацию раскадровки. В вашем случае важно то, что вы должны встроить свой контроллер целевого представления в другой новый контроллер навигации, а затем установить его в свой портрет PortraitController и представить эту навигацию по-разному, как я сделал в нижнем изображении, и он работает как ожидалось.
![введите описание изображения здесь]()
Если вы хотите показать анимацию, которая сделает анимацию презентации, например push анимацию
Ниже мой подкаталог PortrateNavigation UINavigationController
PortrateNavigation.h
#import <UIKit/UIKit.h>
@interface PortrateNavigation : UINavigationController
@end
PortrateNavigation.m
#import "PortrateNavigation.h"
@implementation PortrateNavigation
- (void)viewDidLoad {
[super viewDidLoad];
}
- (BOOL)shouldAutorotate {
return YES;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
@end
Ответ 3
Попробуйте добавить этот метод вместе с shouldAutorotate
и supportedInterfaceOrientations
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
//Setting the orientation of the view. I've set it to portrait here.
return UIInterfaceOrientationPortrait;
}
Также вы можете использовать этот [UIViewController attemptRotationToDeviceOrientation]
, чтобы он вращался до нужной новой ориентации
Ответ 4
Создайте категорию на UINavigationController
и переопределите supportedInterfaceOrientations
#import "UINavigationController+Orientation.h"
@implementation UINavigationController (Orientation)
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(BOOL)shouldAutorotate
{
return YES;
}
@end
Когда вы вставляете UINavigationController
, контейнеры не спрашивают своих детей, нужно ли вращаться или нет
Ответ 5
Вам нужно сделать это вручную. Все контроллеры представлений, в которых вы не хотите поворачивать представление, реализуют следующий метод.
- (BOOL)shouldAutorotate
{
return NO;
}
Ответ 6
Tr это в вашем представлении контроллер
- (BOOL)shouldAutorotate{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationPortrait |
UIInterfaceOrientationPortraitUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
Ответ 7
1) Сделайте переменную bool в AppDelegate.
2) Затем скопируйте и вставьте ниже код в AppDelegate.m(измените его согласно вашему требованию)
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{NSLog(@"%d", [UIDevice currentDevice].orientation)
if (self.isLandscape == YES) //bool created in first step
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
return UIInterfaceOrientationMaskPortrait;
}
3) Теперь скопируйте и вставьте ниже код в метод viewWillAppear контроллера вида, для которого вы хотите принудительно настроить ориентацию.
[AppDelegate sharedAppDelegate].isLandscape = YES; //bool created in first step
NSNumber *value1 = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight]; //change the orientation as per your requirement
[[UIDevice currentDevice] setValue:value1 forKey:@"orientation"];
4). Перед тем, как нажать этот контроллер, вам нужно сначала установить bool. Итак, скажем, вы хотите нажать контроллер просмотра ABC
[AppDelegate sharedAppDelegate].isLandscape = YES;
[self.navigationController pushViewController:<ABC view controller instance> animated:NO];
Надеюсь, это поможет!
Ответ 8
class ViewController: UIViewController {
override func shouldAutorotate() -> Bool {
return false
}
}
Вот ссылка на эту тему:
http://koreyhinton.com/blog/lock-screen-rotation-in-ios8.html
Ответ 9
Если вы хотите временно отключить автоматическое вращение, не делайте этого с помощью масок ориентации. Вместо этого переопределите метод shouldAutorotate на начальном контроллере представления. Этот метод вызывается перед выполнением любой авторотации. Если он возвращает NO, тогда вращение будет подавлено.
Итак, вам нужно подклассировать "UINavigationController", реализовать shouldAutorotate и использовать свой класс контроллера навигации в своем раскадровке.
- (BOOL)shouldAutorotate
{
id currentViewController = self.topViewController;
if ([currentViewController isKindOfClass:[DetailViewController class]])
return NO;
return YES;
}
альтернативный подход можно найти на
http://www.sebastianborggrewe.de/only-make-one-single-view-controller-rotate/