2013-10-01 12 views
7

Korzystam z następującego kodu, aby przedstawić viewcontroller. Mój problem: Po zakończeniu animacji przezroczyste tło główne staje się nieprzejrzyste na czarno.Jak zaprezentować półprzezroczysty (pół-cut) viewcontroller w iOS?

Jak mogę to naprawić i sprawić, że pozostanie jako czysty kolor?

UIViewController *menuViewController=[[UIViewController alloc]init]; 
    menuViewController.view.backgroundColor=[UIColor clearColor]; 
    menuViewController.view.tintColor=[UIColor clearColor]; 
    menuViewController.view.opaque=NO; 

UIView *menuView=[[UIView alloc]initWithFrame:CGRectMake(0,[UIScreen mainScreen].bounds.size.height-200,320,200)]; 
    menuView.backgroundColor=[UIColor redColor]; 

[menuViewController.view addSubview:menuView]; 

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

aktualizacja: Próbuję zobaczyć zawartość "ja" (zobacz prezenter viewcontroller'S).

+4

To nie jest problem przejrzystości. Po zakończeniu animacji system iOS usuwa kontroler ukrytych widoków z ekranu. Czarna, którą widzisz, to kolor tła okna. Wierzę, że iOS7 ma kilka opcji. –

+0

@BrianNickel Masz na myśli, że kontroler podglądu prezentera jest ukryty, dopóki nie zostanie odrzucony? W takim przypadku, czy powinienem dodać widok ręcznie i użyć animacji, aby przenieść ją z dołu ekranu? – frankish

+1

To prawda. Możesz pominąć 'menuViewController' i po prostu animować' menuView' na ekranie, jak tylko chcesz. –

Odpowiedz

8

Jak wspomniano w komentarzach, nie jest to problem z przezroczystością (w przeciwnym razie można by oczekiwać, że tło stanie się białe). Po zakończeniu animacji presentViewController:animated:completion: prezentowany kontroler widoku zostanie faktycznie usunięty ze stosu wizualnego. Czarna, którą widzisz, to kolor tła okna.

Ponieważ wydaje się być po prostu za pomocą menuViewController jako host dla menuView uprościć animację, można rozważyć omijając menuViewController, dodając menuView do istniejącego widoku kontrolerów widoku hierarchii i animowanie go samodzielnie.

0

Spróbuj uczynić widok z góry przezroczystym i dodaj kolejny widok poniżej żądanego widoku, aby kolor tła tego widoku był czarny, a następnie ustaw alfa 0.5 lub dowolny poziom krycia, który Ci odpowiada.

1

Powinieneś użyć właściwości modalPresentationStyleavailable od iOS 3.2.

Na przykład:

presenterViewController.modalPresentationStyle = UIModalPresentationCurrentContext; 
[presenterViewController presentViewController:loginViewController animated:YES completion:NULL]; 
+3

To nie rozwiązuje problemu. PresenterViewController jest nadal usuwany z ekranu. – Peter

+0

Istnieją również pewne dziwactwa podczas przedstawiania z VC dziecka lub innych modów. Ку. – user3099609

23

można przedstawić kontroler widok, a jeszcze oryginalny kontroler widoku widoczny pod spodem, jak forma, w iOS 7. Aby to zrobić, trzeba zrobić dwie rzeczy :

  1. Ustaw modalne styl prezentacji zwyczaju:

    viewControllerToPresent.modalPresentationStyle = UIModalPresentationCustom; 
    
  2. Ustaw delegat przenoszący:

    viewControllerToPresent.transitioningDelegate = self; 
    

W tym przypadku musimy ustawić delegata do siebie, ale może być inny obiekt. Delegat musi realizować dwa wymagane metody protokołu, możliwe tak:

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source 
{ 
    SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init]; 
    semiModalAnimatedTransition.presenting = YES; 
    return semiModalAnimatedTransition; 
} 

- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed 
{ 
    SemiModalAnimatedTransition *semiModalAnimatedTransition = [[SemiModalAnimatedTransition alloc] init]; 
    return semiModalAnimatedTransition; 
} 

W tym momencie można myśleć, gdzie zrobił SemiModalAnimatedTransition klasa pochodzą. Cóż, jest to niestandardowa implementacja przyjęta z bloga teehan+lax.

Oto nagłówek klasy za:

@interface SemiModalAnimatedTransition : NSObject <UIViewControllerAnimatedTransitioning> 
@property (nonatomic, assign) BOOL presenting; 
@end 

i wdrożenie:

#import "SemiModalAnimatedTransition.h" 

@implementation SemiModalAnimatedTransition 

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext 
{ 
    return self.presenting ? 0.6 : 0.3; 
} 

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

    CGRect endFrame = fromViewController.view.bounds; 

    if (self.presenting) { 
     fromViewController.view.userInteractionEnabled = NO; 

     [transitionContext.containerView addSubview:fromViewController.view]; 
     [transitionContext.containerView addSubview:toViewController.view]; 

     CGRect startFrame = endFrame; 
     startFrame.origin.y = endFrame.size.height; 

     toViewController.view.frame = startFrame; 

     [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 
      fromViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed; 
      toViewController.view.frame = endFrame; 
     } completion:^(BOOL finished) { 
      [transitionContext completeTransition:YES]; 
     }]; 
    } 
    else { 
     toViewController.view.userInteractionEnabled = YES; 

     [transitionContext.containerView addSubview:toViewController.view]; 
     [transitionContext.containerView addSubview:fromViewController.view]; 

     endFrame.origin.y = endFrame.size.height; 

     [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{ 
      toViewController.view.tintAdjustmentMode = UIViewTintAdjustmentModeAutomatic; 
      fromViewController.view.frame = endFrame; 
     } completion:^(BOOL finished) { 
      [transitionContext completeTransition:YES]; 
     }]; 
    } 
} 

@end 

Nie najprostszym rozwiązaniem, ale unika hacki i działa dobrze.Niestandardowe przejście jest wymagane, ponieważ domyślnie iOS usunie pierwszy kontroler widoku na końcu przejścia.

UPDATE:

Dla iOS 8, po raz kolejny zmieniła krajobraz. Wszystko, co musisz zrobić, to użyć nowej prezentacji styl .OverCurrentContext, a mianowicie:

viewControllerToPresent.modalPresentationStyle = UIModalPresentationOverCurrentContext; 
+0

'modalPresentationStyle' i' transitionDelegate' można ustawić w 'parepareForSegue' –

+3

powinno to być oznaczone jako najlepsza odpowiedź –

+1

to łamie się w iOS 8. podczas zamykania ekranu WHITE – thesummersign

4

Jest to dość prosty problem do rozwiązania. Zamiast tworzyć niestandardowe przejścia widoku, wystarczy ustawić modalPresentationStyle dla przedstawianego kontrolera widoku. Należy także ustawić kolor tła (i wartość alfa) dla kontrolowanego kontrolera widoku w kodzie story/via.

CustomViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6) 
    } 
} 

W składniku IBAction prezentacji widoku kontrolera -

let vc = storyboard?.instantiateViewControllerWithIdentifier("customViewController") as! CustomViewController 
vc.modalPresentationStyle = UIModalPresentationStyle.Custom 
presentViewController(vc, animated: true, completion: nil) 
+3

Działa to tylko w systemie iOS 8 (i nowszych wersjach). –

+0

@RicSantos Dziękujemy! Tak, to zostało przetestowane tylko na iOS 8+. – arpwal

+0

Doskonałe rozwiązanie, dzięki! – dreampowder

Powiązane problemy