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
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.
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)
}
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. –
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.
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
- 1. Czy mogę mieć selektor wieloelementowy w jquery?
- 2. Czy mogę mieć parsys wewnątrz parsys
- 3. Czy mogę mieć stały tekst w ulotce?
- 4. Czy mogę mieć formularz Django bez modelu
- 5. Czy mogę mieć wiele instancji modułu RequireJS?
- 6. Czy mogę mieć wiele katalogów GOPATH?
- 7. Czy mogę mieć zdarzenie onclick elementu elementu imagemap
- 8. Czy mogę mieć statyczny indeks dolny w Swift?
- 9. Narzędzia deweloperskie Chrome - czy zawsze mogę mieć ładny druk?
- 10. Jak mogę mieć nieaktywnego słuchacza?
- 11. Czy mogę mieć inny serwer pocztowy dla każdej subdomeny?
- 12. Czy mogę mieć wiele tagów rel = "alternate" dla strony internetowej?
- 13. Czy mogę mieć punkt dostępu w VisualStudio, który pomija wiersze?
- 14. vim: czy mogę mieć ostatni klucz wiązania wieloprzyciskowego powtórzyć polecenie?
- 15. Czy mogę mieć wartość ujemną jako wyrażenie stałe w Scali?
- 16. Czy mogę mieć procedurę okna głównego jako lambda w WinMain?
- 17. Czy mogę mieć wiele plików konfiguracyjnych w DropWizard?
- 18. Czy mogę mieć wiele plików site.master w asp.net mvc
- 19. Czy mogę mieć RSpec bez klasy dla metod
- 20. Czy mogę mieć więcej niż 1 instancję "mongos"?
- 21. Czy mogę mieć przykład wyświetlania toast za pomocą runOnUiThread.
- 22. Czy mogę mieć wiele plików web.config w jednym projekcie WWW?
- 23. Jak mogę mieć wielu klientów na serwerze czatów TCP Python?
- 24. Jaki jest najdłuższy ciąg jaki mogę mieć?
- 25. Jak mogę ustawić formę mieć przezroczyste tło
- 26. UIPresentationController zmienia rozmiar, gdy wyświetlany jest inny kontroler widoku.
- 27. Jak mogę mieć asercje zmiennych w Perlu?
- 28. Jak mogę mieć CheckBoxFor za pomocą int?
- 29. Czy moduły mogą mieć właściwości?
- 30. Jak mogę mieć pracę Response.Redirect() z MasterPage?
Ciekawe rozwiązanie. Zdecydowanie muszę spróbować. – jollyCocoa
To jest dobre rozwiązanie dla dokładnie problemu w tytule pytania. –
To jest wspaniałe. –