强迫UIView以某种方向显示的秘诀
我有一个项目其中某些UIView必须以特定的方向(Portrait或者Landscape)显示。这个看似简单的问题,困惑了我很久,直到今天我才完全找到解决的方法。
为简单起见,我以一个简单的例子说明一下我的问题。我有一个允许各种方向知道旋转的RootViewController,它包括一个共三行的UITableView,第一行显示“Portrait”,第二行显示“Landscape”,第三行显示“Autorotation”,点击某些行后,使用pushViewController打开一个DetailViewController,这个View Controller控制的view将根据行的内容有所不同。比如,如果按下的是第一行,则在DetailViewController中显示“Portrait”,并只允许UIView以portrait方式显示。
首先,我根据按下的行号,以orientation作为参数,传递给DetailViewController,在此ViewController的shouldAutorotateToInterfaceOrientation方法中根据orentation参数返回。代码如下:
1 2 3 4 5 6 7 8 9 10 11 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if ( self.orientation == 0 ) // allow portrait return (interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown); else if ( self.orientation == 1 ) // allow landscape { return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } else // allow autorotation return YES; } |
以上代码仅仅使得DetailViewController在特定情况下确定是否允许进行自动旋转。但如果初始的方向不正确的话,它却无能为力。比如,我在RootViewController(它允许任何方向的旋转)处于Landscape方向时,点击第一行(row 0),此时的DetailViewController所呈现的UIView仍然处于Landscape,当然这与我程序的本意当然不符。
于是我的问题就变成了怎样强迫UIView旋转到特定方向?我在网上搜索到一种方案,即UIDvice的setOrientation: 方法,不过遗憾的是此方法是私有api,当然我不能接受。于是我又试验了UIApplication中setStatusBarOrientation:方法,该方法果然把状态条旋转到了我需要的方向,不过我的UIView还是处于不正确的方向(以我上一段提到的情况为例)。因为在创建DetailViewController时触发的shouldAutorotateToInterfaceOrientation中(发生在setStatusBarOrientation之前),当时的UIInterfaceOrientation还是为landscape,而我的orientation参数为0,所以返回为NO,因此屏幕并没有旋转。有什么方法能够再触发一次shouldAutorotateToInterfaceOrientation吗?
答案是肯定的,见我的代码:
1 2 3 4 5 | // trick to retrigger shouldAutorotateToInterfaceOrientation method UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view]; |
在setStatusBarOrientation后,调用以上代码,强行触发了shouldAutorotateToInterfaceOrientation了,此时orientation为0,但interfaceOrientation我已经通过setStatusBarOrientation设置成了UIInterfaceOrientationPortrait,所以会返回YES,直接导致UIView的旋转。(以上代码是我在网上看到的方法)。
至此,整个解决方案就比较完满了,代码下载。不过请注意我的代码实例仅仅针对一种情况进行了处理(即orientation等于1,即仅仅允许UIView处于landscape时),其他情况依此类推。