将方向更改回纵向

Posted

技术标签:

【中文标题】将方向更改回纵向【英文标题】:Change Orientation back to Portrait 【发布时间】:2013-03-21 14:50:01 【问题描述】:

使用我的应用时,用户可以点击并观看列表中显示的视频。一旦他们点击该视频,他们就可以将方向更改为纵向或横向。列表页只有纵向。

我面临的错误是当用户观看横向视频并以横向退出页面时,我的列表页面变得一团糟。

每次用户在视频上按下完成并返回列表时,我都需要一种方法将方向转回纵向。

在我确实有的列表页面上

- (BOOL)shouldAutorotate
  return YES;

我什至尝试在 viewDidAppear 中调用 shouldAutorotate 方法,但这不起作用。我知道在页面加载后不会调用shouldAutorotate,所以有没有办法检查方向然后翻转它或者无论如何都让它成为纵向?

我仍然需要横向,所以我不会从我的 plist 文件中删除它。

任何帮助都会很棒。谢谢

编辑

这是我如何称呼我的视频播放器

    MPMoviePlayerViewController *player=[[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:[[main_data objectAtIndex:indexPath.row] objectForKey:@"url"]]];

    UIView * playerView = [player view];
    [playerView setFrame: CGRectMake(0, 0, 480, 320)];

    CGAffineTransform landscapeTransform;
    landscapeTransform = CGAffineTransformMakeRotation(90*M_PI/180.0f);
    landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);

    [playerView setTransform: landscapeTransform];

    [self presentMoviePlayerViewControllerAnimated:player];

    return;    

【问题讨论】:

也许这个问题可以帮助你***.com/questions/2324745/… 从视频列表到视频的过渡是如何完成的?模态,还是其他方式? 永远不要调用 shouldAutorotate 自己。这不是您可以调用的方法;只有系统应该这样做。自己调用它不会做任何事情。 您的目标是 ios 6 吗?您的部分问题可能是您正在使用来自不同 iOS 版本的轮换方法,但针对的是最新版本,其中轮换已更改。 (BOOL)shouldAutorotate 应该只返回 YES 或否 - 您还需要将它与 (NSInteger)supportedInterfaceOrientations 结合起来,正如 Seamus 在下面指出的那样。但是,我确实相信您的问题出在其他地方。我曾经使用过一种旧方法如下:[UIViewController attemptRotationToDeviceOrientation]。当您从视图堆栈中弹出播放器时,看看这是否有效。 【参考方案1】:

在 iOS 6 上,自动旋转行为的机制发生了变化,因此如果您在 iOS 6 设备上进行测试,则需要做一些额外的工作。在您的视图控制器中,添加以下方法:

-(NSInteger)supportedInterfaceOrientations 
    return UIInterfaceOrientationMaskPortrait;

【讨论】:

我已经添加了这个,当我第一次查看页面时它会被调用。当我进入视频时,更改方向,然后返回该页面,shouldAutorotatesupportedInterfaceOrientations 都没有被调用。 这是因为你正在从视图堆栈中弹出它(模态),因此系统没有理由调用它 我再次检查,shouldAutorotate 第一次没有被调用(我将它与另一个断点混淆了)。有没有理由首先没有调用它。是因为系统不知道它在视图堆栈中吗? 你如何展示你的第一个视图控制器?您是使用window.rootViewController 属性,还是将视图控制器的视图添加为窗口的子视图的旧方法? 我在这里想知道为什么系统不知道您的视图控制器在视图堆栈中。【参考方案2】:

您可以使用多种方法。也许最简单和最可控的就是MPMoviePlayerViewController的子类。

首先让您的应用支持所有界面方向(在app-info.plist 中)。然后限制您的列表视图(假设它是MyListViewController.m)使用适用于 iOS 6 和更早版本操作系统的方法:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

 return UIInterfaceOrientationMaskPortrait;


- (NSUInteger) supportedInterfaceOrientations 
 return(UIInterfaceOrientationMaskPortrait);


- (BOOL) shouldAutorotate 
 return FALSE;   

现在创建一个派生自MPMoviePlayerViewController 的新Objective C 类,称为MyMoviePlayerViewController。这里是MyMoviePlayerViewController.h

#import <MediaPlayer/MediaPlayer.h>

@interface MyMoviePlayerViewController : MPMoviePlayerViewController

@end

这里是MyMoviePlayerViewController.m

#import "MyMoviePlayerViewController.h"

@interface MyMoviePlayerViewController ()
@end

@implementation MyMoviePlayerViewController

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

 return YES;


- (NSUInteger) supportedInterfaceOrientations 
 return(UIInterfaceOrientationMaskAll);


- (BOOL) shouldAutorotate 
 return TRUE;    


-(id)initWithContentURL:(NSURL *)contentURL 
 UIGraphicsBeginImageContext(CGSizeMake(1,1));
 self = [super initWithContentURL:contentURL];
 UIGraphicsEndImageContext();
 if (self) 
    self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
        [[NSNotificationCenter defaultCenter] removeObserver:self
            name:MPMoviePlayerPlaybackDidFinishNotification
            object:[self moviePlayer]];
        [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(movieFinishedCallback:)
            name:MPMoviePlayerPlaybackDidFinishNotification
            object:[self moviePlayer]];
 
 return self;


- (void)viewDidLoad

    [super viewDidLoad];
[[self moviePlayer] setFullscreen:YES animated:NO];
[self moviePlayer].controlStyle = MPMovieControlStyleDefault;


- (void)movieFinishedCallback:(NSNotification*)notification 
    MPMoviePlayerController *moviePlayer = [notification object];
    [[NSNotificationCenter defaultCenter] removeObserver:self
        name:MPMoviePlayerPlaybackDidFinishNotification
        object:moviePlayer];
    self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self dismissViewControllerAnimated:YES completion:nil];

@end

然后,添加到MyListViewController.h

#import "MyMoviePlayerViewController.h"

并且,在MyListViewController.m 中,使用:

MyMoviePlayerViewController *player =[[MyMoviePlayerViewController alloc]
    initWithContentURL:URLWithString:[[main_data objectAtIndex:indexPath.row]
    objectForKey:@"url"]]];
[self presentViewController:player animated:YES completion:nil];

显然,您可以调整设置(例如动画样式、要显示的控件...)以满足您的特定需求。

【讨论】:

这个解决方案最适合我。想解决一些问题但总体上很好的解决方案【参考方案3】:

当您的视频控制器被隐藏时调用[UIViewController attemptRotationToDeviceOrientation] 怎么样?

【讨论】:

我尝试在我的viewDidAppear 方法中调用它。这是一个称呼这个的好地方吗?我没用过【参考方案4】:

在你的列表视图控制器中实现这个

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation

  return UIInterfaceOrientationPortrait ;

-anoop

【讨论】:

【参考方案5】:

试试这个,

在你的 viewdidLoad 方法中写下这一行来支持应用中的方向,

//rotation
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged) name:@"UIDeviceOrientationDidChangeNotification" object:nil];



#pragma mark -Rotation
//method for rotate your playerview, as user changes orientation
-(void)orientationChanged 

    NSLog(@"Orientation Changed..!!");
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.35];
    if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortrait)  
        playerView.transform = CGAffineTransformMakeRotation(0);
    
    else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationPortraitUpsideDown) 
        playerView.transform = CGAffineTransformMakeRotation(M_PI);
    
    else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationLandscapeLeft)  
        playerView.transform = CGAffineTransformMakeRotation(M_PI+(M_PI/2));
    
   else if ([[UIDevice currentDevice] orientation] == UIInterfaceOrientationLandscapeRight)        
        playerView.transform = CGAffineTransformMakeRotation(M_PI/2);
    
    [UIView commitAnimations];


#ifdef IOS_OLDER_THAN_6
- (BOOL)shouldAutorotateToInterfaceOrientation:   (UIInterfaceOrientation)toInterfaceOrientation

    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);

#endif

// For Newer than IOS 6.
#ifdef IOS_NEWER_OR_EQUAL_TO_6
-(BOOL)shouldAutorotate

    return NO;

- (NSUInteger)supportedInterfaceOrientations

    return (UIInterfaceOrientationMaskPortrait);

#endif

希望这会有所帮助。谢谢你.. 编码愉快

【讨论】:

【参考方案6】:

我认为你需要在- (void)movieFinishedCallback:(NSNotification*)notification的代码下面写代码

- (void)movieFinishedCallback:(NSNotification*)notification 

    [self.view setFrame: CGRectMake(0, 0, 320, 480)];
    CGAffineTransform landscapeTransform;
    landscapeTransform = CGAffineTransformMakeRotation(270*M_PI/180.0f);
    landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);
    [self.view setTransform: landscapeTransform];

【讨论】:

以上是关于将方向更改回纵向的主要内容,如果未能解决你的问题,请参考以下文章

纵向而不是横向的自动布局方向更改

如果更改屏幕方向,如何修复按钮大小?

使用 FragmentActivity 中的 viewPager 更改方向

如何在多页 NSPrintOperation 中更改页面方向?

iPad - 根据设备方向(纵向或横向)更改图像

将方向从垂直更改为倒置时更改控制器的颜色