【发布时间】:2010-04-29 15:49:31
【问题描述】:
在给定的事件处理程序(不是“shouldAutorotateToInterfaceOrientation”方法)中,我如何检测当前的 iPad 方向?我有一个文本字段,我必须在横向视图中设置动画(当键盘出现时),而不是在纵向视图中,我想知道我处于哪个方向以查看是否需要动画。
【问题讨论】:
标签: ipad orientation
在给定的事件处理程序(不是“shouldAutorotateToInterfaceOrientation”方法)中,我如何检测当前的 iPad 方向?我有一个文本字段,我必须在横向视图中设置动画(当键盘出现时),而不是在纵向视图中,我想知道我处于哪个方向以查看是否需要动画。
【问题讨论】:
标签: ipad orientation
方向信息不是很一致,有几种方法。如果在视图控制器中,您可以使用 interfaceOrientation 属性。您可以从其他地方拨打电话:
[[UIDevice currentDevice] orientation]
或者,您可以请求接收方向更改通知:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
有些人还喜欢检查状态栏方向:
[UIApplication sharedApplication].statusBarOrientation
【讨论】:
[[UIDevice currentDevice] orientation]:该属性的值是一个常数,表示设备的当前方向。此值表示设备的物理方向,可能与应用程序用户界面的当前方向不同。有关可能值的说明,请参阅“UIDeviceOrientation”。
我觉得
[[UIDevice currentDevice] orientation];
不是很可靠。有时有效,有时无效...在我的应用程序中,我使用
[[UIApplication sharedApplication]statusBarOrientation];
而且效果很好!
【讨论】:
if(UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication]statusBarOrientation])){// landscape}else{//portrait}
其中之一:
interfaceOrientation 属性。[UIApplication sharedApplication].statusBarOrientation。[UIDevice currentDevice].orientation。 (您可能需要致电-beginGeneratingDeviceOrientationNotifications。)【讨论】:
我找到了解决 FaceUp 方向问题的技巧!!!
将方向检查延迟到应用程序开始运行后,然后设置变量、视图大小等!!!
//CODE
- (void)viewDidLoad {
[super viewDidLoad];
//DELAY
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:@selector(delayedCheck)
userInfo:nil
repeats:NO];
}
-(void)delayedCheck{
//DETERMINE ORIENTATION
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait ){
FACING = @"PU";
}
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown ){
FACING = @"PD";
}
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft ){
FACING = @"LL";
}
if( [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight ){
FACING = @"LR";
}
//DETERMINE ORIENTATION
//START
[self setStuff];
//START
}
-(void)setStuff{
if( FACING == @"PU" ){
//logic for Portrait
}
else
if( FACING == @"PD" ){
//logic for PortraitUpsideDown
}
else{
if( FACING == @"LL"){
//logic for LandscapeLeft
}
else
if( FACING == @"LR" ){
//logic for LandscapeRight
}
}
//CODE
您可以在“setStuff”函数中添加子视图、定位元素等...任何最初取决于方向的东西!!!
:D
-克里斯·阿林森
【讨论】:
您可以通过两种方式实现:
1- 通过使用以下方法:
**在-(void)viewDidLoad方法中加入下面一行:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRotated:) name:UIDeviceOrientationDidChangeNotification object:nil];
然后把这个方法放到你的类中
-(void)deviceRotated:(NSNotification*)notification
{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//Do your textField animation here
}
}
上述方法将在设备旋转时检查方向
2- 第二种方法是在-(void)viewDidLoad 中插入以下通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkRotation:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
然后将以下方法放入您的类中
-(void)checkRotation:(NSNotification*)notification
{
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
{
//Do your textField animation here
}
}
上述方法将检查 ipad 或 iPhone 状态栏的方向,并根据它制作所需方向的动画。
【讨论】:
为了确定横向与纵向,有一个内置函数:
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
BOOL inLandscape = UIDeviceOrientationIsLandscape(orientation);
【讨论】:
[UIApplication sharedApplication].statusBarOrientation 在 iPad 中在横向时返回纵向,在启动时返回纵向,在 iPad 中
【讨论】:
我不知道为什么,但每次我的应用程序启动时,前 4 个都是正确的,但随后我得到相反的方向。我使用一个静态变量来计算这个,然后有一个 BOOL 来翻转我如何手动将它发送到子视图。
因此,虽然我没有添加新的独立答案,但我说的是使用上述内容并牢记这一点。注意:我正在接收状态栏方向,因为它是应用启动时唯一被调用的内容,并且“足够正确”以帮助我移动内容。
使用它的主要问题是视图被延迟加载。确保调用包含和子视图的视图属性“之前”设置它们的位置以响应它们的方向。感谢 Apple 在我们设置不存在的变量时没有崩溃,迫使我们记住它们破坏了 OO 并迫使我们也这样做……呸,如此优雅的系统却如此破碎!说真的,我喜欢 Native,但它并不好,鼓励糟糕的 OO 设计。不是我们的错,只是提醒您的调整大小功能可能正在工作,但 Apple 的方式要求您通过使用加载视图,而不是通过创建和初始化它
【讨论】:
在您的视图控制器中,获取 self.interfaceOrientation 的只读值(界面的当前方向)。
【讨论】:
我已经尝试了许多上述方法,但似乎没有任何方法对我来说是 100% 有效的。
我的解决方案是在根视图控制器中创建一个名为 UIInterfaceOrientation 类型的 iVar。
- (void)viewDidLoad {
[super viewDidLoad];
orientation = self.interfaceOrientation; // this is accurate in iOS 6 at this point but not iOS 5; iOS 5 always returns portrait on app launch through viewDidLoad and viewWillAppear no matter which technique you use.
}
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return YES;
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
orientation = toInterfaceOrientation;
}
然后,您可以在任何需要检查方向的地方执行以下操作:
if(UIInterfaceOrientationIsPortrait(orientation)){
// portrait
}else{
// landscape
}
可能还有更好的方法,但这似乎在 98% 的情况下都有效(尽管有 iOS5)并且并不太难。请注意,iOS5 总是以纵向视图启动 iPad,然后向设备发送 willRotateTo- 和 didRotateFromInterfaceOrientation: 消息,因此该值仍然会暂时不准确。
【讨论】:
[UIDevice currentDevice].orientation 效果很好。
但是!!!
...诀窍是将其添加到 - (void)viewWillAppear:(BOOL)animated
exp:
(void)viewWillAppear:(BOOL)animated{
...
BOOL isLandscape = UIInterfaceOrientationIsLandscape(self.interfaceOrientation);
...
}
如果你在 -(void)viewDidLoad 调用它,它的工作并不可靠,特别是如果你使用多个线程(主 UI 线程、后台线程来访问大量外部数据,...)。
评论:
1) 即使您的应用设置了默认的纵向纵向,用户也可以将其锁定为横向。因此,设置默认值并不是解决它的真正解决方案。
2)还有其他任务,比如隐藏导航栏,放置在 viewWillAppear 使其工作,同时防止闪烁。同样适用于其他视图,如 UITableView willDisplayCell -> 使用它来设置 cell.selected 和 cell.accessoryType。
【讨论】: