我有一个MVC应用程序,它有一个模型和几个视图(像皮肤一样)。我希望用户能够切换视图,我无法使用界面方向。最简单的方法如下:
- (void) switchToADifferentView: (UIView*) newView {
// self is a descendant of UIViewController
self.view = newView;
}
这不起作用,因为传入视图不会根据当前方向旋转(直到下一个方向更改test case)。有没有办法在视图上强制定位?看起来系统正在努力保持界面控件本身。 (或者就像手动设置正确的变换一样简单吗?)
我想我最好不要直接切换视图,而是切换控制器。这是有道理的,因为它使初始代码更简单。但是,如何切换它们之间没有“导航关系”的控制器?我想我可以使用presentModalViewController:
,但这似乎是一个黑客。导航控制器也是如此。如果我手动更换控制器,我会再次得到错误的方向:
- (void) switchToAController: (id) incoming {
[currentController.view removeFromSuperview];
[window addSubview:incoming.view]; // does not respect current orientation
}
现在怎么样?我只是将当前的控制器换成另一个控制器?同样,控制器就像在共享模型上运行的“皮肤”一样,所以假装皮肤A是皮肤B上方的“模态”对话框或者它们是导航堆栈的一部分真的没有意义。
答案 0 :(得分:1)
使用第一个代码示例直接切换视图时,可以通过手动设置变换来修复方向:
- (CGAffineTransform) transformForOrientation: (UIInterfaceOrientation) io
{
NSParameterAssert(io <= 4);
// unknown, portrait, portrait u/d, landscape L, landscape R
float angles[] = {0, 0, M_PI, M_PI/2, -M_PI/2};
return CGAffineTransformMakeRotation(angles[io]);
}
- (void) switchToView: (UIView*) newView
{
newView.transform = [self transformForOrientation:self.interfaceOrientation];
self.view = newView;
}
此外,如果您想在轮换期间交换视图,事情会变得更加复杂。首先,您必须根据当前视图转换传入视图。这必须在willRotate…
回调中完成:
- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) target
duration: (NSTimeInterval) duration
{
incomingView = [[UIView alloc] init…];
incomingView.transform = self.view.transform;
}
然后切换willAnimate…
回调中的视图,并根据目标方向设置转换:
- (void) willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation) io
duration: (NSTimeInterval) duration
{
incomingView.transform = [self transformForOrientation:io];
self.view = incomingView;
}
这样,新视图将替换当前视图并平滑旋转到目标位置。
答案 1 :(得分:0)
最后,我选择了“蹦床”方法。每个“皮肤”都是一个单独的控制器,并且有一个特殊的根控制器将皮肤呈现为模态控制器。当皮肤想要切换到另一个皮肤时,它会设置一个标志,指示所需的下一个皮肤并自行解散。根控制器唤醒(viewWillAppear
),注意到标志并显示下一个皮肤。
此解决方案有两个主要优点:1]控制器代码保持简单,因为每个控制器只显示一个视图,没有视图切换。 2]无需破解方向代码,因为系统会透明地处理模态显示控制器内的视图方向。