如何在更改方向时完全隐藏UIView?

时间:2010-03-12 14:17:49

标签: iphone iphone-sdk-3.0 uiview autoresize

我想设计一个视图/视图控制器,在横向显示时自动显示/隐藏子视图。我希望子视图完全消失,其他子视图占用它的空间。

使用UIViewController,我编写了设置子视图的frame属性并调用它的代码:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration;

这在大多数情况下解决了这个问题,但是当视图没有出现时发生方向改变时会出现问题。 绕过这个,我也在调用调整大小的方法:

- (void)viewWillAppear:(BOOL)animated;

但是在一些罕见的情况下(涉及UISearchDisplayController)会出现问题,所以我也在调用

上的resizing方法
- (void)viewDidAppear:(BOOL)animated;

您可以理解,我对此代码不满意,我正在寻找一种更好/更高效的方法来实现这一目标。

有什么想法吗?

6 个答案:

答案 0 :(得分:10)

假设你拥有的只是一个UIWebView和一个广告横幅,那么你可以在横向时手动调整webView的大小:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
                                duration:(NSTimeInterval)duration
{
    if (toOrientation == UIInterfaceOrientationPortrait ||
        toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            [adView setHidden:NO];
        }
    } else {
        if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
            toOrientation == UIInterfaceOrientationLandscapeRight) {
            [adView setHidden:YES];
        }       
    }
}

然后也做

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromOrientation 
                                duration:(NSTimeInterval)duration
{
    UIInterfaceOrientation toOrientation = self.interfaceOrientation;
    if (toOrientation == UIInterfaceOrientationPortrait ||
        toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            [webView setBounds:CGRectMake(0.0,0.0,320.0,436.0)];
        }
    } else {
        if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
            toOrientation == UIInterfaceOrientationLandscapeRight) {
            [webView setBounds:CGRectMake(0.0,0.0,480.0,320.0)];
        }       
    }
}

尺寸假设广告横幅高度为44.0,没有导航栏(44.0)或状态栏(20.0),因此您可能需要调整布局的数字。

答案 1 :(得分:0)

内部

- (void)didRotateFromInterfaceOrientation:
    (UIInterfaceOrientation)fromInterfaceOrientation

隐藏它

sub_view.hidden = YES;

再次展示

sub_view.hidden = NO;

答案 2 :(得分:0)

如果有多个子视图需要在横向和纵向上进行非常不同的布局,那么使用额外的UIView(例如在IB中添加的landscapeView)可能更容易破解它。使用按钮,子视图等加载此视图,并根据需要进行布局。您可以使用与通常(纵向)视图相同的所有连接。请记住在标题中声明IBOutlet UIView *landscapeView;。然后您可以使用以下方法添加视图:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toOrientation 
                                duration:(NSTimeInterval)duration
{
    if ([landscapeView superview]) {
        if (toOrientation == UIInterfaceOrientationPortrait ||
            toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
            [landscapeView removeFromSuperview];
        }
    } else {
        if (toOrientation == UIInterfaceOrientationLandscapeLeft ||
            toOrientation == UIInterfaceOrientationLandscapeRight) {
            [[self view] addSubview:landscapeView];
        }       
    }
}

如果时间不能按你的意愿运作,那么你也可以在

中尝试类似的东西

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;

如果你想变得更加漂亮,那么你可以将主视图留空,同时创建UIView *portraitViewUIView *landscapeView,然后删除willRotateToInterfaceOrientation中的当前视图并添加didRotateToInterfaceOrientation中的新视图。

为安全起见,您还应确保最初显示正确的视图:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    UIInterfaceOrientation toOrientation = self.interfaceOrientation;
    if (toOrientation == UIInterfaceOrientationPortrait ||
        toOrientation == UIInterfaceOrientationPortraitUpsideDown) {
        [self.view addSubview:portraitView];
    } else {
        [self.view addSubview:landscapeView];
    }

}

以及

- (void)viewWillDisappear:(BOOL)animated
{
    if ([landscapeView superview]) {
        [landscapeView removeFromSuperview];
    }
    if ([portraitView superview]) {
        [portraitView removeFromSuperview];
    }
}

答案 3 :(得分:0)

一个选项是在旋转时呈现带有交叉渐变过渡的模态视图,并在旋转回来时将其关闭。

答案 4 :(得分:0)

Personnaly,对于这样的情况,我觉得编写subView的位置比依赖框架的布局管理要简单得多。

所以,假设你的应用程序显示标题栏,其高度为20分,这就是我要做的事情:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    CGFloat titleBarHeight = 20;
    CGFloat navBarHeight = self.navigationController.navigationBar.frame.size.height;
    if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
        webView.frame = CGRectMake(0, 0, 320, 480 - titleBarHeight - navBarHeight - adView.frame.size.height);
        adView.hidden = NO;
    }else{
        webView.frame = CGRectMake(0, 0, 480, 320 - titleBarHeight - navBarHeight);
        adView.hidden = YES;
    }
}

答案 5 :(得分:0)

我利用代码中的父视图边界。请尝试下面的代码,看看动画是否适合您。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
        {
            webView.frame = self.view.bounds;
        adView.hidden=YES;
            break;
        }
    }
}


- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    switch (fromInterfaceOrientation) {
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
        {
            webView.frame = originalFrame;
            adView.hidden=NO;
            break;
        }
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    adView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    originalFrame = webView.frame;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}