Отобразить clearColor UIViewController над UIViewController

У меня есть представление UIViewController как subview/modal поверх другого представления UIViewController, например, что subview/modal должен быть прозрачным и любые компоненты, добавленные в subview, должны быть видимыми. Проблема в том, что у меня есть subview, на черном фоне вместо clearColor. Я пытаюсь сделать UIView как clearColor, а не черным фоном. Кто-нибудь знает, что с ним не так? Любое предложение оценили.

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];

[vc setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:vc animated:NO];  

SecondViewController.m

- (void)viewDidLoad 
{
     [super viewDidLoad];
     self.view.opaque = YES;
     self.view.backgroundColor = [UIColor clearColor];
}

RESOLVED. Я исправил проблемы. Он работает так хорошо для iPhone и iPad. Modal View Controller без черного фона просто clearColor/transparent. Единственное, что мне нужно изменить - заменить UIModalPresentationFullScreen на UIModalPresentationCurrentContext. Насколько это просто!

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

ВНИМАНИЕ: Если вы используете свойство modalPresentationStyle для navigationController:

FirstViewController.m

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
vc.view.backgroundColor = [UIColor clearColor];
self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:NO completion:nil];

ЗАМЕЧАНИЕ: Плохая новость заключается в том, что вышеупомянутое решение не работает на iOS 7. Хорошей новостью является то, что я исправил проблему для iOS7! Я попросил кого-нибудь помочь, и вот что он сказал:

При представлении контроллера вида по типу, iOS удаляет контроллеры представлений под ним из иерархии представлений на время, которое оно представлено. Хотя вид вашего модально представленного контроллера просмотра прозрачен, под ним нет ничего, кроме окна приложения, которое является черным. В iOS 7 появился новый модальный стиль презентации UIModalPresentationCustom, который заставляет iOS не удалять представления под представленным контроллером представления. Однако для использования этого модального стиля презентации вы должны предоставить свой собственный делегат перехода для обработки презентации и удаления анимаций. Это описано в разделе "Пользовательские переходы с использованием контроллеров представлений" из WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218, в котором также описывается, как реализовать свой собственный делегат перехода.

Вы можете увидеть мое решение для вышеупомянутой проблемы в iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

Ответ 1

RESOLVED. Я исправил проблемы. Он работает так хорошо для iPhone и iPad. Modal View Controller без черного фона просто clearColor/transparent. Единственное, что мне нужно изменить, - это заменить UIModalPresentationFullScreen на UIModalPresentationCurrentContext. Как это просто!

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

ВНИМАНИЕ: Если вы используете свойство modalPresentationStyle для navigationController:

FirstViewController.m

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
    vc.view.backgroundColor = [UIColor clearColor];
    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:vc animated:NO completion:nil];

ЗАМЕЧАНИЕ: Плохая новость заключается в том, что вышеупомянутое решение не работает на iOS 7. Хорошей новостью является то, что я исправил проблему для iOS7! Я попросил кого-нибудь помочь, и вот что он сказал:

При представлении контроллера вида по типу, iOS удаляет контроллеры представлений под ним из иерархии представлений на время, которое оно представлено. Хотя вид вашего модально представленного контроллера просмотра прозрачен, под ним нет ничего, кроме окна приложения, которое является черным. iOS 7 представила новый модальный стиль презентации UIModalPresentationCustom, который заставляет iOS не удалять представления под представленным контроллером представления. Однако для использования этого модального стиля презентации вы должны предоставить свой собственный делегат перехода для обработки презентации и удаления анимаций. Это описано в разделе "Пользовательские переходы с использованием контроллеров представлений" из WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218, в котором также описывается, как реализовать свой собственный делегат перехода.

Вы можете увидеть мое решение для вышеупомянутой проблемы в iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

Ответ 2

iOS8 +

В iOS8 + теперь вы можете использовать новый modalPresentationStyle UIModalPresentationOverCurrentContext, чтобы представить контроллер вида с прозрачным фоном:

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    

Ответ 3

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

1. Представление контроллера просмотра

Define context

2. Представленный контроллер просмотра

Presentation: Over Current Context

Ответ 4

Это из бета-версии xCode 7 с использованием перетаскивания управления. Просто установите фон вашего адресата для очистки и установите свойства segue в IB как это (nb. Презентация также может быть "Over Full Screen" ):

введите описание изображения здесь

Ответ 5

Я нашел самый простой способ заставить его работать на iOS7 и iOS8, чтобы добавить set presentationStyle в UIModalPresentationOverCurrentContext на modallyPresentedVC (ViewController, который вы хотите представить модально) из-за iOS8:

[modallyPresentedVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
[modallyPresentedVC.navigationController setModalPresentationStyle:UIModalPresentationOverCurrentContext];

и UIModalPresentationCurrentContext при представлении VC (контроллер, который представляет modallyPresented) из-за iOS7:

[presentingVC setModalPresentationStyle:UIModalPresentationCurrentContext];
[presentingVC.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];

Потому что вещи обрабатываются по-разному на iOS7 и iOS8. Конечно, вам не нужно устанавливать свойства navigationController, если вы его не используете. Надеюсь, что это поможет.

Ответ 6

Другой способ (нет необходимости создавать настраиваемый переход и работает на iOS 7)

Использование раскадровки:

Создайте контроллер детского просмотра с размером свободы, установите ширину представления на 500x500 (например) и добавьте следующий метод:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    self.view.superview.bounds = CGRectMake(0, 0, 500, 500);
    self.view.superview.backgroundColor = [UIColor clearColor];
}

Затем создайте Modal segue с листом формы и протестируйте его.

Ответ 7

Решение iOS 7 с пользовательским segue:

CustomSegue.h
#import <UIKit/UIKit.h>

    @interface CustomSegue : UIStoryboardSegue <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning>

    @end



CustomSegue.m
#import "CustomSegue.h"

@implementation CustomSegue

-(void)perform {

    UIViewController* destViewController = (UIViewController*)[self destinationViewController];
    destViewController.view.backgroundColor = [UIColor clearColor];
    [destViewController setTransitioningDelegate:self];
    destViewController.modalPresentationStyle = UIModalPresentationCustom;
    [[self sourceViewController] presentViewController:[self destinationViewController] animated:YES completion:nil];
}


//===================================================================
// - UIViewControllerAnimatedTransitioning
//===================================================================

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext {
    return 0.25f;
}

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {

    UIView *inView = [transitionContext containerView];
    UIViewController* toVC = (UIViewController*)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    [inView addSubview:toVC.view];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];

    [UIView animateWithDuration:0.25f
                     animations:^{

                         [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)];
                     }
                     completion:^(BOOL finished) {
                         [transitionContext completeTransition:YES];
                     }];
}


//===================================================================
// - UIViewControllerTransitioningDelegate
//===================================================================

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {

    return self;
}

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
    //I will fix it later.
    //    AnimatedTransitioning *controller = [[AnimatedTransitioning alloc]init];
    //    controller.isPresenting = NO;
    //    return controller;
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator {
    return nil;
}

@end

Решение основано на коде hightech.

Ответ 8

Версия Swift2:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewController") as! YourViewController
vc.view.backgroundColor = UIColor.clearColor()
vc.modalPresentationStyle = UIModalPresentationStyle.OverFullScreen // orOverCurrentContext to place under navigation
self.presentViewController(vc, animated: true, completion: nil)

Ответ 9

Вы также можете "добавить" окно в представление.

OneViewController *vc = [[OneViewController alloc] init];
if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]) {
    [self presentViewController:vc animated:YES completion:nil];
} else {
    [self presentModalViewController:vc animated:YES];
}

[[[UIApplication sharedApplication] keyWindow] insertSubview:self.view atIndex:0];

И таким образом, презентация может быть анимирована.

Ответ 10

Для iOS7

Теперь есть способ достичь этого, используя пользовательские переходы iOS7, таким образом:

MyController * controller = [MyController new];
[controller setTransitioningDelegate:self.transitionController];
controller.modalPresentationStyle = UIModalPresentationCustom;
[self controller animated:YES completion:nil];

Чтобы создать свой настраиваемый переход, вам нужно 2 вещи:

  • Объект TransitionDelegate (реализация <UIViewControllerTransitionDelegate>)
  • Объект "AnimatedTransitioning" (реализация <UIViewControllerAnimatedTransitioning>)

Дополнительную информацию об пользовательских переходах можно найти в этом учебнике.

Ответ 11

Для меня это работает:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle:nil];
    UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MMPushNotificationViewController"];

    vc.view.backgroundColor = [UIColor clearColor];
    self.modalPresentationStyle = UIModalPresentationCurrentContext;
#ifdef __IPHONE_8_0
    if(IS_OS_8_OR_LATER)
    {
        self.providesPresentationContextTransitionStyle = YES;
        self.definesPresentationContext = YES;
        [vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
#endif


    [self presentViewController:vc animated:NO completion:nil];

MMPushNotificationViewController - это контроллер прозрачного представления, а также я сделал цвет представления MMPushNotificationViewController как clearcolor. Теперь все, что я сделал и сделал мой Transparentviewcontroller.

Ответ 12

Работает отлично на iOS7 и iOS8

UIViewController* vc=[[UIViewController alloc]initWithNibName:@"VC" bundle:nil];

vc.view.alpha=0.7;
[vc setModalPresentationStyle:UIModalPresentationOverCurrentContext];

self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;

[self presentViewController:vc animated:NO completion:nil];

Ответ 13

Решение Swift 3 и iOS10:

//create view controller
let VC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RoadTripPreviewViewController")
//remove black screen in background
VC.modalPresentationStyle = .overCurrentContext
//add clear color background
VC.view.backgroundColor = UIColor.clear
//present modal
self.present(VC, animated: true, completion: nil)

Ответ 14

Для iOS 7 и только с помощью Interface Builder это можно сделать, установив презентацию на "Over Current Context" на всех контроллерах представлений, участвующих в модальном представлении. Даже для контроллеров навигации.

Например, установите его на всех этих контроллерах представления:

NavController → RootViewController → ModalViewController

enter image description here

Ответ 15

Я не очень много играл с конструктором Storyboard/Interface, но то, что появляется у меня, - это то, что вы говорите, что представление четкое (то есть 100% альфа/сквозное изображение), а также быть непрозрачным (0% альфа - полностью твердым). Эти две вещи, похоже, не мешают. Я бы прокомментировал строку self.view.opaque = YES; и посмотрел, работает ли она тогда;)

А, что-то еще, о чем я только подумал, - вполне возможно, что ваш контроллер просмотра имеет альфа-фон, но, конечно, альфа будет показывать цвет базового окна или контроллера корневого представления программы, который по умолчанию черный. На самом базовом уровне всего вашего приложения не может быть прозрачного фона - прозрачного для чего? Что позади? Должно быть что-то увидеть ЧЕРЕЗ прозрачность. Это имеет смысл?

Ответ 16

Просто используйте "self.modalPresentationStyle = UIModalPresentationCurrentContext;", при представлении представления

Будет нормально работать:)