原文链接:
http://the.ichibod.com/kiji/always-constrain-a-view-controller-to-portrait-or-landscape-orientation/
Interesting problem: most of your app allows for any orientation, however one specific view controller is picky and can only be either of the portrait (or landscape) orientations. When switching to this picky view collection, the view is displayed incorrectly and then rotates, though it still is displayed incorrectly.
There is a fix to constrain one view controller to an orientation when switching between controllers in an app and I am sure this is one of many solutions. This was utilized in an iPad app for iOS 4.3.
The Plan
The example code below is meant to be implemented in a view controller (and could be implemented with more work in a UIView). The idea is to rotate the view 90 degrees before it displayed on screen, if it is coming from a landscape orientation and the view can only be portrait specifically. When the view is rotated to portrait, then we want to remove the rotation and assign it back to zero.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
Despite being constrained to only the two portrait orientations in the code above, the view is still attempted to be displayed in landscape orientation (at least in my experience).
Step One
The first step is setting up the viewWillAppear: method in the view controller. This will be called before the view controller appears and is rendered on screen.
- (void)viewWillAppear:(BOOL)animated {
CGAffineTransform rotateTransform;
switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIDeviceOrientationLandscapeLeft:
rotateTransform = CGAffineTransformMakeRotation(-90*M_PI/180.0);
break;
case UIDeviceOrientationLandscapeRight:
rotateTransform = CGAffineTransformMakeRotation(90*M_PI/180.0);
break;
default:
rotateTransform = CGAffineTransformMakeRotation(0);
break;
}
rotateTransform = CGAffineTransformTranslate(rotateTransform, +90.0, +90.0);
[self.view setTransform:rotateTransform];
}
The device orientation is determined by [UIApplication sharedApplication].statusBarOrientation. At this time, the device orientation data found at [[UIDevice currentDevice] orientation] I have found to be unreliable at the point in which viewWillAppear: is called. Therefore the statusBarOrientation is utilized. Before the view appears, the orientation is used to determine if the device is in one of the two landscape orientations and the view’s transform property is assigned the rotated transformation object that is created. All of this will rotate the view, even though the view controller thinks it is in the landscape orientation, and display it in the portrait orientation.
Step Two
The second (and last) is to implement the willRotateToInterfaceOrientation:duration: method in your controller. This method is called on a view controller immediately before the interface is about to rotate. The following code will determine if we have already rotated the view, and need to reset it before we rotate to the orientation we are looking for.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
CGAffineTransform t = self.view.transform;
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation) && t.b && t.c) {
[self.view setTransform:CGAffineTransformMakeRotation(0)];
}
}
The code above is simple. It retrieves the view’s transform information and determines if b and c in the transform matrix are both not equal to or less than 0, otherwise the view has a rotation transformation applied. Then proceeds to reset the views transform rotation to the default of 0.
Small Glitch
There is a small visual glitch that is created because of this process. The view controller and orient itself and respond to the shouldAutorotateToInterfaceOrientation: that is set in the code above. However, the controller will still think it requires a rotation so the black areas on the corners will be displayed as if the the orientation was changing. It is changing, however the view is not, because when it rotates the CGAffineTransformMakeRotation(0) is resetting it, so visually the content stays in the same position. Small, though possibly a deal breaker for some as a worthwhile solution.
I mentioned before there are probably other solutions to this problem, this one seemed to work for me. Let me know if you find any other easier ways to do this in the comments.
分享到:
相关推荐
经过视频学习和总结出来的
视图工具视图工具视图工具视图工具视图工具视图工具视图工具视图工具视图工具
这是滚动视图与列表视图的共存效果源码,我们知道滚动视图与列表视图共存会存在滚动的问题,并且列表视图只显示一个半选项。 只要当列表视图的高度设定一定的值时,列表视图同样地会显示对应的高度的选项。 因此我们...
对话框,视图 对话框,视图 对话框,视图
QQ的视图视图、列表视图、网格视图和滚动视图。越界
如果你要创建一个视图,为其指定一个名称和查询即可。Sql Server只保存视图的元数据,用户描述这个对象,以及它所包含的列,安全,依赖等。当你查询视图时,无论是获取数据还是更新数据,Sql server都用视图的定义...
MFC视图编程 MFC视图编程 MFC视图编程 MFC视图编程
月视图和周视图切换控件来舒适的调节编制文件
详细的介绍mfc树视图与列表视图的创建与用法,方便初学者学习
基于实验1创建的汽车用品网上商城数据库Shopping,理解视图和索引的概念和作用,练习视图的基本操作,包括视图的建立,视图的查询,视图的更新,视图的删除,体会视图带来的方便;练习索引的创建和删除,对比有索引...
【例1】创建ccj视图,包括计算机专业各学生的学号、其选修的课程号及成绩。要保证对该视图的修改都符合专业为计算机这个条件。 【例2】创建计算机专业学生的平均成绩视图ccj_avg,包括学号(在视图中列名为num)和...
本资源对应的文章地址为 https://blog.csdn.net/mazhiyuan1981/article/details/108745382
通过视图的设计和定义,掌握建立视图的基本方法,包括通过单张表建立视图和通过多张表建立视图,通过在定义的视图上进行查询,删除,更新,插入操作,理解视图的概念,掌握简单的视图查询方法。 3. 实验预备知识 在...
③ 在查询分析器中用SQL语句来创建视图View3和视图View4,视图View3的要求与View1相同,视图View4与视图View2的条件相同。 2、数据控制实验 ① 假定系统有U1、U2、U3 、U4、U5、U6六个登录用户,试将查询图书表的...
1、用CREATE语句建立视图,观察结果。 ⑴建立计科系(CS)学生的视图cs_student,并要求进行修改和插入操作时仍需保证该视图只有计科系的学生。 ⑵建立计科系选修了1号课程的学生的视图。 ⑶定义一个反映学生出生...
后来,PhilippeKruchten加入Rational,他的4+1视图方法演变为著名的、为许多架构师所熟知的“RUP4+1视图方法”(如下图所示)。概括而言:逻辑视图(LogicalView),设计的对象模型。进程视图(ProcessView),捕捉...
视图与查询:利用学生管理中的数据库进行操作 1、 建立视图名为学生档案视图,包含xsgl(或学生档案表)中的学号、姓名、奖学金字段的内容 2、 建立视图名为成绩视图,包含学生的学号,姓名,年龄,课程号,成绩 3、...
从数据库管理系统 (DBMS) 的观点来看,视图是数据(元数据)的说明。创建典型视图时,通过 SELECT 语句(定义一个显示为虚拟表的结果集)来定义元数据。当其它查询的 FROM 子句中引用了某个视图时,将从系统目录中...