【问题标题】:Programatic UIViews being rotated correctly正确旋转的编程 UIView
【发布时间】:2012-06-26 22:24:32
【问题描述】:

我几乎所有的用户界面都是以编程方式完成的,只是在界面生成器中进行了一些细微的改动。但是 99% 的用户界面完全是在代码中完成的,因为我觉得通过这样做。

但是我现在在处理设备旋转时遇到了问题,因为我有几个 UIViews 被添加为子视图我面临旋转问题,因为这是我通常声明视图的方式

htmlTest.webViewTest.frame = CGRectMake(4.0, 4.0, 312.0, 363.0);

并且由于这个固定的 CGRectMake,当设备旋转时,视图保持相同的大小并且正确地适合视图的方向。

所以我研究了一个我认为很糟糕的解决方案。我在其中制作了几个视图,用户可以从中选择选项,然后我将它们动画出来。但他们需要能够处理以纵向或横向加载,然后如果在加载时它们需要能够处理从任一方向到另一个方向的旋转。

这就是我完成其中一种观点的方式。

#pragma createAwesomeJumpBar
- (void)jumpBarButtonPosition:(int)changeView
{
    // ChangeView is used to check if the this method is being called from a device rotation or from a button press (0, being rotation and 1, being tabbarButton touch

    // if tabbar selected
    if (changeView == 1) {
        if  ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait)
        {
            if (![jumpBarContainerPortrait superview]) {
                // load portrait view
                jumpBarContainerPortrait = [[UIView alloc] initWithFrame:CGRectMake(0.0, 480.0, 320, (jumpBarHeightPortrait + 49.0))];
                jumpBarContainerPortrait.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];

                // add jumpbar container to view
                [self.view insertSubview:jumpBarContainerPortrait belowSubview:actionTabBar];

                [UIView animateWithDuration:0.6
                                      delay:0.0f
                                    options:UIViewAnimationCurveEaseIn 
                                 animations:^{

                                     jumpBarContainerPortrait.frame = CGRectMake(0.0, (367 - jumpBarHeightPortrait), 320.0, (jumpBarHeightPortrait + 49.0)); // display jumpBar


                                 } completion:^(BOOL finished) {
                                     if (finished) {
                                         NSLog(@"YAY!");
                                     }
                                 }];
            }
            else if ([jumpBarContainerPortrait superview]) {
                //unload portrait view
                [UIView animateWithDuration:0.6
                                      delay:0.0f
                                    options:UIViewAnimationCurveEaseIn 
                                 animations:^{

                                     jumpBarContainerPortrait.frame = CGRectMake(0.0, 480.0, 320.0, (jumpBarHeightPortrait + 49.0)); // display jumpBar

                                     // remove selected tabButton highlight
                                     [actionTabBar setSelectedItem:nil];


                                 } completion:^(BOOL finished) {
                                     if (finished) {

                                         // remove subView for superView
                                         [jumpBarContainerPortrait removeFromSuperview];

                                     }
                                 }];

            }

        }
        else if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
        {
            if (![jumpBarContainerLandscape superview]) {
                // load landscape view
                jumpBarContainerLandscape = [[UIView alloc] initWithFrame:CGRectMake(0.0, 320, 480.0, (jumpBarHeightLandscape + 49.0))];
                jumpBarContainerLandscape.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];

                // add jumpbar container to view
                [self.view insertSubview:jumpBarContainerLandscape belowSubview:actionTabBar];

                [UIView animateWithDuration:0.6
                                      delay:0.0f
                                    options:UIViewAnimationCurveEaseIn 
                                 animations:^{

                                     jumpBarContainerLandscape.frame = CGRectMake(0.0, (207 - jumpBarHeightLandscape), 480.0,  (jumpBarHeightLandscape + 49.0)); // display jumpBar


                                 } completion:^(BOOL finished) {
                                     if (finished) {
                                         NSLog(@"YAY!");
                                     }
                                 }];
            }
            else if ([jumpBarContainerLandscape superview]) {
                // remove landscape view
                [UIView animateWithDuration:0.6
                                      delay:0.0f
                                    options:UIViewAnimationCurveEaseIn 
                                 animations:^{

                                     jumpBarContainerLandscape.frame = CGRectMake(0.0, 320, 480.0, (jumpBarHeightLandscape + 49.0)); // display jumpBar

                                     [actionTabBar setSelectedItem:nil];

                                 } completion:^(BOOL finished) {
                                     if (finished) {

                                         // remove subView for superView
                                         [jumpBarContainerLandscape removeFromSuperview];
                                     }
                                 }];
            }

        }
    }
    // if device rotated selected
    else if (changeView == 0) {
        if  ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait)
        {
            if([jumpBarContainerLandscape superview])
            {
            // Device is changing from landscape to protrait change views to fit
            // load landscape view
            jumpBarContainerPortrait = [[UIView alloc] initWithFrame:CGRectMake(0.0, (367 - jumpBarHeightPortrait), 320.0, (jumpBarHeightPortrait + 49.0))];
            jumpBarContainerPortrait.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
            jumpBarContainerPortrait.alpha = 1.0;

            // add jumpbar container to view

                [UIView transitionFromView:jumpBarContainerLandscape
                                    toView:jumpBarContainerPortrait
                                  duration:animationSpeed
                                   options:UIViewAnimationOptionTransitionCrossDissolve 
                                completion:NULL];

                [self.view insertSubview:jumpBarContainerPortrait belowSubview:actionTabBar];


            }
        }
        else if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight)
        {
            if ([jumpBarContainerPortrait superview])
            {
            // Device is changing from portrait to landscape change views to fit
            // load landscape view
            jumpBarContainerLandscape = [[UIView alloc] initWithFrame:CGRectMake(0.0, (207 - jumpBarHeightLandscape), 480.0,  (jumpBarHeightLandscape + 49.0))];
            jumpBarContainerLandscape.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
            jumpBarContainerLandscape.alpha = 1.0;

            // add jumpbar container to view

                [UIView transitionFromView:jumpBarContainerPortrait
                                    toView:jumpBarContainerLandscape
                                  duration:animationSpeed
                                   options:UIViewAnimationOptionTransitionCrossDissolve
                                completion:NULL];

                [self.view insertSubview:jumpBarContainerLandscape belowSubview:actionTabBar];



            }

        }
    }
}

在这个例子中,我有两个视图横向和纵向,显然每个名称都是针对它们各自的方向.. 上面的逻辑是这样的

if tabbarselected 

if !view visible
if device orientation portrait 
animate in portrait view.
if device orientation landscape
animate in landscape view

if view visible
if device orientation portrait
animate out portrait view
clear tabbar
if device orientation landscape
animate out landscape view
clear tabbar

if !tabbarselected //meaning listener has identified orientation of device has changed 

if device orientation portrait
unload portrait 
load landscape

if device orientation landscape
unload landscape
load portrait

我想知道是否有比经历所有这些麻烦更简单的方法!我仍然相当缺乏经验,所以这是我最好的尝试。我希望那里的人知道一种更简单的方法,而不是必须做所有这些腿部工作才能将视图添加到其他视图中,因为子视图会正确调整方向

任何帮助将不胜感激!我很绝望哈哈:)

【问题讨论】:

  • 您应该在此处使用 switch 语句。
  • hrmm...告诉开关在哪里好.. 你认为我可以用 switch 替换所有 if 语句吗?
  • 第一次创建框架时为什么不设置 autoSizing 蒙版。这样当你改变方向时它会自动调整大小?
  • 我要去阅读苹果文档。我还没有看到如何做到这一点。我认为自动调整大小仅在 Interface Builder 中可用。
  • 另外,小事,但不是在你的 CGRectMake 中硬编码数字,我总是使用超级视图的尺寸,例如,self.view.frame.size.widthself.view.frame.size.height。处理不同的屏幕尺寸(可能是 iPhone 5 的问题)、不同的方向、存在或不存在容器控制器(如 navigationController 或 tabController 等)。

标签: iphone ios uiview orientation device-orientation


【解决方案1】:

请参阅autoresizingMask documentation。为您提供与 Interface Builder 中相同的弹簧和支柱控制。例如:

CGRect frame = CGRectMake(margin, margin, self.view.frame.size.width - margin * 2, self.view.frame.size.height - margin * 2);
UIView *mySubview = [[UIView alloc] initWithFrame:frame];
[self.view mySubview];
mySubview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

此外,如果您认为 autoresizingMask 还不够(例如,当您相对于彼此移动对象以真正微调纵向与横向方向时),我建议您在 @ 中执行此布局过程987654322@ 适用于 iOS5,(或 willAnimateRotationToInterfaceOrientation 适用于 iOS4 或更早版本)。这样您就不需要自己为更改设置动画,并且动画将与屏幕旋转动画的其余部分一起完成。

【讨论】:

  • 今天 mySubview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 救了我的命 ;) 再次欢呼老兄.. 代码看起来好多了
猜你喜欢
  • 2012-11-04
  • 2011-03-23
  • 2011-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多