iOS: Modal ViewController z przezroczystym tłem

180

Próbuję przedstawić kontroler widoku modalnie, z przezroczystym tłem. Moim celem jest jednoczesne wyświetlanie widoku kontrolerów widoku prezentującego i prezentowanego. Problem polega na tym, że po zakończeniu animacji prezentacji widok kontrolera widoku prezentacji znika.

- (IBAction)pushModalViewControllerButtonPressed:(id)sender
{
    ModalViewController *modalVC = [[ModalViewController alloc] init];
    [self presentViewController:modalVC animated:YES completion:nil];
}

Wiem, że mógłbym po prostu dodać widok jako widok podrzędny, ale z jakiegoś powodu chciałbym uniknąć tego rozwiązania. Jak mogę to naprawić?

Michael
źródło
4
@ TheKing Wygląda na to, że Michael, podobnie jak ja, chce, aby widok modalny był półprzezroczysty, aby pojawiał się jako unosząca się warstwa żelowa nad widokiem podstawowym (prezentującym). Tworzy wrażenie, że użytkownik pozostaje w bieżącym kontekście, dokonując szybkiego ustawienia, w przeciwieństwie do innych ważnych funkcji (w osobnym widoku).
Basil Bourque,
Zobacz moją odpowiedź tutaj stackoverflow.com/a/29794201/1606125 dla iOS 8
Pankaj Wadhwa
szybka wersja tutaj stackoverflow.com/a/34578402/3380878
Mojtabye
1
Na iOS 10 działa UIModalPresentationOverFullScreen jak inigo333 wspomniany poniżej.
Josef Rysanek

Odpowiedzi:

97

Poniższy kod działa tylko na iPadzie.

self.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:modalVC animated:YES];

Chciałbym dodać widok podrzędny.

Oto bardzo dobra dyskusja. Spójrz na komentarze. Nie tylko odpowiedź.

Widok modalny

Gdybym był tobą, nie zrobiłbym tego. Chciałbym dodać widok podrzędny i zrobić to. Wydaje się, że daje mi lepszą kontrolę nad rzeczami.

EDYTOWAĆ:

Jak wspomniał Paul Linsay, od iOS 8 wszystko, czego potrzeba, to UIModalPresentationOverFullScreenmoduł modalPresentationStyle ViewController. Dotyczy to również przycisków nawigacji i paska narzędzi.

SP
źródło
18
To czyni pracę na iOS 7 i także na iPhone, jest to, że trzeba określić modalPresentationStyle = UIModalPresentationCurrentContextna prezentera widoku kontrolera, a nie w prezentowanym jeden.
redent84
6
Tak, działa, ale TYLKO, jeśli ustawisz to na wyższej ViewController hierarchii widoków. (np. a NavigationControllerlub instancja kontrolera widoku menu slajdów, na przykład).
iGranDav,
4
O dziwo, w moim przypadku działało to tylko po ustawieniu stylu modalnego na UIModalPresentationCustomi tylko wtedy, gdy zostało ustawione tuż przed, presentViewControllera nie w viewDidLoad.
mojuba
5
Od iOS 8 wszystko, czego potrzeba, to UIModalPresentationOverFullScreen dla prezentowanego modalPresentationStyle ViewController.
Paul Linsay
1
Po około 1000 próbach zdałem sobie sprawę, że musisz modalPresentationStyle wcześniejviewDidLoad ustawić . Zrobiłem to w konstruktorze i zadziałało.
bendytree
186

Dla tych, którzy próbują uzyskać to do pracy w iOS 8, „Apple-zatwierdzone” sposobem wyświetlania przejrzystego modalne kontroler widoku jest poprzez ustawienie modalPresentationStyle na obecnym ed kontrolera do UIModalPresentationOverCurrentContext.

Można to zrobić w kodzie lub ustawiając właściwości segue w serii ujęć.

Z dokumentacji UIViewController:

UIModalPresentationOverCurrentContext

Styl prezentacji, w którym treść jest wyświetlana tylko nad treścią kontrolera widoku nadrzędnego. Widoki poniżej prezentowanej treści nie są usuwane z hierarchii widoków po zakończeniu prezentacji. Jeśli więc przedstawiony kontroler widoku nie wypełnia ekranu nieprzezroczystą zawartością, treść podstawowa jest wyświetlana.

Podczas prezentacji kontrolera widoku w oknie popover ten styl prezentacji jest obsługiwany tylko wtedy, gdy stylem przejścia jest UIModalTransitionStyleCoverVertical. Próba użycia innego stylu przejścia powoduje wyjątek. Możesz jednak użyć innych stylów przejścia (z wyjątkiem przejścia z częściowym zawinięciem), jeśli kontroler widoku rodzica nie znajduje się w oknie popover.

Dostępne w iOS 8.0 i nowszych.

https://developer.apple.com/documentation/uikit/uiviewcontroller

Film „Zobacz postępy kontrolera w iOS 8” z WWDC 2014 opisuje to szczegółowo.

Uwaga:

  • Upewnij się, że prezentowany kontroler widoku ma wyraźny kolor tła, aby nie był przezroczysty!
  • Musisz to ustawić przed prezentacją, tj. Ustawienie tego parametru w viewDidLoadprezentowanymViewController nie będzie miało żadnego wpływu
Jeff C.
źródło
32
Uwaga - Wygląda na to, że zmieniono cel, w którym należy ustawić modalPresentationStyle . Na przykład w iOS 7, aby to zadziałało, musiałem ustawić modalPresentationStyle kontrolerów View, które próbowały otworzyć modal na UIModalPresentationCurrentContext . Aby jednak działało to w iOS8, musiałem ustawić modalPresentationStyle widoku modalnego, który będzie wyświetlany na UIModalPresentationOverCurrentContext .
u2Fan
1
Jeśli używasz sekwensów w swoich scenorysach, musisz ustawić tam styl prezentacji. Przynajmniej to działało dla mnie.
Julian B.
Dodałem te trzy wiersze do metody init w prezentowanym kontrolerze widoku i działa jak urok: self.providesPresentationContextTransitionStyle = TAK; self.definesPresentationContext = TAK; [self setModalPresentationStyle: UIModalPresentationOverCurrentContext];
inigo333
2
Na iOS 8+ musiałem zaprezentować modal z UINavigationController, więc prezentowanie od dziecka nie zapewniło mi tego, czego potrzebowałem. Zamiast tego sourceVCjest self.navigationController. Ponadto dopiero po ustawieniu docelowego stylu prezentacji jako niestandardowego mogłem go przejrzeć. [sourceVC setModalPresentationStyle:UIModalPresentationCurrentContext];, [targetVC setModalPresentationStyle:UIModalPresentationCustom];Mam nadzieję , że to komuś pomoże.
devdc
Uwaga - Zaproszenie presentedVC.modalPresentationStyle = UIModalPresentationOverCurrentContextw prezentowaniu VC. Nie działa w prezentowanym PCV. Zaufaj mi, próbowałem.
smileham
104

W systemie iOS 8.0 i nowszym można to zrobić, ustawiając właściwość modalPresentationStyle na UIModalPresentationOverCurrentContext

//Set property **definesPresentationContext** YES to avoid presenting over presenting-viewController's navigation bar

self.definesPresentationContext = YES; //self is presenting view controller
presentedController.view.backgroundColor = [YOUR_COLOR with alpha OR clearColor]
presentedController.modalPresentationStyle = UIModalPresentationOverCurrentContext;

[self presentViewController:presentedController animated:YES completion:nil];

Zobacz załączony obraz

sat20786
źródło
5
To jedyne rozwiązanie, które mogę dostać do pracy. Bardzo proste. Po prostu dodaj to do prezentującego VC przed segregacją modalną.
Siriss,
1
Xcoe 9.2 / iOS 11.2 szybki .customi .overFullScreendziała.
William Hu
I wygląda na to, że jeśli ustawisz .overFullScreenobecny kontroler widoku viewWillAppearnie będzie wywoływany.
William Hu
Jeszcze jedno, presentedController.view.backgroundColor = #color#powinno być napisane w presentedController's viewDidLoad, albo presentedControllerjest życie zostaje przerwane.
DawnSong
44

Ten kod działa poprawnie na telefonie iPhone w systemie iOS6 i iOS7:

presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha'
presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[presentingVC presentViewController:presentedVC animated:YES completion:NULL];

W takim przypadku brakuje Ci animacji wsuwania. Aby zachować animację, nadal możesz użyć następującego „nie-eleganckiego” rozszerzenia:

[presentingVC presentViewController:presentedVC animated:YES completion:^{
    [presentedVC dismissViewControllerAnimated:NO completion:^{
        presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext;
        [presentingVC presentViewController:presentedVC animated:NO completion:NULL];
    }];
}];

Jeśli nasza prezentacjaV znajduje się w UINavigationController lub UITabbarController, musisz współpracować z tymi kontrolerami jako prezentingVC.

Ponadto w iOS7 można zaimplementować niestandardowy UIViewControllerTransitioningDelegateprotokół animacji przejścia . Oczywiście w tym przypadku można uzyskać przezroczyste tło

@interface ModalViewController : UIViewController <UIViewControllerTransitioningDelegate>

Po pierwsze, przed prezentacją musisz ustawić modalPresentationStyle

modalViewController.modalPresentationStyle = UIModalPresentationCustom;

Następnie musisz zaimplementować dwie metody protokołu

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    CustomAnimatedTransitioning *transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = YES;
    return transitioning;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    CustomAnimatedTransitioning * transitioning = [CustomAnimatedTransitioning new];
    transitioning.presenting = NO;
    return transitioning;
}

Ostatnią rzeczą jest zdefiniowanie niestandardowego przejścia w CustomAnimatedTransitioningklasie

@interface CustomAnimatedTransitioning : NSObject <UIViewControllerAnimatedTransitioning>
@property (nonatomic) BOOL presenting;
@end

@implementation CurrentContextTransitionAnimator

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

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext 
{
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    if (self.presenting) {
        // custom presenting animation
    }
    else {
        // custom dismissing animation
    }
}
malex
źródło
7
Potwierdzono, że to działa. UWAGA: jeśli Twój viewController znajduje się w nawigacjiController, upewnij się, że modalPresentationStylejest również ustawiony!
mxcl
Myślę, że w najczęstszych przypadkach dobrze jest traktować kontroler nawigacyjny jako prezentację PVC.
malex
Tak, przy użyciu tego modalPresentationStyle niemożliwe jest uzyskanie animacji prezentacji ((
malex 14.01.2014
2
@alex tak to działa przepraszam: moim błędem było ustawienie modalPresentationStyle na UIModalPresentationCurrentContext dla prezentacjiVC zamiast prenstingVC.
tiguero
5
@mxcl A jeśli widok viewController navigationController sam jest wewnątrz tabBarController, upewnij się, że jego modalPresentationStyle jest również ustawiony;)
Thomas CG de Vilhena
21

Zmagałem się trochę z Konstruktorem interfejsów XCode 7, aby ustawić styl prezentacji zgodnie z sugestią @VenuGopalTewari. W tej wersji wydaje się, że nie ma trybu prezentacji Over Current Contextani Over Full Screentrybu prezentacji. Aby więc działało, ustawiam tryb na Default:

wprowadź opis zdjęcia tutaj z wprowadź opis zdjęcia tutaj

Dodatkowo ustawiam tryb prezentacji kontrolera widoku prezentowanego modalnie na Over Full Screen:

wprowadź opis zdjęcia tutaj

Bastian
źródło
To działało dla mnie, nie potrzebowałem kodu. Używam Xcode 7.2, szybki, a celem jest iOS 8.0
LightMan
To też działało dla mnie. +1 za poprawną odpowiedź. Dzięki :)
Augustine PA
Najlepsza odpowiedź tutaj!
shinyuX
1
Brak kodu = najlepsza odpowiedź. Bastian wygrywa tę grę. Proszę dać +1 tej odpowiedzi.
GeneCode
Ta odpowiedź zadziałała ... spędziłem nad tym godzinę
użytkownik578386
18

Utwórz segment, aby modalnie prezentować i ustaw właściwość prezentacji tego segmentu na ponad bieżący kontekst, będzie działać w 100%

wprowadź opis zdjęcia tutaj

Venu Gopal Tewari
źródło
3
Podziwiam 100% pewników, zadziałało! Kluczem jest zastosowanie go na segue. Dziękuję bardzo
Badr
Jeśli nie masz przypisanego segue do przycisku i wywołujesz go programowo, upewnij się, że ustawiłeś identyfikator i wywołałeś performSegueWithIdentifier zamiast presentViewController
user3344977
1
Próbowałem wszystkich innych odpowiedzi, ale to jedyna, która działała dla mnie w iOS9.
endavid
14

PresentViewController z przezroczystym tłem - w iOS 8 i iOS 9

MYViewController *myVC = [self.storyboard   instantiateViewControllerWithIdentifier:@"MYViewController"];
    myVC.providesPresentationContextTransitionStyle = YES;
    myVC.definesPresentationContext = YES;
    [myVC setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    [self.navigationController presentViewController:myVC animated:YES completion:nil];

A w MYViewController ustaw kolor tła na czarny i zmniejsz krycie

Ashwini Chougale
źródło
12

To trochę hacky sposób, ale dla mnie ten kod działa (iOS 6):

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[self presentViewController:self.signInViewController animated:YES completion:^{
    [self.signInViewController dismissViewControllerAnimated:NO completion:^{
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
        [self presentViewController:self.signInViewController animated:NO completion:nil];
        appDelegate.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen;

    }];
}];

Ten kod działa również na iPhonie

Mak
źródło
Dzięki - właśnie tego potrzebowałem - wyświetlając początkowy ekran „Pomoc” na głównym ekranie głównym. Piękny!
Matt H
1
Dziś spędzam prawie 3 godziny na przeglądaniu i poszukiwaniu rozwiązania, które działa zarówno na iOS7, jak i iOS8. Biorąc pod uwagę fakt, że ta odpowiedź ma 1,5 roku i używam ECSlidingViewController, jest to jedyne działające rozwiązanie! Dzięki @Mak.
Centurion
Idealny. Ponadto, jeśli nie obchodzi Cię animacja, 3 linie w wewnętrznym zakończeniu działają idealnie Dzięki!
RasTheDestroyer
po 3 godzinach spędzonych bez powodzenia znalazłem to, na zdrowie, chciałbym móc zagłosować więcej: D
alessioarsuffi
11

Ta kategoria działała dla mnie (iOS 7, 8 i 9)

Plik H.

@interface UIViewController (navigation)
- (void) presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;
@end

Plik M.

@implementation UIViewController (navigation)
- (void)presentTransparentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion
{
    if(SYSTEM_VERSION_LESS_THAN(@"8.0")) {
        [self presentIOS7TransparentController:viewControllerToPresent withCompletion:completion];

    }else{
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
         [self presentViewController:viewControllerToPresent animated:YES completion:completion];
    }
}
-(void)presentIOS7TransparentController:(UIViewController *)viewControllerToPresent withCompletion:(void(^)(void))completion
{
    UIViewController *presentingVC = self;
    UIViewController *root = self;
    while (root.parentViewController) {
        root = root.parentViewController;
    }
    UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
    root.modalPresentationStyle = UIModalPresentationCurrentContext;
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
        root.modalPresentationStyle = orginalStyle;
    }];
}
@end
Przetrząsać
źródło
1
Sprawdziłem wszystkie odpowiedzi .. ale dla mnie twoja odpowiedź jest idealna. .. „+1” do tego. @Ted
g212gs
1
Myślałem, że nie mogę znaleźć rozwiązania. Wielkie dzięki!
CopperCash,
10

Rozwiązanie tej odpowiedzi przy użyciu szybkiego byłoby następujące.

let vc = MyViewController()
vc.view.backgroundColor = UIColor.clear // or whatever color.
vc.modalPresentationStyle = .overCurrentContext
present(vc, animated: true, completion: nil)
Anthony Dito
źródło
9

Jeśli używasz Storyboard, możesz wykonać ten krok:

  1. Dodaj kontroler widoku (V2), skonfiguruj interfejs użytkownika tak, jak chcesz
  • dodaj UIView - ustaw tło na czarne, a krycie na 0,5
  • dodaj kolejne UIView (2) - które będą służyć jako twoje wyskakujące okienko (Pls weź pod uwagę, że UIView i UIView (2) muszą mieć ten sam poziom / hierarchię. wpływa na UIView (2))
  1. Prezentuj V2 modalnie

  2. Kliknij segue. W Inspektorze atrybutów ustaw opcję Prezentacja na pełny ekran . Usuń animację, jeśli chcesz

Storyboard

  1. Wybierz V2. W Inspektorze atrybutów ustaw opcję Prezentacja na pełny ekran . Zaznacz Definiuje kontekst i zapewnia kontekst

Storyboard

  1. Wybierz MainView swojego V2 (Pls. Sprawdź obraz). Ustaw kolor tła na Wyczyść kolor

Storyboard

dhin
źródło
6

Dodałem te trzy linie do metody init w prezentowanym kontrolerze widoku i działa jak urok:

self.providesPresentationContextTransitionStyle = YES;
self.definesPresentationContext = YES;
[self setModalPresentationStyle:UIModalPresentationOverCurrentContext];

EDYCJA (działa na iOS 9.3):

self.modalPresentationStyle = UIModalPresentationOverFullScreen;

Zgodnie z dokumentacją:

UIModalPresentationOverFullScreen Styl prezentacji widoku, w którym prezentowany widok obejmuje ekran. Widoki poniżej prezentowanej treści nie są usuwane z hierarchii widoków po zakończeniu prezentacji. Jeśli więc przedstawiony kontroler widoku nie wypełnia ekranu nieprzezroczystą zawartością, treść podstawowa jest wyświetlana.

Dostępne w iOS 8.0 i nowszych.

inigo333
źródło
1
Praca na iOS 10.2.
Josef Rysanek
4

Alternatywnym sposobem jest użycie „widoku kontenera”. Po prostu zrób alfa poniżej 1 i umieść w nim seque. XCode 5, docelowy iOS7. Testowane na iPhonie.

wprowadź opis zdjęcia tutaj

Widok kontenera dostępny z iOS6. Link do postu na blogu na ten temat.

Mike Glukhov
źródło
3

Stworzyłem obiekt do obsługi prezentacji tego, co nazywam „nałożonym modalem”, co oznacza, że ​​zachowuje widok tła i pozwala mieć modal z przezroczystym tłem.

Ma jedną, prostą metodę, która robi to:

- (void)presentViewController:(UIViewController *)presentedViewController
       fromViewController:(UIViewController *)presentingViewController
{
    presentedViewController.modalPresentationStyle = UIModalPresentationCustom;
    presentedViewController.transitioningDelegate = self;
    presentedViewController.modalPresentationCapturesStatusBarAppearance = YES;

    [presentedViewController setNeedsStatusBarAppearanceUpdate];

    [presentingViewController presentViewController:presentedViewController
                                       animated:YES
                                     completion:nil];
}

Ważne jest, aby ustawić modalPresentationCapturesStatusBarAppearancewłaściwość YESi wymusić aktualizację wyglądu paska stanu, jeśli prezentowany kontroler widoku ma innypreferredStatusBarStyle .

Ten obiekt powinien mieć @property (assign, nonatommic) isPresenting

Chcesz ten przedmiot do wykonania do UIViewControllerAnimatedTransitioningi UIViewControllerTransitioningDelegateprotokołów i wdrożyć następujące metody:

- (id)animationControllerForPresentedController:(UIViewController *)presented
                           presentingController:(UIViewController *)presenting
                               sourceController:(UIViewController *)source
{
    self.isPresenting = YES;

    return self;
}

- (id)animationControllerForDismissedController:(UIViewController *)dismissed
{
    self.isPresenting = NO;

    return self;
}

i:

- (NSTimeInterval)transitionDuration:(id)transitionContext
{
    return 0.25;
}

- (void)animateTransition:(id)transitionContext
{
    UIViewController* firstVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController* secondVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView* containerView = [transitionContext containerView];
    UIView* firstView = firstVC.view;
    UIView* secondView = secondVC.view;

    if (self.isPresenting) {
        [containerView addSubview:secondView];
        secondView.frame = (CGRect){
            containerView.frame.origin.x,
            containerView.frame.origin.y + containerView.frame.size.height,
            containerView.frame.size
        };

        firstView.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        [UIView animateWithDuration:0.25 animations:^{
            secondView.frame = containerView.frame;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
        } else {
        [UIView animateWithDuration:0.25 animations:^{
            firstView.frame = (CGRect){
                containerView.frame.origin.x,
                containerView.frame.origin.y + containerView.frame.size.height,
                containerView.frame.size
        };

        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
}

Robi to animację wsuwania z dołu naśladującą domyślną animację modalną, ale możesz zrobić to, co chcesz.

Ważne jest to, że widok kontrolera widoku prezentującego pozostanie z tyłu, umożliwiając stworzenie przezroczystego efektu.

To rozwiązanie działa na iOS 7+

Pedro Mancheno
źródło
Dziękuję za odpowiedź.
Salman Khakwani
3

Bardzo prostym sposobem na zrobienie tego ( Storyboardsna przykład za pomocą ) jest:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"SomeStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"SomeStoryboardViewController"];
// the key for what you're looking to do:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.view.alpha = 0.50f;

[self presentViewController:vc animated:YES completion:^{
    // great success
}];

Pozwoli to przedstawić UIViewControllerw Storyboardmodally, ale z półprzezroczystym tle.

JaredH
źródło
3

Działa na iOS 7-10

if #available(iOS 8.0, *) {
    nextVC.modalPresentationStyle = .OverCurrentContext
    self.presentViewController(nextVC, animated: true, completion: nil)
} else {
    // Fallback on earlier version
    self.modalPresentationStyle = .Custom          
    nextVC.modalTransitionStyle = .CrossDissolve            
    self.presentViewController(nextVC, animated: false, completion: nil)
    }
}
iluvatar_GR
źródło
2

Aby podsumować wszystkie dobre odpowiedzi i komentarze tutaj i nadal mieć animację podczas przechodzenia do nowej, ViewControlleroto co zrobiłem: (Obsługuje iOS 6 i nowsze wersje)

Jeśli używasz UINavigationController\, UITabBarControllerjest to właściwy sposób:

    SomeViewController *vcThatWillBeDisplayed = [self.storyboard instantiateViewControllerWithIdentifier:@"SomeVC"];

    vcThatWillBeDisplayed.view.backgroundColor = [UIColor colorWithRed: 255/255.0 green:255/255.0 blue:255/255.0 alpha:0.50];    

    self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext;
    [self presentViewController:presentedVC animated:YES completion:NULL];

Jeśli to zrobisz, stracisz modalTransitionStyleanimację. Aby go rozwiązać, możesz łatwo dodać do swojej SomeViewControllerklasy:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIView animateWithDuration:0.4 animations:^() {self.view.alpha = 1;}
       completion:^(BOOL finished){}];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.alpha = 0;
}
Segev
źródło
2

Oczywiście powinieneś ustawić UIModalPresentationCurrentContext, ale miejsce ustawienia clearColor jest również bardzo ważne! Nie można ustawić tła w funkcji viewDidLoad, ustawić go przed załadowaniem widoku, tak jak w kontrolerze widoku głównego lub w funkcji init kontrolera, który ma się pojawić!

actionController.view.backgroundColor = [UIColor clearColor];
[self presentViewController:actionController animated:YES completion:nil];

lub

- (instancetype)init {

    self = [super initWithNibName:nil bundle:nil];

    if(self) {
        self.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self.view setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}
Santiago
źródło
To była wskazówka, która pomogła mi wśród wszystkich innych. Dzięki za pomoc.
Tomasz Nazarenko
1

Jeśli używasz modalnego segue, ustaw go jako ten obraz (możesz wyłączyć animację, jeśli chcesz)wprowadź opis zdjęcia tutaj

Ahmed
źródło
1

Kompletna metoda przetestowana na iOS 7 i iOS 8.

@interface UIViewController (MBOverCurrentContextModalPresenting)

/// @warning Some method of viewControllerToPresent will called twice before iOS 8, e.g. viewWillAppear:.
- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion;

@end

@implementation UIViewController (MBOverCurrentContextModalPresenting)

- (void)MBOverCurrentContextPresentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
    UIViewController *presentingVC = self;

    // iOS 8 before
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
        UIViewController *root = presentingVC;
        while (root.parentViewController) {
            root = root.parentViewController;
        }

        [presentingVC presentViewController:viewControllerToPresent animated:YES completion:^{
            [viewControllerToPresent dismissViewControllerAnimated:NO completion:^{
                UIModalPresentationStyle orginalStyle = root.modalPresentationStyle;
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = UIModalPresentationCurrentContext;
                }
                [presentingVC presentViewController:viewControllerToPresent animated:NO completion:completion];
                if (orginalStyle != UIModalPresentationCurrentContext) {
                    root.modalPresentationStyle = orginalStyle;
                }
            }];
        }];
        return;
    }

    UIModalPresentationStyle orginalStyle = viewControllerToPresent.modalPresentationStyle;
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext;
    }
    [presentingVC presentViewController:viewControllerToPresent animated:YES completion:completion];
    if (orginalStyle != UIModalPresentationOverCurrentContext) {
        viewControllerToPresent.modalPresentationStyle = orginalStyle;
    }
}

@end
BB9z
źródło
1

Szybki 4.2

guard let someVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "someVC") as? someVC else {
    return
}
someVC.modalPresentationStyle = .overCurrentContext

present(someVC, animated: true, completion: nil)
Aleksiej Szewczenko
źródło
0

w appdelegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [[_window rootViewController]setModalPresentationStyle:UIModalPresentationCurrentContext];
    return YES;
}

w pierwszym widoku kontrolera, z którego należy załadować następny widok:

  NextViewController *customvc = [[NextViewController alloc]init];
    [self presentViewController:customvc animated:YES completion:^{

    }];

w twoim nextViewController, który należy dodać przezroczysty:

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor clearColor];
    UIView* backView = [[UIView alloc] initWithFrame:self.view.frame];
    backView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
    [self.view insertSubview:backView atIndex:0];
}
Zaraki
źródło
0

Ekran logowania jest modalny, co oznacza, że ​​znajduje się na poprzednim ekranie. Do tej pory mamy rozmazane tło, ale nic nie zamazuje; to tylko szare tło.

Musimy poprawnie ustawić nasz Modal.

docelowy link do obrazu

  • Najpierw musimy zmienić tło widoku kontrolera widoku na Wyczyść kolor. Oznacza to po prostu, że powinien być przejrzysty. Domyślnie ten widok jest biały.

  • Po drugie, musimy wybrać Segment, który prowadzi do ekranu logowania, a następnie w Inspektorze atrybutów ustawić Prezentację na Ponad bieżący kontekst. Ta opcja jest dostępna tylko z włączonym automatycznym układem i klasami wielkości.

docelowy link do obrazu

tinkl
źródło
0

Ustaw nawigację modalPresentationStylenaUIModalPresentationCustom

i ustaw kolor tła kontrolera widoku jako przezroczysty.


źródło