2010-12-27 20 views

Odpowiedz

3

System iOS nie obsługuje przezroczystości podczas prezentacji widoku.

+1

Tak, myślę. Do tej pory iOS nie obsługuje przezroczystości w modalu. Dziękuję za maszynę do odpowiedzi. :) – Rizki

+0

Cóż, wiedząc, że to nie pomaga, ale –

+0

to jest niepoprawne, robię to z transperancją. – DeyaEldeen

0

Trzeba go działa wstecz, w pewnym sensie. Załaduj swój widok modalny, a następnie dodaj wszystkie elementy na nim "ręcznie" jako Subview, w ten sposób nie będą one ukrywane. Tak, jest dużo kodowania, ale można to zrobić. Zrobiłem to do odtwarzania filmów i posiadania dodatkowych elementów na ekranie, ustawiając mniejszy rozmiar klatki dla odtwarzacza filmowego i rzucając niektóre przyciski i widoki tekstu wokół niego jako Subviews. B

10

Okay, więc presentModalViewController nie oferuje takiego zachowania ... Jednak nadal jest możliwe. Stworzyłem kategorię, która działa dla mnie (i mam nadzieję, że ty). Jako dodatkowy bonus zapobiega to także awariom związanym z odrzucaniem i prezentowaniem widoków modalnych w tym samym czasie!

plik nagłówka:

// 
// UIViewController+overView.h 
// Created by Kevin Lohman on 5/30/12. 
// 

#import <UIKit/UIKit.h> 

@interface UIViewController (OverView) 
- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated; 
- (void)dismissOverViewControllerAnimated:(BOOL)animated; 
@end 

Realizacja Plik:

// 
// UIViewController+overView.m 
// Created by Kevin Lohman on 5/30/12. 
// 

#import "UIViewController+overView.h" 

@implementation UIViewController (OverView) 

#define kUIViewControllerOverViewDismissNotification @"OverViewDismissNotification" 

const float kUIViewControllerOverViewAnimationDuration = 0.75; 
const NSInteger kUIViewControllerOverViewTag = 8008135; // Arbitrary number, so as not to conflict 
- (void)overViewDismissed 
{ 
    [self autorelease]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kUIViewControllerOverViewDismissNotification object:self.view]; 
} 

- (void)presentOverViewController:(UIViewController *)modalViewController animated:(BOOL)animated 
{ 
    UIView *toView = self.view; 

    CGRect finalRect = CGRectIntersection([[UIScreen mainScreen] applicationFrame], self.view.frame); // Make sure it doesn't go under menu bar 
    modalViewController.view.frame = finalRect; 
    modalViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; 
    modalViewController.view.tag = kUIViewControllerOverViewTag+modalViewController.modalTransitionStyle; // Hiding some info here :) 

    if(animated) 
    { 
     switch(modalViewController.modalTransitionStyle) 
     { 
      // Currently only cross dissolve and cover vertical supported... if you add support let me know. 
      case UIModalTransitionStyleCrossDissolve: 
      { 
       float beforeAlpha = modalViewController.view.alpha; 
       modalViewController.view.alpha = 0; 
       [toView addSubview:modalViewController.view]; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        modalViewController.view.alpha = beforeAlpha; 
       }]; 
       break; 
      } 
      case UIModalTransitionStyleCoverVertical: 
      default: 
      { 
       modalViewController.view.frame = CGRectMake(modalViewController.view.frame.origin.x, modalViewController.view.frame.size.height, 
                  modalViewController.view.frame.size.width, modalViewController.view.frame.size.height); 
       [toView addSubview:modalViewController.view]; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        modalViewController.view.frame = finalRect; 
       }]; 
       break; 
      } 
     } 
    } 
    else { 
     [toView addSubview:modalViewController.view]; 
    } 

    [modalViewController retain]; // Keep it around until we dismiss it. 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(overViewDismissed) name:kUIViewControllerOverViewDismissNotification object:modalViewController.view]; // Release will happen when this notification is posted 
} 

NSInteger transitionStyleForTag(tag) 
{ 
    if (tag >= kUIViewControllerOverViewTag && tag <= kUIViewControllerOverViewTag+UIModalTransitionStylePartialCurl) 
    { 
     return tag-kUIViewControllerOverViewTag; 
    } 
    else { 
     return -1; // Not a Over View 
    } 
} 

- (void)dismissOverViewControllerAnimated:(BOOL)animated 
{ 
    UIView *overView = transitionStyleForTag(self.view.tag) >= 0 ? self.view : nil; // Can dismiss ourselves 
    for(UIView *subview in self.view.subviews) 
    { 
     if(transitionStyleForTag(subview.tag) >= 0) 
      overView = subview; // Keep going, lets dismiss last presented first 
    } 
    if(!overView) return; // None to dismiss 

    if(animated) 
    { 
     switch(transitionStyleForTag(overView.tag)) 
     { 
      // Currently only cross dissolve and cover vertical supported... if you add support let me know. 
      case UIModalTransitionStyleCrossDissolve: 
      { 
       float beforeAlpha = overView.alpha; 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        overView.alpha = 0; 
       } completion:^(BOOL finished) { 
        [overView removeFromSuperview]; 
        overView.alpha = beforeAlpha; 
        [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
       }]; 
       break; 
      } 
      case UIModalTransitionStyleCoverVertical: 
      default: 
      { 
       [UIView animateWithDuration:kUIViewControllerOverViewAnimationDuration animations:^{ 
        overView.frame = CGRectMake(0, overView.frame.size.height, overView.frame.size.width, overView.frame.size.height); 
       } completion:^(BOOL finished) { 
        [overView removeFromSuperview]; 
        [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
       }]; 
       break; 
      } 
     } 
    } 
    else { 
     [overView removeFromSuperview]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:kUIViewControllerOverViewDismissNotification object:overView]; 
    } 
} 
@end 

A potem z niego korzystać, wystarczy użyć presentOverViewController zamiast presentModalViewController i dismissOverViewController zamiast dissmissModalViewController.

Istnieje kilka ograniczeń:

  1. Musisz przedstawić korzeni większości kontrolera widoku, więc jeśli chcesz na cały ekran i masz VC wewnątrz UINavigationController, przedstaw go kontrolerowi nawigacji.
  2. mogą być pewne problemy z obrotu (nie widzę w ogóle) na starszych iOS buduje (4,0 lub więcej)
  3. Obecnie zajmuje się tylko Krzyż Rozpuścić i animacje Pokrycie pionowe.
+0

Ładne i uporządkowane rozwiązanie, dzięki! Dwie obserwacje. Najpierw moduł obsługi 'overViewDismissed' zwalnia self zamiast modalnego kontrolera widoku, co prowadzi do awarii. Usuń kod powiadomienia addObserver/postNotification w całości i zarządzaj pamięcią modalnego kontrolera widoku poza metodami obecnymi/odrzuconymi. Po drugie, '[[UIScreen mainScreen] applicationFrame]' nie zawsze zwraca prawidłowy rozmiar klatki. Zamiast tego używam 'self.view.superview.frame' (patrz [ta odpowiedź] (http://stackoverflow.com/a/4052442/22764)). –

+0

@ Vladimir Grigorov hej, dzięki za notatkę, wydaje się, że ma tam jakąś złą logikę. Nie pamiętam, w którym kodzie umieściłem to, ale wyobrażam sobie, że naprawiłem to lokalnie ... jeśli nadal kompilujesz/uruchamiasz jego stałą wersję, czy mógłbyś edytować odpowiedź na podstawie twoich ustaleń? Mógłbym to zmienić (czy to jest po prostu zmiana [autorelease self] na autorelease self.parentViewController] Ryzykowne dla mnie, aby dokonać zmiany ślepo :) – BadPirate

+0

Usunąłem już kod powiadomienia, jak napisałem w poprzednim komentarzu i ta wersja ma przeszedł test ... –

9

Odpowiedź była dla mnie jedna linia kodu, dodawany do kontrolera widoku rodzica przed przedstawieniem modalne kontrolera wyświetlania:

self.modalPresentationStyle = UIModalPresentationCurrentContext; 

To zatrzyma Zobacz główne przed usunięciem raz widok modalne ma został dodany.

+0

To nie wydaje się działać dla mnie. –

+0

Nic mi nie pomogło. – surfrider

+6

Ale to działa self.navigationController.modalPresentationStyle = UIModalPresentationCurrentContext; – surfrider

Powiązane problemy