Представьте прозрачный модальный UIViewController

Я пытаюсь создать собственный alertView (для iOS7 +) самостоятельно, но у меня проблемы с представлением alertView.

У меня есть UIViewController с черным фоном (альфа установлена ​​на 0,25f) и alertView в качестве подпредставления.

Когда я хочу показать alertView, я модально представляю viewController:

-(void) show 
{
    UIWindow* window = [[UIApplication sharedApplication] keyWindow];
    self.modalTransitionStyle = UIModalPresentationCustom;
    self.transitioningDelegate = self;
    [window.rootViewController presentViewController:self animated:YES completion:nil];
}

А вот и мой объект-аниматор:

-(NSTimeInterval) transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);
    return 2;
}

-(void) animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    NSLog(@"%s",__PRETTY_FUNCTION__);

    UIView* toView = [transitionContext viewForKey:UITransitionContextToViewKey];
    toView.alpha = 0;

    UIView* container = [transitionContext containerView];
    [container addSubview:toView];

    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        toView.alpha = 0.5;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

Дело в том, что модальный VC исчезает вместе с представляющим VC в фоновом режиме, как и предполагалось, но когда анимация заканчивается, представляющий VC удаляется из фона.

Если вместо этого я вызываю [transitionContext completeTransition:YES];, представляющий VC находится в фоновом режиме, но модальный VC удаляется в конце анимации, поэтому я предполагаю, что контекст отменяет презентацию, если мы отправим «НЕТ».

Есть ли способ сохранить представляющий VC в фоновом режиме без необходимости делать его снимок и устанавливать его в качестве фона для модального представления VC?


person Imotep    schedule 12.08.2014    source источник
comment
Возможный дубликат stackoverflow.com/questions/22003967/?   -  person Daniel Galasko    schedule 28.08.2014
comment
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;   -  person Mitul Marsoniya    schedule 06.04.2017


Ответы (6)


Я пробовал это решение, и оно работает как на iOS 7, так и на 8:

if ([[UIDevice currentDevice].systemVersion integerValue] >= 8)
{
    //For iOS 8
    presentingViewController.providesPresentationContextTransitionStyle = YES;
    presentingViewController.definesPresentationContext = YES;
    presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
else
{
    //For iOS 7
    presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
}

Примечание. Помните о разнице между «presentingViewController» и «presentViewController».

person Basem Saadawy    schedule 14.01.2015
comment
Как, черт возьми, у тебя нет голосов? Это лучший ответ на свете - person jovanjovanovic; 14.01.2015
comment
Для полноэкранного просмотра (особенно при презентации из UINavigationController) используйте presentedViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; - person tomec; 15.02.2015
comment
хороший ответ. это работает и для меня. Единственное, о чем нам нужно позаботиться, - это представление и представление контроллеров представления. - person Ankit; 06.11.2016
comment
Мне также пришлось добавить цвет фона представленного контроллера представления с альфа-свойством, например: [self.view setBackgroundColor: [UIColor colorWithRed: 170 / 255.0 зеленый: 170 / 255.0 синий: 170 / 255.0 альфа: 0,4]]; - person Hima; 25.02.2018

iOS8 +

Для iOS8 + вы можете использовать нижеприведенный фрагмент кода

SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:secondViewController animated:YES completion:nil];    
person arunjos007    schedule 11.01.2017

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

В Storyboard я изменил презентацию моего segue на «Over Full Screen», и это помогло.

person Carien van Zyl    schedule 22.09.2015

Я думаю, что вы видите стандартное поведение iOS.

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

Я думаю, что ваше единственное решение - сделать нестандартную презентацию.

Реплика: Я этого не тестировал. Но происходит это примерно так.

/* Create a window to hold the view controller. */
UIWindow *presenterWindow = [[UIWindow alloc] init];

/* Make the window transparent. */
presenterWindow.backgroundColor = [UIColor clearColor];
presenterWindow.opaque = NO;

/* Set the window rootViewController to the view controller you
   want to display as a modal. */
presenterWindow.rootViewController = myModalViewController;

/* Setup animation */
CGRect windowEndFrame = [UIScreen mainScreen].bounds;
CGRect windowStartFrame = windowEndFrame;

/* Adjust the start frame to appear from the bottom of the screen. */
windowStartFrame.origin.y = windowEndFrame.size.height;

/* Set the window start frame. */
presenterWindow.frame = windowStartFrame;

/* Put the window on screen. */
[presenterWindow makeKeyAndVisible];

/* Perform the animation. */
[UIView animateWithDuration:0.5
                      delay:.0
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     presenterWindow.frame = windowEndFrame;
                 }
                 completion:^(BOOL finished){
                     /* Your transition end code */
                 }];

Однако это не оставляет вам возможности использовать какую-либо логику контроллера представления, встроенную в UIViewController. Когда представленный контроллер представления будет готов, вам нужно будет представить себя, а затем отменить анимацию и убрать UIWindow с экрана.

person Trenskow    schedule 12.08.2014
comment
Глядя на stackoverflow.com/questions/11236367.com/questions/11236367 /, а точнее на github.com/hightech/, я думаю, это должно сработать. И что еще более важно, вначале мой alertView был просто представлением, которое я добавил в окно приложения, но оно не вращалось. Поэтому я завернул его в VC, чтобы помочь ему справиться с вращением. Я думаю, что вращение не обрабатывается вашим решением. - person Imotep; 12.08.2014

ViewController не должен быть прозрачным, когда вы его представляете или нажимаете. Вы можете попробовать добавить его как подпредставление. А для эффекта перехода измените его рамку сразу после добавления в качестве подпредставления. Сделайте его рамку где-нибудь за пределами видимого вида, а затем анимируйте его, чтобы изменить рамку на видимый вид.

Надеюсь это поможет.

person Nameet    schedule 12.08.2014
comment
Если я добавлю его как подвид окон, он не будет вращаться вместе с пользовательским интерфейсом, а если я добавлю его как подвид верхнего VC, прозрачный фон не будет покрывать весь пользовательский интерфейс. - person Imotep; 12.08.2014

К вашему сведению, я наконец сделал свой собственный alertView подклассом UIView для «части popUp». Чтобы показать это, я просто добавляю alertView в качестве подпредставления keyWindow с ограничениями для его центрирования и помещаю за ним прозрачный черный фоновый вид.

Поскольку это не контроллер, мне приходится самостоятельно управлять ротацией пользовательского интерфейса (только для iOS 7 он хорошо сочетается с пользовательским интерфейсом в iOS 8).

person Imotep    schedule 28.08.2014