Wyświetlam widok modalny z
[self presentModalViewController:controller animated:YES];
Kiedy widok przesuwa się w górę ekranu, jest przezroczysty zgodnie z ustawieniem w pliku xib, z którego jest tworzony, ale po wypełnieniu ekranu staje się nieprzezroczysty.
Czy w ogóle można zachować przejrzystość widoku?
Podejrzewam, że widok, nad którym jest umieszczany, nie jest renderowany, a nie, że widok modalny staje się nieprzejrzysty.
ios
iphone
uiviewcontroller
Darryl Braaten
źródło
źródło
viewcontroller.modalPresentationStyle = .FormSheet
Odpowiedzi:
Twój widok jest nadal przezroczysty, ale gdy kontroler modalny znajduje się na szczycie stosu, widok za nim jest ukryty (tak jak w przypadku każdego kontrolera widoku znajdującego się najwyżej). Rozwiązaniem jest samodzielne ręczne animowanie widoku; wtedy behind-viewController nie będzie ukryty (ponieważ nie zostawisz go).
źródło
Po iOS 3.2 istnieje metoda, która pozwala to zrobić bez żadnych „sztuczek” - zobacz dokumentację dotyczącą właściwości modalPresentationStyle . Masz rootViewController, który przedstawi ViewController. Oto kod do sukcesu:
viewController.view.backgroundColor = [UIColor clearColor]; rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; [rootViewController presentModalViewController:viewController animated:YES];
Dzięki tej metodzie tło viewControllera będzie przezroczyste, a bazowy rootViewController będzie widoczny. Należy pamiętać, że wydaje się, że działa to tylko na iPadzie, patrz komentarze poniżej.
źródło
Over Current Context
jako stylu prezentacji.Co potrzebowałem, aby to zadziałało:
self.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
źródło
modalPresentationStyle
na kontrolerze widoku prezentacji (zamiast na oknierootViewController
).Dla tych, którzy chcą zobaczyć kod, oto co dodałem do kontrolera mojego przezroczystego widoku:
// Add this view to superview, and slide it in from the bottom - (void)presentWithSuperview:(UIView *)superview { // Set initial location at bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, superview.bounds.size.height); self.view.frame = frame; [superview addSubview:self.view]; // Animate to new location [UIView beginAnimations:@"presentWithSuperview" context:nil]; frame.origin = CGPointZero; self.view.frame = frame; [UIView commitAnimations]; } // Method called when removeFromSuperviewWithAnimation's animation completes - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { if ([animationID isEqualToString:@"removeFromSuperviewWithAnimation"]) { [self.view removeFromSuperview]; } } // Slide this view to bottom of superview, then remove from superview - (void)removeFromSuperviewWithAnimation { [UIView beginAnimations:@"removeFromSuperviewWithAnimation" context:nil]; // Set delegate and selector to remove from superview when animation completes [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; // Move this view to bottom of superview CGRect frame = self.view.frame; frame.origin = CGPointMake(0.0, self.view.superview.bounds.size.height); self.view.frame = frame; [UIView commitAnimations]; }
źródło
Zatwierdzonym przez Apple sposobem na zrobienie tego w systemie iOS 8 jest ustawienie modalPresentationStyle na „UIModalPresentationOverCurrentContext”.
Z dokumentacji UIViewController:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/
Film „Zobacz postępy kontrolera w iOS 8” z WWDC 2014 omawia to bardziej szczegółowo.
Upewnij się, że kontroler prezentowanego widoku ma wyraźny kolor tła (w przeciwnym razie nadal będzie on nieprzezroczysty).
źródło
Jest jeszcze jedna opcja: przed pokazaniem kontrolera modalnego zrób zrzut ekranu całego okna. Wstaw przechwycony obraz do UIImageView i dodaj widok obrazu do widoku kontrolera, który chcesz pokazać. Następnie odeślij do tyłu. Wstaw inny widok nad widokiem obrazu (czarne tło, alfa 0,7). Pokaż swój kontroler modalny i wygląda na to, że był przezroczysty. Właśnie wypróbowałem to na iPhonie 4 z systemem iOS 4.3.1. Jak urok.
źródło
to jest dość stare, ale rozwiązałem ten sam problem w następujący sposób: ponieważ muszę zaprezentować kontroler nawigacyjny w iPhonie, dodanie widoku podrzędnego nie było opłacalnym rozwiązaniem.
Więc co zrobiłem:
1) Przed zaprezentowaniem kontrolera widoku zrób zrzut ekranu bieżącego ekranu:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, self.view.opaque, 0.0); [self.view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * backgroundImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext();
2) Utwórz kontroler widoku, który chcesz zaprezentować, i dodaj tło jako widok podrzędny, wysyłając je z powrotem.
UIViewController * presentingVC = [UIViewController new]; UIImageView * backgroundImageOfPreviousScreen = [[UIImageView alloc] initWithImage:backgroundImage]; [presentingVC.view addSubview:backgroundImageOfPreviousScreen]; [presentingVC.view sendSubviewToBack:backgroundImageOfPreviousScreen];
3) Przedstaw swój kontroler widoku, ale przed tym w nowym kontrolerze widoku dodaj przezroczysty widok w viewDidLoad (użyłem ILTranslucentView)
-(void)viewDidLoad { [super viewDidLoad]; ILTranslucentView * translucentView = [[ILTranslucentView alloc] initWithFrame:self.view.frame]; [self.view addSubview:translucentView]; [self.view sendSubviewToBack:translucentView]; }
I to wszystko!
źródło
Spisałem swoje ustalenia na ten temat w innym pytaniu , ale sedno jest takie, że musisz wywołać
modalPresentationStyle = UIModalPresentationCurrentContext
wszystko, co w tej chwili posiada pełny ekran. W większości przypadków jest to coś, czym jest rootViewController [UIApplication sharedApplication] .delegate.window. Może to być również nowy kontroler UIViewController, który został przedstawionymodalPresentationStyle = UIModalPresentationFullScreen
.Przeczytaj mój inny, znacznie bardziej szczegółowy post, jeśli zastanawiasz się, jak konkretnie rozwiązałem ten problem. Powodzenia!
źródło
Wygląda na to, że jest zepsuty w IOS 8, używam kontrolera nawigacyjnego, a kontekst, który jest wyświetlany, to kontekst menu nawigacji, który w naszym przypadku jest przesuwanym kontrolerem menu.
Używamy pod 'TWTSideMenuViewController', '0.3' nie sprawdziliśmy, czy jest to problem z biblioteką, czy z metodą opisaną powyżej.
źródło
To zadziałało w iOS 8-9:
1- Ustaw tło kontrolera widoku za pomocą alfy
2- Dodaj ten kod:
TranslucentViewController *tvc = [[TranslucentViewController alloc] init]; self.providesPresentationContextTransitionStyle = YES; self.definesPresentationContext = YES; [tvc setModalPresentationStyle:UIModalPresentationOverCurrentContext]; [self.navigationController presentViewController:tvc animated:YES completion:nil];
źródło
Wiem, że to dość stare pytanie. Utknąłem w tej kwestii i udało mi się uzyskać trop z tego wątku. Więc umieszczając tutaj jak to zrobiłem, zadziałało :). Używam storyboardu i mam przejście do ViewController, który ma zostać przedstawiony. Kontroler widoku ma przezroczysty kolor tła. Teraz w inspektorze atrybutów ścieżki ustawiłem prezentację na „Over current context”. I to zadziałało. Tworzę dla iPhone'a.
źródło
Stworzyłem otwartą bibliotekę MZFormSheetController w celu zaprezentowania modalnego arkusza formularza na dodatkowym UIWindow. Możesz go użyć do prezentacji kontrolera widoku przezroczystości, a nawet dostosować rozmiar kontrolera prezentowanego widoku.
źródło
W moim stanie mam widok na ten sam viewController. Stwórz więc nowy kontroler widoku do przechowywania UIView. Uczyń ten widok przezroczystym, ustawiając jego właściwość alfa. Następnie jednym kliknięciem napisałem ten kod. Wygląda dobrze.
UIGraphicsBeginImageContext(objAppDelegate.window.frame.size); [objAppDelegate.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); UIViewController *controllerForBlackTransparentView=[[[UIViewController alloc] init] autorelease]; [controllerForBlackTransparentView setView:viewForProfanity]; UIImageView *imageForBackgroundView=[[UIImageView alloc] initWithFrame:CGRectMake(0, -20, 320, 480)]; [imageForBackgroundView setImage:viewImage]; [viewForProfanity insertSubview:imageForBackgroundView atIndex:0]; [self.navigationController presentModalViewController:controllerForBlackTransparentView animated:YES];
I pokazuje, czego chcę. mam nadzieję, że to komuś pomoże.
źródło
Oto kategoria, którą utworzyłem, która rozwiąże problem.
// // UIViewController+Alerts.h // #import <UIKit/UIKit.h> @interface UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated; - (void)dismissAlertViewControllerAnimated:(BOOL)animated; @end // // UIViewController+Alerts.m // #import "UIViewController+Alerts.h" @implementation UIViewController (Alerts) - (void)presentAlertViewController:(UIViewController *)alertViewController animated:(BOOL)animated { // Setup frame of alert view we're about to display to just off the bottom of the view [alertViewController.view setFrame:CGRectMake(0, self.view.frame.size.height, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; // Tag this view so we can find it again later to dismiss alertViewController.view.tag = 253; // Add new view to our view stack [self.view addSubview:alertViewController.view]; // animate into position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertViewController.view setFrame:CGRectMake(0, (self.view.frame.size.height - alertViewController.view.frame.size.height) / 2, alertViewController.view.frame.size.width, alertViewController.view.frame.size.height)]; }]; } - (void)dismissAlertViewControllerAnimated:(BOOL)animated { UIView *alertView = nil; // find our tagged view for (UIView *tempView in self.view.subviews) { if (tempView.tag == 253) { alertView = tempView; break; } } if (alertView) { // clear tag alertView.tag = 0; // animate out of position [UIView animateWithDuration:(animated ? 0.5 : 0.0) animations:^{ [alertView setFrame:CGRectMake(0, self.view.frame.size.height, alertView.frame.size.width, alertView.frame.size.height)]; }]; } } @end
źródło
Po wielu badaniach wygląda na to, że rozwiąże to nasz problem i spełni nasz cel.
utwórz wypływ ze źródłowego VC do docelowego VC z identyfikatorem.
na przykład „goToDestinationViewController” w porządku, aby ułatwić życie, rozważmy bieżący kontroler widoku, tj. ten, który chcesz za przezroczystym widokiem jako źródło i miejsce docelowe jako miejsce docelowe
Teraz w źródłowym VC w viewDidLoad: lub view
performSegueWithIdentifier("goToDestinationViewController", sender: nil)
dobrze, że jesteśmy w połowie. Teraz przejdź do swojego storyboardu. Kliknij ścieżkę. który powinien wyglądać tak: segue
zmień opcje na pokazane.
Teraz jest prawdziwe rozwiązanie.
w widoku docelowym kontrolera viewDidLoad dodaj ten kod.
self.modalPresentationStyle = .Custom
.................................................. .......................TAK PROSTE......................... .........................................
źródło
self.modalPresentationStyle = .custom
działa dla mnie modalnie prezentując rzeczywisty kontroler widoku z przezroczystym tłem w Swift 3, Xcode 8. Jedynym problemem jest to, że jeśli kontroler widoku prezentacji jest osadzony w kontrolerze paska zakładek, pasek zakładek pojawia się przed przezroczystym widok tła.tabBarController.tabBar.isHidden
powinien być ustawiony natrue
.Alternatywnym sposobem jest użycie „widoku kontenera”. Wystarczy zrobić alfa poniżej 1 i osadzić za pomocą seque. XCode 5, docelowo iOS7.
nie można pokazać obrazu, za mało reputacji)))
Widok kontenera dostępny od iOS6.
źródło
Ten kod działa dobrze na iPhonie pod iOS6 i iOS7:
presentedVC.view.backgroundColor = YOUR_COLOR; // can be with 'alpha' presentingVC.modalPresentationStyle = UIModalPresentationCurrentContext; [presentingVC presentViewController:presentedVC animated:YES completion:NULL];
Ale w ten sposób tracisz animację „przesuwania od dołu”.
źródło
Znalazłem to eleganckie i proste rozwiązanie na iOS 7 i nowsze!
Dla iOS 8 Apple dodał UIModalPresentationOverCurrentContext, ale nie działa na iOS 7 i wcześniejszych, więc nie mogłem go użyć w moim przypadku.
Utwórz kategorię i umieść poniższy kod.
plik .h
typedef void(^DismissBlock)(void); @interface UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion; @end
plik .m
#import "UIViewController+Ext.h" @implementation UIViewController (Ext) - (DismissBlock)presentController:(UIViewController *)controller withBackgroundColor:(UIColor *)color andAlpha:(CGFloat)alpha presentCompletion:(void(^)(void))presentCompletion { controller.modalPresentationStyle = UIModalPresentationCustom; UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; __block UIView *overlay = [[UIView alloc] initWithFrame:keyWindow.bounds]; if (color == nil) { color = [UIColor blackColor]; } overlay.backgroundColor = color; overlay.alpha = alpha; if (self.navigationController != nil) { [self.navigationController.view addSubview:overlay]; } else if (self.tabBarController != nil) { [self.tabBarController.view addSubview:overlay]; } else { [self.view addSubview:overlay]; } self.modalPresentationStyle = UIModalPresentationCurrentContext; [self presentViewController:controller animated:true completion:presentCompletion]; DismissBlock dismissBlock = ^(void) { [self dismissViewControllerAnimated:YES completion:nil]; [UIView animateWithDuration:0.25 animations:^{ overlay.alpha = 0; } completion:^(BOOL finished) { [overlay removeFromSuperview]; }]; }; return dismissBlock; } @end
Uwaga: działa również dla navigationContoller, tabBarController.
Przykład użycia:
// Please, insure that your controller has clear background ViewController *controller = [ViewController instance]; __block DismissBlock dismissBlock = [self presentController:controller withBackgroundColor:[UIColor blackColor] andAlpha:0.5 presentCompletion:nil]; // Supposed to be your controller's closing callback controller.dismissed = ^(void) { dismissBlock(); };
Ciesz się tym! i proszę zostawić informacje zwrotne.
źródło
To najlepszy i najczystszy sposób, jaki do tej pory znalazłem:
@protocol EditLoginDelegate <NSObject> - (void)dissmissEditLogin; @end - (IBAction)showtTransparentView:(id)sender { UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"foo bar" delegate:self cancelButtonTitle:@"cancel" destructiveButtonTitle:@"destructive" otherButtonTitles:@"ok", nil]; [actionSheet showInView:self.view]; } - (void)willPresentActionSheet:(UIActionSheet *)actionSheet{ UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:@"Login" bundle:nil]; self.editLoginViewController = [loginStoryboard instantiateViewControllerWithIdentifier:@"EditLoginViewController"]; self.editLoginViewController.delegate = self; [self.editLoginViewController viewWillAppear:NO]; [actionSheet addSubview:self.editLoginViewController.view]; [self.editLoginViewController viewDidAppear:NO]; }
źródło
Najlepszym rozwiązaniem, z jakim się spotkałem, jest użycie metody addChildViewController. Oto doskonały przykład: Dodaj widok podrzędnego kontrolera widoku do widoku podrzędnego nadrzędnego kontrolera widoku
źródło
Próbuję użyć wielu metod do rozwiązania, ale nadal nie udało mi się, następujący kod został wdrożony w końcu.
Rezolucja Swift:
// A.swift init method modalPresentationStyle = .currentContext // or overCurrentContent modalTransitionStyle = .crossDissolve // dissolve means overlay
następnie w B wyświetl kontroler :
// B.swift let a = A() self.present(a, animated: true, completion: nil)
źródło