Хороший слайд-переход между не полноэкранным и полноэкранным UIViewController - PullRequest
6 голосов
/ 11 декабря 2011

У меня есть контроллер представления, который не является полноэкранным (имеет строку состояния), и я хочу представить модальный контроллер представления, который является полноэкранным.

Если я скрываю строку состояния в начале анимации (родительский)viewWillDisappear или модальное viewWillAppear), то на мгновение родитель будет виден без строки состояния, что выглядит как ошибка.

Если я сделаю это в конце анимации (родительский viewDidDisappear или модальный viewDidAppear), то статусПанель будет видна на мгновение поверх модального вида, то есть она не будет отображаться, поскольку модальное представление «покрыло ее».

Есть ли способ сделать это красиво?

edit:

Одной из возможностей было бы создание UIWindow с windowLevel = alert, по крайней мере, на время анимации.Пример рекламного объявления iAd, похоже, хорошо покрывает строку состояния без другого окна, поэтому это должно быть как-то возможно.

Ответы [ 5 ]

4 голосов
/ 20 декабря 2011

Еще один забавный маленький проект.Это было лучшее, что я мог придумать.Это не так уж плохо, если вы не возражаете против использования вашего собственного контроллера контейнера для управления представлением / отклонением контроллеров представления.Я пытаюсь сделать что-то в общем, но при желании это можно свернуть в приложение с ContainerViewController.

Обратите внимание, что я реализовал только эквивалент UIModalTransitionStyleCoverVertical.Вы можете настроить анимацию так, как вам нравится.

Соответствующий код анимации:

- (void)presentViewController:(UIViewController *)viewControllerToPresent
{   
    // do nothing if no controller
    if (!viewControllerToPresent) return;

    [__viewControllers addObject:viewControllerToPresent];
    CGRect toFrame = viewControllerToPresent.view.frame;
    toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
    viewControllerToPresent.view.frame = toFrame;

    [UIView transitionWithView:self.view
                      duration:0.2
                       options:UIViewAnimationOptionTransitionNone
                    animations:^{
                        [[UIApplication sharedApplication] setStatusBarHidden:viewControllerToPresent.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
                        [self.view addSubview:viewControllerToPresent.view];
                        viewControllerToPresent.view.frame = [UIScreen mainScreen].applicationFrame;
                    }
                    completion:nil];
}

- (void)dismissViewController
{
    // nothing to dismiss if showing first controller
    if (__viewControllers.count <= 1) return;

    UIViewController *currentViewController = [__viewControllers lastObject];
    UIViewController *previousViewController = [__viewControllers objectAtIndex:__viewControllers.count - 2];

    [UIView transitionWithView:self.view
                      duration:0.2
                       options:UIViewAnimationOptionTransitionNone
                    animations:^{
                        [[UIApplication sharedApplication] setStatusBarHidden:previousViewController.wantsFullScreenLayout withAnimation:UIStatusBarAnimationSlide];
                        CGRect toFrame = currentViewController.view.frame;
                        toFrame.origin = CGPointMake(0, CGRectGetMaxY(self.view.bounds));
                        currentViewController.view.frame = toFrame;
                    }
                    completion:^(BOOL finished) {
                        [currentViewController.view removeFromSuperview];
                        [__viewControllers removeLastObject];
                    }];
}
0 голосов
/ 21 декабря 2011

Это может быть так же просто, как отложить представление вашего modalViewController с помощью executeSelector: withDelay:

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

0 голосов
/ 16 декабря 2011

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

@interface TSFullScreenModalViewController : UIViewController
{
    UIWindow*   _window;
}

- (void) presentFullScreenModal;

@end

@implementation TSFullScreenModalViewController

- (void) viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear: YES];

    [_window resignKeyWindow];
    [_window release];
    _window = nil;
}

- (void) presentFullScreenModal
{
    UIViewController* rvc = [[UIViewController new] autorelease];
    rvc.view.backgroundColor = [UIColor clearColor];

    _window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds] ;
    _window.windowLevel = UIWindowLevelStatusBar+1;
    _window.backgroundColor = [UIColor clearColor];
    _window.rootViewController = rvc;
    [_window makeKeyAndVisible];

    [UIApplication sharedApplication].statusBarHidden = YES;
    [rvc presentModalViewController: self animated: YES];
    [UIApplication sharedApplication].statusBarHidden = NO;
}

@end

Получите ваш контроллер модального представления, например так:

@interface MyModalViewController : TSFullScreenModalViewController
{
}

- (IBAction) onDismiss:(id)sender;

@end

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

- (IBAction) onShowModal:(id)sender
{
    MyModalViewController* mmvc = [[MyModalViewController new] autorelease];
    [mmvc presentFullScreenModal];
}

Наконец, отклоните ваш контроллер представления, как обычно:

- (IBAction) onDismiss:(id)sender
{
    [self dismissModalViewControllerAnimated: YES];
}
0 голосов
/ 18 декабря 2011

Может быть немного хакерской, но вы рассмотрели:

  1. Сделайте программный снимок экрана первого представления со строкой состояния (см. Этот ТАК вопрос )
  2. Создайте новый вид, который отображает только что снятое изображение в полноэкранном режиме (используя UIImage s initWithFrame)
  3. Скрыть строку состояния
  4. Представьте контроллер модального вида

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

РЕДАКТИРОВАТЬ :

Не подойдет для этого, потому что вы можете 'сделать скриншоты строки состояния.

0 голосов
/ 11 декабря 2011

Я делаю это в своем приложении с помощью этого кода:

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation: UIStatusBarAnimationSlide ];


DocumentListViewController * dl = [[DocumentListViewController alloc] initWithNibName:@"DocumentListView" bundle:nil] ;
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:dl];
[dl release];

// Go to the list of documents...
[[self.view superview] addSubview:nav.view];

nav.view.alpha = 0.0 ;

[self hideActivityAlert];

[UIView animateWithDuration:1.0 animations:^{
    nav.view.alpha = 1.0; } completion:^(BOOL A){
        [self.view removeFromSuperview];
        [self release];} ];

Строка состояния отображается в простом виде во время анимации.

Вы должны быть уверены, что при первом просмотре, когдастрока состояния скрыта заполнит пространство.Используйте свойство autoresizingMask с правильным значением.

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