2014-09-16 5 views
12

Jestem nowy w rozwoju iOS i staram się nauczyć storyboardingu, Swifta i nowych funkcji systemu iOS 8 w tym samym czasie.Sposób użycia: odrzucenie poppera w iPhonie w Adaptive Storyboard

Stworzyłem bardzo prosty scenopis, który wykorzystuje przejście prezentacji Popover do wyświetlania innego widoku. Na symulatorze, jeśli uruchomię to dla iPada, działa zgodnie z oczekiwaniami. Jeśli jednak uruchomię go dla iPhone'a, zamiast popover, wyświetla on widok pełnoekranowy, na górze oryginalnego widoku. Jest okej; jednak nie ma sposobu, aby go zamknąć i wrócić do pierwotnego ekranu.

Oglądałem wideo z konferencji WWDC 2014 "228 A Look wewnątrz kontrolerów prezentacji" i można wyświetlić przycisk odrzucania, jeśli interfejs użytkownika jest tworzony całkowicie za pomocą kodu.

Obejrzałem także sesję "411 Co nowego w budowaniu interfejsu", w której mówią, że można to zrobić w Konstruktorze interfejsów, ale nie pokazują tego, obiecując pokazać, jak to zrobić w laboratorium, jeśli każdy jest zainteresowany. Niestety, nie uczestniczyłem w WWDC 2014 ani nie znam nikogo, kto ma. Moje wyszukiwania w Google również nie zwróciły niczego przydatnego.

+1

Czy na planszy jest jakikolwiek kontroler UINavigationController? –

+0

@AdityaWirayudha: Nie, ale mogę dodać, jeśli było to wymagane. – Eduardo

+1

Proszę spróbować, myślę, że doda kontroler widoku prezentacji w stosie nawigacji (stąd przycisk powrotu na przedstawionym kontrolerze widoku) –

Odpowiedz

11

Można dodać kontroler nawigacyjny jak to-

  • Określ popover widok kontroler jako kontroler widoku głównego do kontrolera nawigacji.
  • Usunięcie segmentu popover, którego aktualnie używasz:
  • Ponownie podłącz segment z przycisku, który wyświetla popover, do kontrolera nawigacyjnego. Na iPadzie otrzymasz popover, a na iPhonie otrzymasz prezentację modalną. Na iPadzie i iPhonie pojawi się kontroler nawigacyjny. W zależności od przypadku użycia może to być lub nie być coś, co chcesz. Oto ekran pokazujący, jak powinien wyglądać scenorys.
    • Your storyboard should look like this if you add the navigation controller in storyboard.

Jeśli naprawdę chcesz, aby kontroler widoku, aby zawsze być popover zostawić storyboard tak jest i dodać coś takiego do kontrolera widoku, który prezentuje popover-

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
if ([segue.identifier isEqualToString:@"Your segue name"]) { 
    UIViewController *yourViewController = segue.destinationViewController; 
    yourViewController.modalPresentationStyle = UIModalPresentationPopover; 
    UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController; 
    popoverPresentationController.delegate = self; 
    } 
} 

kontroler widok prezentujący popover będzie musiała odpowiedzieć na tę metodę UIPopoverPresentationDelegate

- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller 
{ 
return UIModalPresentationNone;//always popover. 
} 

Na koniec można wykonać następujące czynności, aby dodać kontroler nawigacyjny tylko do modalnej prezentacji kontrolera widoku na telefonie iPhone i pozostawić popover na iPadzie bez kontrolera nawigacyjnego.

  • Pozostaw swój scenorys w niezmienionej postaci.
  • Właściwym miejscem do wstrzyknięcia kontrolera nawigacyjnego jest - (UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style. Aby to się stało, musimy ustawić się jako delegat UIPopoverPresentationController. Po raz kolejny będziemy to zrobić w prepareForSegue:

    -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
    { 
    if ([segue.identifier isEqualToString:@"Your segue name"]) { 
        UIViewController *yourViewController = segue.destinationViewController; 
        yourViewController.modalPresentationStyle = UIModalPresentationPopover; 
        UIPopoverPresentationController *popoverPresentationController = yourViewController.popoverPresentationController; 
        popoverPresentationController.delegate = self; 
        } 
    } 
    

Wtedy będziemy to robić w metodzie delegata, że ​​wspomnianym powyżej

-(UIViewController *)presentationController:(UIPresentationController *)controller viewControllerForAdaptivePresentationStyle:(UIModalPresentationStyle)style 
{ 
    UIViewController *presentedViewController = controller.presentedViewController; 
    UINavigationController *navigationController = [[UINavigationController alloc] 
       initWithRootViewController:presentedViewController]; 
    UIBarButtonItem *dismissButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleDone target:self action:@selector(done:)]; 
    presentedViewController.navigationItem.rightBarButtonItem = dismissButton; 

    return navigationController; 
} 

Powodzenia!

+0

W jaki sposób spowodowałbyś, że przycisk Gotowe nie jest wyświetlany w przypadku wyświetlenia popover? – Eduardo

+0

'- (void) prepareForSegue (UIStoryboardSegue *) Segue nadawcy (ID) nadawca {if ([segue.identifier isEqualToString: @ "rozmiar strony popover"]) { UINavigationController * navController = segue.destinationViewController; UIModalPresentationStyle style = navController.modalPresentationStyle; if (styl == UIModalPresentationPageSheet) { UIBarButtonItem * doneButton = [[przydział UIBarButtonItem] initWithBarButtonSystemItem: UIBarButtonItemStyleDone target: self action: @selector (done :)]; [navController.navigationItem setRightBarButtonItem: doneButton]; } } } ' –

+0

Przepraszamy za słabe odstępy, w komentarzach obowiązuje limit znaków. Zakładam, że masz na myśli, jak usunąć zrobiony przycisk z pierwszym przykładem, który ma zrzut ekranu storyboardu. –

8

Jeśli chcesz, to popover na iPadzie, ale modalny arkusz z przyciskiem zamykania na iPhonie, możesz to zrobić bez tworzenia dodatkowego kontrolera nawigacyjnego w scenorysie dla popover.

w Xcode 6.3 ujęć, wystarczy podłączyć kontroler widoku i wyznaczenia segue jako „obecny jako popover”

Poniższy kod powinien iść w kontroler widoku, który segues do popover, a nie w popover sam:

Najpierw trzeba ustawić delegata popover:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "myPopoverSegueName") { 
     let vc = segue.destinationViewController 
     vc.popoverPresentationController?.delegate = self 
     return 
    } 
} 

Następnie dodać rozszerzenie delegata (poniżej kod Pana zdaniem regulatora) i utworzyć przycisk kontrolera nawigacji/zamknij na bieżąco:

extension myViewController: UIPopoverPresentationControllerDelegate { 

    func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? { 
     let btnDone = UIBarButtonItem(title: "Done", style: .Done, target: self, action: "dismiss") 
     let nav = UINavigationController(rootViewController: controller.presentedViewController) 
     nav.topViewController.navigationItem.leftBarButtonItem = btnDone 
     return nav 
    } 

} 

Następnie dodaj swoją funkcję odwoływania i powinno być dobrze iść:

func dismiss() { 
    self.dismissViewControllerAnimated(true, completion: nil) 
} 
+0

Jest to znacznie prostsze niż zaakceptowana odpowiedź. – MattL

3

Nie jestem pewien, dlaczego trzeba zrobić storyboard konfiguracji dla przycisku Gotowe, cała praca może być wykonywana programowo z kilkoma liniami kodu. Ważną częścią jest wdrożenie niektórych UIAdaptivePresentationControllerDelegate metod protokołu dokładnie jak poniżej:

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle 
{ 
     return .FullScreen 
} 
func presentationController(controller: UIPresentationController, 
     viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController?{ 

     var navController:UINavigationController = UINavigationController(rootViewController: controller.presentedViewController) 
     controller.presentedViewController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: self, action:"done") 
     return navController  
} 

Następnie prosty sposób zaimplementować zachowanie odwoływanie dla popover w przypadku, gdy został przedstawiony na pełnym ekranie:

func done(){   
     presentedViewController?.dismissViewControllerAnimated(true, completion: nil) 
} 

i skończyłeś!

+0

Dzięki! Kiedy zadałem to pytanie, był to mój pierwszy projekt na iOS. Byłem kompletnym noobem. – Eduardo

0

Można to zrobić za pomocą mimimalnego kodu, a zamiast tego wstawić logikę do storyboardu. W kontrolerze widoku, który prezentuje popover, wystarczy umieścić w metodzie markera

@IBAction func unwindToContainerVC(segue: UIStoryboardSegue) { 

} 

Nie potrzeba żadnego kodu, ale musi być obecna, dzięki czemu można kontrolować przeciągnąć na ikonę Exit później podczas korzystania z interfejsu konstruktora.

Moja zawartość popover nie zajmuje całego widoku tła, ale ma niewielki margines wokół niego. Oznacza to, że możesz użyć kreatora interfejsów, aby utworzyć rozpoznawcę gestów dotykowych dla tego widoku. Sterowanie przeciągnij wykrywacz gestów do ikony Wyjdź, a następnie wyskakuj wybrane opcje wyjścia, z których jedną jest metoda unwindToContainerVC, jak pokazano powyżej.

Teraz każde stuknięcie wokół krawędzi (na przykład w scenariuszu iPhone 4S) przenosi użytkownika z powrotem do prezentującego kontrolera widoku.

Oto inspektor połączeń dla funkcji rozpoznawania gestów: enter image description here

0

W moim przypadku, miałem małe okienko, które chciałem być popup zarówno na iPhone i iPad - i chciał uniknąć używając nawigacji pasek za pomocą przycisku Dismiss. Odkryto, że potrzebne jest wdrożenie dwóch połączeń delegowanych (Swift 3.0):

extension MyViewController : UIPopoverPresentationControllerDelegate { 
    // Needed for iPhone popup 
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { 
     return .none 
    } 

    // Needed for iPhone in landscape 
    func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle { 
     return .none 
    } 
} 
Powiązane problemy