8

Buduję niestandardowy graficzny interfejs użytkownika w uniwersalnej aplikacji na iPhone'a i iPada. Na iPadzie opiera się on w dużym stopniu na "sideViews" dla narzędzi takich jak manipulacja zawartością, detailInformation i podobne (pomyśl o zaawansowanym SplitView). Z punktu widzenia wizualnego nowy UIPresentationController jest na miejscu, pozwalając mi zaprezentować te "sideViews" (i nie używając dimmedView), a implementacja została prosta do zbudowania i utrzymania, a jednocześnie przyjemnie zintegrować z storyboardem. Ale muszę być w stanie manipulować treścią presentViewController podczas gdy widoczneViewController jest widoczny. Moje pytanie brzmi: czy mogę ustawić userInteractionEnabled (lub podobne) na presentViewController podczas prezentacji sideViews?Czy mogę UIPresentationController mieć userInteractionEnabled na PresentingViewController?

Odpowiedz

11

UIPresentationController wstawia swój pogląd kontenera jako podrzędny okna nad widokiem przedstawienia, więc wszelkie akcenty poza przedstawionego widoku uwięzione przez widok pojemnika i nigdy nie je do przedstawiając widok.

Poprawka polega na wstawieniu widoku do widoku kontenera, który przechodzi przez dotknięcia do prezentującego widoku. Możesz użyć tego jako widoku przyciemniania lub ustawić jego backgroundColor na [UIColor clearColor] dla uzyskania w pełni przezroczystego widoku. Ustaw widoki przekazywania w kodzie kontrolera prezentacji.

@interface IVPasserView : UIView 

@property (strong, nonatomic) NSArray* passthroughViews; 

@end 

@implementation IVPasserView 

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    UIView* hit = [super hitTest:point withEvent:event]; 
    if (hit == self) 
     for (UIView* passthroughView in _passthroughViews) 
     { 
      hit = [passthroughView hitTest:[self convertPoint:point toView:passthroughView] 
           withEvent:event]; 
      if (hit) 
       break; 
     } 
    return hit; 
} 

@end 

Uwaga: podczas gdy ten jest niezgodny z duchem -[UIView hitTest:withEvent:] na to, że nie zwraca podrzędny, to jest w rzeczywistości, jak standardowy system UIPopoverPresentationController obsługuje go. Jeśli ustawisz tam właściwość passthroughViews, widok kontenera będzie odpowiadał hitTest:withEvent: w widoku przejścia, nawet jeśli nie jest to widok super podglądu/subview! Tak więc prawdopodobnie przetrwa kolejne wydanie iOS.

+0

Ciekawe rozwiązanie. Zdecydowanie muszę spróbować. – jollyCocoa

+0

To jest dobre rozwiązanie dla dokładnie problemu w tytule pytania. –

+0

To jest wspaniałe. –

2

Okay, więc wydaje się, że pomysł UIPresentationController NIE jest w stanie używać go jako zaawansowanego SplitView (a przynajmniej to mój obecny wniosek). Udało mi się jednak zbudować obejście. Jeśli ktokolwiek znajdzie lepszy sposób postępowania, daj mi znać w komentarzach.

Co mogę zrobić, to wstawiam widok PresentingViewController w strukturze transitionContexts containerView (takiej samej jak hierarchia UIPresentationControllers containerView) w indeksie 0. Dzięki temu mogę w przejrzysty sposób obsługiwać zdarzenia touchEvent w widoku PresentingViewControllers. Ale usuwa widok PresentingViewControllers z pierwotnej hierarchii widoku, więc muszę przenieść go tam, kiedy prezentacja zostanie odrzucona. Oznacza to umieszczenie widoku z powrotem w widoku parentViewController, jeśli jest obecny, lub w oknie aplikacji, jeśli prezentujeViewController jest rootViewController aplikacji (mogą być również inne scenariusze, ale to zrobi na razie).

Wszystko to odbywa się w animateTransition w UIViewControllerAnimatedTransitioning.

Oto fragment kodu:

UIView.animateWithDuration(transitionDuration(transitionContext), 
     delay: 0.0, 
     usingSpringWithDamping: 1.0, 
     initialSpringVelocity: 0.5, 
     options: UIViewAnimationOptions.BeginFromCurrentState|UIViewAnimationOptions.AllowUserInteraction, 
     animations: {() -> Void in 
      animatingView.frame = finalFrame 
     }) { (finished:Bool) -> Void in 
      if !self.isPresentation { 
       if let parentViewController = backgroundVC.parentViewController { 
        parentViewController.view.addSubview(backgroundVC.view) 
       } 
       else if let window = (UIApplication.sharedApplication().delegate as! AppDelegate).window { 
        window.addSubview(backgroundVC.view) 
       } 
       fromView.removeFromSuperview() 
      } 
      else { 
       containerView.insertSubview(backgroundVC.view, atIndex: 0) 
      } 
      transitionContext.completeTransition(true) 
    } 
+1

Masz rację, że kontrolery prezentacji nie są dobrze dostosowane do tworzenia niestandardowych widoków podziału. W tym przypadku kontrola kontrolera widoku jest prawdopodobnie lepszym rozwiązaniem. –

1

Prezentacja modalna nie jest dobrze dopasowana do sytuacji. Lepiej jest zaimplementować swój scenariusz za pomocą niestandardowego kontrolera widoku kontenera i zastąpić metodę showDetailViewController:sender: w celu obsługi prezentacji dodatkowych kontrolerów widoku. Możesz zaadaptować tę metodę, aby wyświetlić modulator widoku na iPhonie, a na przykład na iPadzie.

Oto fragment z Apple Documentation:

Przedstawiając Versus pokazującą widok Controller

Klasa UIViewController oferuje dwa sposoby, aby wyświetlić widok Kontroler:

The showViewController: Nadawca: i showDetailViewController: sender: metody oferują najbardziej adaptacyjny i elastyczny sposób wyświetlania kontrolerów widoku . Te metody pozwalają kontrolerowi przedstawiającemu prezentację decydować, jak najlepiej obsługiwać prezentację. Na przykład kontroler widoku kontenera może zawierać kontroler widoku jako dziecko, a nie prezentując go modalnie. Domyślne zachowanie przedstawia kontroler widoku modalnie. PresentViewController: animated: completion: Metoda zawsze wyświetla kontroler widoku modalnie. Kontroler widoku, który wywołuje tę metodę, może ostatecznie nie obsługiwać prezentacji , ale prezentacja jest zawsze modalna. Ta metoda dostosowuje styl prezentacji do poziomych kompaktowych środowisk. Metody showViewController: sender: i showDetailViewController: sender: są preferowanym sposobem inicjowania prezentacji. Sterownik widokowy może wywoływać je bez wiedzy o reszcie hierarchii kontrolera widoku lub pozycji bieżącego kontrolera widoku w tej hierarchii. Te metody ułatwiają również ponowne użycie kontrolerów widoku w różnych częściach aplikacji bez pisania ścieżek warunkowego kodu.

+0

Hej, Alexander! Dziękuję za odpowiedź i przepraszam za opóźnioną odpowiedź. To z pewnością wydaje się interesującym rozwiązaniem. Zobaczę, czy to rozwiąże mój problem, a jeśli tak, daj mu za to kredyt. Awansuj teraz na dobry pomysł. – jollyCocoa

Powiązane problemy