Zeigen Sie clearColor UIViewController über UIViewController an

150

Ich habe eine UIViewControllerAnsicht als Unteransicht / Modal über einer anderen UIViewControllerAnsicht, z. B. dass die Unteransicht / das Modal transparent sein sollte und alle Komponenten, die der Unteransicht hinzugefügt werden, sichtbar sein sollten. Das Problem ist, dass ich habe, dass die Unteransicht schwarzen Hintergrund zeigt, um clearColor zu haben. Ich versuche UIViewals clearColor nicht schwarzen Hintergrund zu machen. Weiß jemand, was daran falsch ist? Jeder Vorschlag geschätzt.

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];
}

BEHOBEN : Ich habe die Probleme behoben. Es funktioniert so gut für iPhone und iPad. Modal View Controller ohne schwarzen Hintergrund, nur clearColor / transparent. Das einzige , was ich ändern muß , ist I ersetzt UIModalPresentationFullScreenzu UIModalPresentationCurrentContext. Wie einfach ist das!

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];

HINWEIS: Wenn Sie eine modalPresentationStyleEigenschaft von verwenden 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];

HINWEIS: Die schlechte Nachricht ist, dass die oben genannte Lösung unter iOS 7 nicht funktioniert. Die gute Nachricht ist, dass ich das Problem für iOS7 behoben habe! Ich habe jemanden um Hilfe gebeten und hier ist, was er sagte:

Wenn ein Ansichts-Controller modal dargestellt wird, entfernt iOS die darunter liegenden Ansichts-Controller für die Dauer der Darstellung aus der Ansichtshierarchie. Während die Ansicht Ihres modal dargestellten Ansichts-Controllers transparent ist, befindet sich nichts darunter außer dem schwarzen App-Fenster. iOS 7 führte einen neuen modalen Präsentationsstil ein UIModalPresentationCustom, der bewirkt, dass iOS die Ansichten unter dem Controller für präsentierte Ansichten nicht entfernt. Um diesen modalen Präsentationsstil verwenden zu können, müssen Sie jedoch Ihren eigenen Übergangsdelegierten bereitstellen, um die Präsentation zu verwalten und Animationen zu schließen. Dies wird im Vortrag "Benutzerdefinierte Übergänge mit View Controllern" von WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 beschrieben, in dem auch erläutert wird, wie Sie Ihren eigenen Übergangsdelegierten implementieren.

Möglicherweise sehen Sie meine Lösung für das oben genannte Problem in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

Hightech
quelle
1
Stellen Sie sicher, dass Sie den modalPresentationStyle des rootViewController festlegen, sonst funktioniert es nicht
Thorsten
Bitte werfen Sie einen Blick auf den Kommentar zu dieser Antwort stackoverflow.com/a/25990081/1418457 , es funktioniert
onmyway133
Dieser stackoverflow.com/q/27598846/1603234 bringt mich zum Lächeln, jetzt bist du dran :)
Hemang
Ich musste self.modalPresentationStyle = UIModalPresentationCurrentContext machen; mit dem präsentierten View Controller, damit es funktioniert, nicht mit dem präsentierenden.
Tulleb
1
Überprüfen Sie Brodys Antwort unten. modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext; wird das Problem lösen,
GoodSp33d

Antworten:

143

iOS8 +

In iOS8 + können Sie jetzt den neuen modalPresentationStyle UIModalPresentationOverCurrentContext verwenden, um einen Ansichtscontroller mit transparentem Hintergrund darzustellen:

MyModalViewController *modalViewController = [[MyModalViewController alloc] init];
modalViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;           
[self presentViewController:modalViewController animated:YES completion:nil];    
Brody Robertson
quelle
5
Sollte die akzeptierte Antwort sein. Die zuvor akzeptierte Antwort ist aus älteren Gründen weiterhin gültig, dies ist jedoch die empfohlene Methode.
Tomasz Bąk
3
Wenn Sie nur für iOS 8 entwickeln, gehen Sie mit dieser Antwort! Es funktioniert
Mário Carvalho
2
Das ist gut, aber sollte nicht die letzte Zeile sein [self presentViewController:modalViewController animated:YES completion:nil];? (anstelle von targetController)?
SuperDuperTango
3
Um dies für mich zu arbeiten, habe ich modalViewController.view.backgroundColor = UIColor.clearColor () hinzugefügt. Danke für die Lösung
Pramod
kann mir jemand auch den Code für den Pushviewcontroller geben (ich meine für den Navigationscontroller).
Alok
140

BEHOBEN : Ich habe die Probleme behoben. Es funktioniert so gut für iPhone und iPad. Modal View Controller ohne schwarzen Hintergrund, nur clearColor / transparent. Das einzige, was ich ändern muss, ist, dass ich UIModalPresentationFullScreen durch UIModalPresentationCurrentContext ersetzt habe. Wie einfach ist das!

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];

HINWEIS: Wenn Sie eine modalPresentationStyle-Eigenschaft von navigationController verwenden:

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];

HINWEIS: Die schlechte Nachricht ist, dass die oben genannte Lösung unter iOS 7 nicht funktioniert. Die gute Nachricht ist, dass ich das Problem für iOS7 behoben habe! Ich habe jemanden um Hilfe gebeten und hier ist, was er sagte:

Wenn ein Ansichts-Controller modal dargestellt wird, entfernt iOS die darunter liegenden Ansichts-Controller für die Dauer der Darstellung aus der Ansichtshierarchie. Während die Ansicht Ihres modal dargestellten Ansichts-Controllers transparent ist, befindet sich nichts darunter außer dem schwarzen App-Fenster. iOS 7 führte mit UIModalPresentationCustom einen neuen modalen Präsentationsstil ein, der bewirkt, dass iOS die Ansichten unter dem präsentierten Ansichts-Controller nicht entfernt. Um diesen modalen Präsentationsstil verwenden zu können, müssen Sie jedoch Ihren eigenen Übergangsdelegierten bereitstellen, um die Präsentation zu verwalten und Animationen zu schließen. Dies wird im Vortrag "Benutzerdefinierte Übergänge mit View Controllern" von WWDC 2013 https://developer.apple.com/wwdc/videos/?id=218 beschrieben, in dem auch erläutert wird, wie Sie Ihren eigenen Übergangsdelegierten implementieren.

Möglicherweise sehen Sie meine Lösung für das oben genannte Problem in iOS7: https://github.com/hightech/iOS-7-Custom-ModalViewController-Transitions

Hightech
quelle
1
self.modalPresentationStyle = UIModalPresentationCurrentContext;geschafft.
Adriano Lucas
4
Übrigens habe ich beobachtet, dass wegen self.modalPresentationStyle = UIModalPresentationCurrentContext; es präsentiert modalViewController keine Animation .. irgendwelche Ideen?
Devarshi
1
@Miraaj Setzen Sie dann modalPresentationStyle zurück auf UIModalPresentationFullScreen, bevor Sie zeigen, dass UIViewController funktionieren sollteself.modalPresentationStyle = UIModalPresentationFullScreen; [self performSegueWithIdentifier:@"CustomSegue" sender:self];
Hightech
1
Wenn Sie dies in iOS 6 und 7 ausführen, ist der neue Ansichts-Controller beim Animieren der Präsentation klar, aber sobald er vorhanden ist, wird der Hintergrund schwarz. Es wird wieder klar, wenn die Entlassung animiert wird. Hat jemand anderes dieses Problem gehabt?
Drew C
3
@pkamb Ich habe die Lösung für iOS 7 aktualisiert. stackoverflow.com/a/11252969/1344459 Ich hoffe, das hilft Ihnen.
Hightech
114

Für rein visuelle Denker und Storyboard-Fans gibt es also folgende Möglichkeiten:

1. Präsentieren des View Controllers

Kontext definieren

2. Präsentierter View Controller

Präsentation: Über den aktuellen Kontext

Pasevin
quelle
Dies sollte die akzeptierte Antwort sein. Dies ist alles, was Sie tun müssen, damit dies funktioniert. Stellen Sie dann die Hintergrundfarbe der Ansicht auf dem Modal Controller auf Löschen ein.
Jesse
In diesem Fall überschreiben vereinbarte Storyboard-Optionen den Code.
C0D3
17
Diese Antwort ist so süß, ich habe jetzt Diabetes.
GeneCode
25

Swift 3 & iOS10 Lösung:

//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)
Kevin ABRIOUX
quelle
16

Dies ist aus xCode 7 Beta 4 unter Verwendung eines Steuer-Drag-Segues. Stellen Sie einfach den Hintergrund Ihres Ziels ein, um ihn zu löschen, und legen Sie die Segue-Eigenschaften in IB wie folgt fest (nb. Die Präsentation kann auch "Über Vollbild" sein):

Geben Sie hier die Bildbeschreibung ein

smileBot
quelle
2
DANKE. Ich habe Ihren Segue Fix + die ViewControllers Antwort von @pasevin gemacht und es hat funktioniert !!
CSawy
1
Dies beantwortete meine Frage. Vielen Dank. Haben Sie eine Abstimmung: D
Nate4436271
8

Ich fand, dass der einfachste Weg, es unter iOS7 und iOS8 zum Laufen zu bringen, darin besteht, den Präsentationsstil auf dem modallyPresentedVC (ViewController, den Sie modal präsentieren möchten) aufgrund von iOS8 auf UIModalPresentationOverCurrentContext zu setzen:

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

und UIModalPresentationCurrentContext zum Präsentieren von VC (dem Controller, der das modallyPresented präsentiert) aufgrund von iOS7:

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

Weil die Dinge unter iOS7 und iOS8 anders gehandhabt werden. Natürlich müssen Sie die Eigenschaften von navigationController nicht festlegen, wenn Sie keine verwenden. Hoffentlich hilft das.

3vangelos
quelle
hat meinen Speck gerettet! Danke
Ente
5

Swift2-Version:

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)
Mojtabye
quelle
4

Ein anderer Weg (keine Notwendigkeit, einen benutzerdefinierten Übergang zu erstellen und funktioniert unter iOS 7)

Verwenden von Storyboard:

Erstellen Sie den untergeordneten Ansichts-Controller mit der Größe "Freiheit", setzen Sie die Ansichtsbreite beispielsweise auf 500 x 500 und fügen Sie die nächste Methode hinzu:

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

Erstellen Sie dann einen Modal Segue mit Form Sheet und testen Sie ihn.

EducaPix
quelle
Du bist unglaublich !!! das funktioniert tatsächlich !!! (Das Einstellen der "Freiheit" -Größe in IB hat keinen Einfluss auf eine bestimmte Cose, es ist eine simulierte Metrik, aber es funktioniert trotzdem !!!) und es ist so einfach !!!
Radu Simionescu
4

iOS 7-Lösung mit benutzerdefiniertem Übergang:

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

Lösung basierend auf Hightech-Code.

Max Gribov
quelle
Wenn ich das von [self entlassenViewControllerAnimated: YES Vervollständigung: NULL] entlasse; Ich bekomme eine Ausnahme?
Asadullah Ali
Ja für diesen Code. Oder Sie müssen die Methode animationControllerForDismissedController implementieren, damit die Animation mit der Arbeit beginnt.
Max Gribov
4

Für mich funktioniert das:

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];

MMPushNotificationViewControllerist der Transparent View Controller und ich habe auch die MMPushNotificationViewControllerAnsichtsfarbe als Klarfarbe gemacht. Jetzt alles was ich getan und meinen Transparentviewcontroller gemacht habe.

Manab Kumar Mal
quelle
2

Für iOS7

Es gibt jetzt eine Möglichkeit, dies mithilfe der benutzerdefinierten iOS7-Übergänge zu erreichen:

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

Um Ihren benutzerdefinierten Übergang zu erstellen, benötigen Sie zwei Dinge:

  • Ein TransitionDelegate-Objekt (Implementierung <UIViewControllerTransitionDelegate>)
  • Ein "AnimatedTransitioning" -Objekt (Implementierung <UIViewControllerAnimatedTransitioning>)

Weitere Informationen zu benutzerdefinierten Übergängen finden Sie in diesem Lernprogramm .

Kirualex
quelle
Gibt es spezielle Gründe, warum Sie der Animator-Klasse den Mainviewcontroller und den Second View Controller hinzugefügt haben? Warum haben Sie UIViewController * toVC = (UIViewController *) nicht direkt verwendet? [TransitionContext viewControllerForKey: UITransitionContextToViewControllerKey]; UIViewController * fromVC = (UIViewController *) [TransitionContext viewControllerForKey: UITransitionContextFromViewControllerKey];
Satyam Raikar
Es ist nicht mein Tutorial, daher kenne ich die Vor- und Nachteile nicht. Ihr Punkt scheint jedoch gültig zu sein.
Kirualex
2

Funktioniert hervorragend unter iOS7 und 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];
Hoppus
quelle
Ein Duplikat der zweitbesten Antwort.
Tomasz Bąk
2

Sie können das Fenster auch erneut zur Ansicht hinzufügen.

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];

Auf diese Weise kann die Präsentation animiert werden.

Elfenbecher
quelle
1

Für iOS 7 und nur mit Interface Builder kann dies erreicht werden, indem die Präsentation auf allen an der modalen Präsentation beteiligten View-Controllern auf "Over Current Context" gesetzt wird. Auch für Navigationssteuerungen.

Stellen Sie es beispielsweise auf allen diesen Ansichts-Controllern ein:

NavController -> RootViewController -> ModalViewController

Geben Sie hier die Bildbeschreibung ein

David Hernandez
quelle
0

Ich habe nicht viel mit dem Storyboard / Interface Builder herumgespielt, aber was mir auffällt, ist, dass Sie der Ansicht sagen, dass sie klar gefärbt ist (dh 100% Alpha / Durchsichtig) und dass sie auch undurchsichtig ist ( 0% Alpha - vollständig fest). Diese beiden Dinge scheinen nicht ineinander zu greifen. Ich würde die self.view.opaque = YES;Zeile auskommentieren und sehen, ob es dann funktioniert;)

Ah, etwas anderes, an das ich gerade gedacht habe - es ist durchaus möglich, dass Ihr View Controller den Alpha-Hintergrund hat, aber natürlich wird das Alpha bis zur Farbe des Basisfensters oder des Root View Controllers des Programms durchscheinen, das von ist Standard schwarz. Die Grundschicht Ihrer gesamten App kann keinen transparenten Hintergrund haben - transparent für was? Was steckt dahinter? Es muss etwas geben, um durch die Transparenz zu sehen. Ist das sinnvoll?

WendiKidd
quelle
Ich habe versucht, self.view.opaque = YES zu kommentieren. Linie und es funktioniert nicht. :-(
Hightech
Hast du den zweiten Teil meiner Antwort gelesen? Abhängig von Ihrem Setup können Sie möglicherweise nicht das tun, was Sie möchten. Was platzieren Sie hinter dem clearColor VC? Vielleicht können wir das klären ^^
WendiKidd
-3

Verwenden Sie einfach "self.modalPresentationStyle = UIModalPresentationCurrentContext;", um die Ansicht zu präsentieren

Wird gut funktionieren :)

Venkateswarlu.NP
quelle
1
Dies wiederholt nur das, was die vorhandenen Antworten bereits gesagt haben.
Pang