The Missing Manual
for Swift Development
The Guide I Wish I Had When I Started Out
Join 20,000+ Developers Learning About Swift Development
Download Your Free Copy
Projekt Photos wykorzystuje wyłącznie storyboardy do projektowania i tworzenia kontrolerów widoku. W tym odcinku pokażę ci, że wzorzec koordynatora nie jest ograniczony do storyboardów. Możesz również użyć wzorca koordynatora, jeśli wolisz pliki XIB od storyboardów. Jeśli wolisz nie używać żadnego z nich, to też jest to możliwe. Nie ma znaczenia, jak zaprojektujesz i stworzysz kontrolery widoku swojego projektu.
Projekt startowy
Projekt startowy z tego odcinka jest funkcjonalnie identyczny z gotowym projektem z poprzedniego odcinka. Jest jednak kilka różnic, na które chciałbym zwrócić uwagę. Klasa TermsViewController
nie jest już zgodna z protokołem Storyboardable
i ma teraz trzy podklasy, TermsViewControllerStoryboard
, TermsViewControllerXIB
i TermsViewControllerCode
.
Klasa TermsViewControllerStoryboard
jest identyczna z klasą TermsViewController
z poprzedniego odcinka. Interfejs użytkownika klasy TermsViewControllerStoryboard
jest zdefiniowany w pliku Main.storyboard. Instancję klasy możemy wywołać, wywołując metodę instantiate()
protokołu Storyboardable
.
Interfejs użytkownika klasy TermsViewControllerXIB
jest zdefiniowany w pliku TermsViewControllerXIB.xib. Klasa TermsViewControllerXIB
definiuje statyczną, zmienną właściwość, nibName
, aby uniknąć używania literałów łańcuchowych. Jest to podobne do właściwości storyboardIdentifier
zdefiniowanej w Storyboardable.swift.
Jak sama nazwa wskazuje, klasa TermsViewControllerCode
nie ma powiązania z storyboardem ani z plikiem XIB. Interfejs użytkownika jest tworzony w kodzie. To oczywiście powoduje, że kodu jest znacznie więcej. Przyjrzyjmy się każdemu z tych kontrolerów widoku i zbadajmy, jak pasują one do wzorca koordynatora.
Storyboardy
Storyboardy istnieją od kilku lat i Apple zachęca programistów do korzystania z nich. Używam storyboardów w większości projektów, nad którymi pracuję. Xcode automatycznie tworzy storyboard podczas tworzenia nowego projektu, ale zdecydowanie polecam używanie kilku mniejszych storyboardów zamiast jednego dużego storyboardu. Używając kilku mniejszych storyboardów, możesz łatwiej uniknąć konfliktów scalania, a praca z mniejszymi storyboardami jest szybsza i mniej skomplikowana.
Segmenty są kluczową cechą storyboardów, ale nigdy nie używam ich w połączeniu z wzorcem koordynatora. Podczas gdy możliwe jest użycie segmentów w połączeniu z wzorcem koordynatora, segment angażuje kontroler widoku w przepływ aplikacji i jest to coś, czego chcemy uniknąć. Pamiętaj, że koordynatorzy projektu obsługują przepływ aplikacji. Kontroler widoku nie musi wiedzieć nic o przepływie aplikacji i nie musi wiedzieć o innych kontrolerach widoku.
Nawet bez segmentów, storyboardy mają swoją wartość. Zawsze dzielę średnie i duże projekty na moduły. Każdy moduł ma storyboard, który zawiera kontrolery widoku danego modułu.
Otwórz TermsCoordinator.swift i przejdź do metody showTerms()
. Implementacja jest identyczna jak w gotowym projekcie z poprzedniego odcinka. Jedyną różnicą jest nazwa klasy kontrolera widoku. Koordynator terminów instancjonuje klasę TermsViewControllerStoryboard
zamiast klasy TermsViewController
.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerStoryboard.instantiate() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
XIBs
Pliki XIB istnieją od wczesnych dni rozwoju Cocoa. Brakuje im kilku cech w porównaniu do storyboardów, ale nadal mają swoją wartość. Głównie używam XIB dla komponentów wielokrotnego użytku, takich jak komórki widoku tabeli i komórki widoku kolekcji.
Otwórz TermsViewControllerXIB.xib. Interfejs użytkownika klasy TermsViewControllerXIB
jest identyczny z interfejsem klasy TermsViewControllerStoryboard
w Main.storyboard. Otwórz plik TermsCoordinator.swift i ponownie zapoznaj się z metodą showTerms()
. Aby utworzyć instancję klasy TermsViewControllerXIB
, wywołujemy inicjalizator init(nibName:bundle:)
, przekazując nazwę pliku XIB oraz referencję do bundle’a zawierającego plik XIB.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerXIB(nibName: TermsViewControllerXIB.nibName, bundle: .main) // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
Code
Możliwe jest również tworzenie interfejsu użytkownika kontrolerów widoku projektu w kodzie. Jeśli nie lubisz storyboardów lub plików XIB, to jest to jedyna opcja. Nie używam tej opcji zbyt często od czasu wprowadzenia storyboardów, ale może być przydatna od czasu do czasu.
Tworzenie i inicjalizowanie kontrolera widoku w kodzie jest przydatne, jeśli ten kontroler widoku ma złożony lub dynamiczny interfejs użytkownika. Tworzenie i inicjalizowanie kontrolerów widoku w kodzie ma jeszcze jedną przekonującą zaletę. Pozwala na wstrzykiwanie inicjalizatora, formę wstrzykiwania zależności. Omówię wstrzykiwanie zależności w następnym odcinku.
Aby utworzyć instancję klasy TermsViewControllerCode
, wywołujemy inicjalizator init()
. Jest to równoznaczne z wywołaniem inicjalizatora init(nibName:bundle:)
i przekazaniem nil
dla obu argumentów.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerCode() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
What’s Next?
Wzorzec koordynatora jest wzorcem elastycznym. Nie ma znaczenia, czy używasz storyboardów, plików XIB, czy żadnego z nich. Możesz używać segmentów, ale pamiętaj, że naruszasz podstawową zasadę wzorca koordynatora, jeśli to zrobisz. Kontroler widoku nie musi wiedzieć o przepływie aplikacji i nie powinien wiedzieć o innych kontrolerach widoku.