Как полностью скрыть UIView при смене ориентации? - PullRequest
10 голосов
/ 12 марта 2010

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

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

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

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

- (void)viewWillAppear:(BOOL)animated;

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

- (void)viewDidAppear:(BOOL)animated;

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

Есть идеи?

Ответы [ 6 ]

10 голосов
/ 21 марта 2011

Если все, что у вас есть, это 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), поэтому вам может потребоваться настроить цифры для макета.

0 голосов
/ 23 марта 2011

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

- (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;
}
0 голосов
/ 22 марта 2011

Персонально, для подобных ситуаций я чувствую, что кодирование позиции вашего 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;
    }
}
0 голосов
/ 21 марта 2011

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

0 голосов
/ 21 марта 2011

Если есть несколько подпредставлений, которые нужно разнести по-разному в альбомной и портретной ориентации, то может быть проще взломать его с помощью дополнительного 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];
    }
}
0 голосов
/ 12 марта 2010

Внутри

- (void)didRotateFromInterfaceOrientation:
    (UIInterfaceOrientation)fromInterfaceOrientation

Чтобы скрыть это

sub_view.hidden = YES;

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

sub_view.hidden = NO;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...