Как скрыть UIView полностью при изменении ориентации?

Я хочу создать элемент управления представлением/представлением, который автоматически отображает/скрывает subview, когда он находится в альбомной ориентации. Я хочу, чтобы subview полностью исчезало и другие подпункты занимали свое пространство.

Используя UIViewController, я написал код, который устанавливает свойство рамки subviews и вызывает его:

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

Это решает проблему большую часть времени, но имеет проблемы, когда изменение ориентации происходит, когда представление не появляется. чтобы обойти это, я также вызываю метод изменения размера:

- (void)viewWillAppear:(BOOL)animated;

но это имеет проблемы в некоторых редких случаях (с использованием UISearchDisplayController), поэтому я также вызываю метод изменения размера на

- (void)viewDidAppear:(BOOL)animated;

Как вы можете понять, я недоволен этим кодом, и я ищу лучший/более эффективный способ сделать это.

Любые идеи?

Ответ 1

Предполагая, что у вас есть пользовательский интерфейс UIWebView и рекламный баннер, вы можете просто изменить размер веб-страниц вручную в ландшафте:

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

Тогда также do

- (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), поэтому вам может потребоваться настроить номера для вашего макета.

Ответ 2

Внутри

- (void)didRotateFromInterfaceOrientation:
    (UIInterfaceOrientation)fromInterfaceOrientation

Чтобы скрыть его

sub_view.hidden = YES;

Чтобы снова показать его

sub_view.hidden = NO;

Ответ 3

Если есть несколько подзаголовков, которые нужно разложить по-разному в пейзаже и на портрете, тогда может быть проще взломать его с помощью дополнительного UIView, скажем, LandscapeView, добавленного в IB. Загрузите этот просмотр с помощью кнопок, подзапросов и т.д. И выложите их по своему усмотрению. Вы можете использовать все те же соединения, что и с обычным (портретным) представлением. Не забудьте объявить 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 *portraitView, так и UIView *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];
    }
}

Ответ 4

вариант состоит в том, чтобы представить модальное представление с перекрестным переходом на поворот и уволить его, когда он будет повернут назад.

Ответ 5

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;
    }
}

Ответ 6

Я использую границы родительского представления в моем коде. Попробуйте код ниже, посмотрите, работает ли анимация для вас.

- (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;
}