praca z kontrolerami widoku tabeli w Swift

napisany przez Reinder de Vries dnia sierpnia 3 2020 w rozwój aplikacji, iOS

praca z kontrolerami widoku tabeli w języku Swift

w tym samouczku pokażę Ci krok po kroku, jak działają Kontrolery widoku tabeli i jak można z nich korzystać. Przejdziemy do pełnej gamy UITableViewController, zagłębiając się w programowanie obiektowe, delegację i zakulisowe mechanizmy widoków tabel.

kontroler widoku tabeli wyświetla uporządkowane, powtarzalne informacje w pionowej liście. Do tworzenia kontrolera widoku tabeli używasz klasy UITableViewController w aplikacji na iOS.

praca z kontrolerem widoku tabeli oznacza również pracę z kilkoma ważnymi koncepcjami Rozwoju Systemu iOS, takimi jak podklasowanie, wzorzec projektowania delegacji i ponowne wykorzystanie widoków.

to ważne dla profesjonalnych i praktycznych programistów iOS (ty!) do opanowania pracy ze sterownikami widoku tabeli. Gdy już przyzwyczaisz się do pracy nad tak wielopłaszczyznowym komponentem UI, takim jak UITableViewController, inne bardziej złożone aspekty rozwoju iOS zaczną mieć sens.

gotowy? Zanurzmy się!

  1. jak działa kontroler widoku tabeli
  2. Konfigurowanie prostego kontrolera widoku tabeli
  3. kodowanie źródła danych kontrolera widoku tabeli
  4. dostarczanie komórek do kontrolera widoku tabeli
  5. reagowanie na interakcje użytkownika
  6. Czytaj dalej

jak działa kontroler widoku tabeli kontroler widoku działa

jeśli używałeś wcześniej dowolnej aplikacji na iOS, wcześniej używałeś kontrolerów widoku tabeli. Są one używane tak często w aplikacjach na iOS!

oto przykład kontrolera widoku tabeli:

 przykład kontrolera widoku tabeli

kontroler widoku tabeli zwykle ma te widoczne komponenty:

  • widok tabeli, który jest komponentem interfejsu użytkownika, lub widok, który jest wyświetlany na ekranie. Widok tabeli jest instancją klasy UITableView, która jest podklasą UIScrollView.
  • komórki widoku tabeli, które są powtarzalnymi wierszami lub widokami, pokazanymi w widoku tabeli. Komórka widoku tabeli jest instancją klasy UITableViewCell i ta klasa jest często podklasowana do tworzenia niestandardowych komórek widoku tabeli.

kontroler widoku tabeli również opiera się na wykorzystaniu tych komponentów, Za kulisami:

  • delegat widoku tabeli, który odpowiada za zarządzanie układem widoku tabeli i reagowanie na zdarzenia interakcji z użytkownikiem. Delegat widoku tabeli jest instancją klasy UITableViewDelegate.
  • źródło danych widoku tabeli, które jest odpowiedzialne za zarządzanie danymi w widoku tabeli, w tym komórkami i sekcjami widoku tabeli. Źródłem danych jest instancja klasy UITableViewDataSource.

Kontroler nawigacyjny jest często używany w połączeniu z kontrolerem widoku tabeli, aby umożliwić nawigację między widokiem tabeli a kolejnymi kontrolerami widoku oraz aby wyświetlić pasek nawigacji nad widokiem tabeli.

najciekawszą częścią pracy z kontrolerami widoku tabeli jest sam kontroler widoku tabeli! Jak to?

czy znasz architekturę Model-View-Controller? Zgodnie z architekturą Model-View-Controller widok tabeli i komórka widoku tabeli są widokami,a kontroler widoku tabeli jest kontrolerem.

widoki są odpowiedzialne za wyświetlanie informacji w sposób widoczny dla użytkownika, z interfejsem użytkownika (UI). Administratorzy są odpowiedzialni za wdrażanie logiki, zarządzanie danymi i podejmowanie decyzji. Powiedział inaczej: nie widzisz kontrolera, ale on tam jest, zarządzając tym, co widzisz za pomocą widoków.

gdy używasz kontrolera widoku tabeli w aplikacji, podklasujesz klasę UITableViewController. Klasa UITableViewController jest podklasą UIViewController.

oto hierarchia klas przykładowego kontrolera widoku tabeli, który wyświetla informacje kontaktowe:

  • instancja ContactsTableViewController
    • podklasy UITableViewController
      • podklasy UIViewController

zgodnie z zasadami programowania obiektowego (OOP), gdy Klasa RaceCar podklasy klasy Vehicle, dziedziczy właściwości i funkcje tej klasy nadrzędnej, takie jak maxSpeed i drive().

Klasa Vehicle jest wtedy nazywana superklasą RaceCar. Zasada ta nazywana jest dziedziczeniem.

Może być! Pomyśl o tym tak: aby kontroler widoku tabeli działał poprawnie, musisz odziedziczyć kilka kodów, więc nie musisz pisać całego kodu samodzielnie. Hierarchia klas i OOP służą do uporządkowania tego dziedziczenia.

schemat klasy kontrolera widoku tabeli

możesz pracować z widokami tabeli bez użycia kontrolera widoku tabeli. Wystarczy dodać UITableView do kontrolera widoku, dostarczyć mu implementacje funkcji delegata widoku tabeli i źródła danych i gotowe.

Klasa UITableViewController zapewnia domyślne implementacje tych funkcji delegowania widoku tabeli i źródła danych widoku tabeli. To kluczowy aspekt pracy z kontrolerem widoku stołu!

jak zobaczysz w kolejnych rozdziałach tego samouczka, nadpisamy te funkcje za pomocą naszych własnych implementacji. W ten sposób możemy dostosować kontroler widoku tabeli.

dowiedz się, jak tworzyć aplikacje na iOS

rozpocznij pracę z iOS 14 i Swift 5

Zapisz się na mój kurs programowania na iOS i dowiedz się, jak tworzyć świetne aplikacje na iOS 14 za pomocą Swift 5 i Xcode 12.

Konfigurowanie prostego kontrolera widoku tabeli

w porządku, wykorzystajmy to wszystko w praktyce. W tej sekcji zbudujemy prosty kontroler widoku tabeli. Zaimplementujesz funkcje potrzebne do działania, a ja wyjaśnię, jak działają. Ruszajmy!

możesz używać 3 różnych metod pracy z interfejsem użytkownika w Xcode:

  1. tworzenie widoków programowo, tj. kodowanie ich ręcznie
  2. Konfigurowanie Ui w Interface Builder i łączenie ich z kodem Swift za pomocą XIBs
  3. Konfigurowanie UI i ich przejść w Interface Builder za pomocą Storyboardów
  4. (technicznie można użyć SwiftUI też, ale jeśli chodzi o Kontrolery widoku tabeli, to poza zakresem tego samouczka.)

ręczne kodowanie UI jest żmudne i bezproduktywne. Jeśli nie jesteś ostrożny z Storyboardami, ukrywają one złożoność przed programistą. Będziemy pracować z Storyboardami, zastanawiając się dokładnie, jak działają za kulisami.

oto, co zamierzasz zrobić:

najpierw Utwórz nowy projekt Xcode za pomocą pliku → Nowy → Projekt…. Pamiętaj, aby wybrać szablon aplikacji i wybrać Storyboard dla interfejsu i delegat aplikacji UIKit dla cyklu życia.

następnie wykonaj następujące kroki:

  1. kliknij prawym przyciskiem myszy swój projekt w Nawigatorze projektu i wybierz nowy plik…
  2. Wybierz szablon klasy Cocoa Touch (iOS)
  3. Wybierz UITableViewController dla podklasy
  4. Nazwij klasę ContactsTableViewController
  5. nie zaznaczaj również Utwórz plik XIB
  6. wreszcie, kliknij Dalej i zapisz plik wraz z innymi plikami SWIFT

na koniec zrób to:

  1. przejdź do Main.storyboard i usuń istniejącą scenę kontrolera widoku
  2. Dodaj nowy kontroler widoku tabeli do storyboardu za pomocą biblioteki
  3. Po wybraniu kontrolera widoku tabeli przejdź do Inspektora atrybutów i zaznacz pole wyboru is Initial View Controller
  4. na koniec przejdź do Inspektora tożsamości i ustaw klasę na ContactsTableViewController

to jest to! Masz teraz kontroler widoku tabeli wewnątrz storyboardu projektu i podłączyłeś go do klasy ContactsTableViewController Swift.

Xcode Table view controller skonfiguruj

jak się domyślasz, twoja klasa ContactsTableViewController jest podklasą UITableViewController. Możesz to zobaczyć w pliku Swift, na górze, w deklaracji klasy.

class ContactsTableViewController: UITableViewController { ···

ta składnia oznacza: Klasa ContactsTableViewController jest podklasą UITableViewController.

po kliknięciu prawym przyciskiem myszy na „UITableViewController”, trzymając klawisz Option-key, możesz zobaczyć w deklaracji klasy, że UITableViewController jest podklasą UIViewController i jest zgodna z protokołami UITableViewDelegate i UITableViewDataSource.

zobacz dokumentację kontrolera widoku tabeli w Xcode

to jest moc kontrolera widoku tabeli! To nie tylko daje nam poszczególne komponenty do tworzenia widoku tabeli, kontroler zapewnia również domyślną implementację. Dlatego podklasa UITableViewController zamiast tworzyć pusty kontroler widoku z widokiem tabeli.

w tym momencie możesz uruchomić aplikację za pomocą Command-R lub przycisku Odtwórz, a na ekranie pojawi się pusty kontroler widoku tabeli.

a tak w ogóle to czemu? Jeszcze nic nie zakodowaliśmy! Dzieje się tak dlatego, że kontroler widoku tabeli ma domyślną implementację, która po prostu pokazuje puste komórki na ekranie. Super!

 przykład kontrolera widoku tabeli w symulatorze iPhone ' a

w zależności od wersji Xcode użyliśmy delegata sceny do skonfigurowania początkowego kontrolera widoku projektu aplikacji. Dowiedz się więcej tutaj: Delegat sceny w Xcode

XIB i stalówka to w zasadzie to samo-zawierają informacje o układzie. XIB ma format XML, podczas gdy stalówka ma format binarny. XML jest kompilowany do binarnego podczas tworzenia aplikacji, dlatego funkcje UIKit zawsze mówią o „stalówce”, podczas gdy Xcode zawsze nazywa to „xib”.

kodowanie źródła danych kontrolera widoku tabeli

teraz, gdy twój kontroler widoku tabeli został skonfigurowany, ożyw go! W tym rozdziale skupimy się na różnych funkcjach, które musisz zaimplementować, aby kontroler widoku tabeli działał.

jak wyjaśniono wcześniej, funkcje te należą do delegata kontrolera widoku tabeli lub do źródła danych kontrolera widoku tabeli. Oba te protokoły używają delegacji, aby dostosować widok tabeli.

najważniejsze funkcje dla UITableViewDataSource to:

  • numberOfSections(in:)
  • tableView(_:numberOfRowsInSection:)
  • tableView(_:cellForRowAt:)

inne istotne funkcje dla UITableViewDelegate to:

  • tableView(_:didSelectRowAt:)
  • tableView(_:willDisplay:for:)

więcej funkcji można znaleźć w dokumentacji Apple Developer dla UITableViewDelegate i UITableViewDataSource.

Dodawanie danych kontaktów

rozpocznij od dodania danych kontaktowych kontrolera widoku tabeli. Dodaj następującą właściwość do klasy ContactsTableViewController :

let contacts:] = , , , , , , , , , , , , , , , , ]

to rolodex, który wszyscy chcielibyśmy mieć, prawda? Oto jak to działa:

  • let contacts deklaruje stałą o nazwie contacts. Dodałeś ją jako właściwość do klasy, więc każda instancja klasy ma dostęp do tej stałej w całym kodzie klasy.
  • Typ contacts to ], czyli tablica tablic ciągów znaków. Zasadniczo tworzysz tablicę, której elementy są tablicami łańcuchów. (Nazwa zmiennej i jej Typ są oddzielone dwukropkiem :)
  • kod = przypisuje literał tablicy do contacts, wypełniony nazwiskami i numerami telefonów kilku miliarderów.

w późniejszym momencie możemy użyć liczby pozycji w tablicy z contacts.count. I możemy uzyskać indywidualne nazwy i numery telefonów z contacts i contacts, używając składni indeksu dolnego.

rejestrowanie klasy komórek widoku tabeli

zanim będzie można używać komórek w kontrolerze widoku tabeli, należy je zarejestrować w widoku tabeli. Można to zrobić na dwa sposoby:

  1. podając klasę komórki widoku tabeli i identyfikator
  2. podając komórkę widoku tabeli XIB i identyfikator

gdy używasz niestandardowej komórki widoku tabeli, najprawdopodobniej chcesz zarejestrować XIB w tym celu. Gdy używasz domyślnych komórek widoku tabeli lub innej komórki programowej, rejestrujesz klasę. Na razie skorzystamy z zajęć!

Dodaj następujący kod do funkcji viewDidLoad() :

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

upewnij się, że dodałeś go poniżej linii super.viewDidLoad(). Jak zapewne wiesz, funkcja viewDidLoad() jest częścią cyklu życia kontrolera widoku i należy do klasy UIViewController.

nadpisujesz funkcję viewDidLoad(), aby reagować na to zdarzenie w cyklu życia kontrolera widoku, dzięki czemu możesz skonfigurować Widok po jego załadowaniu. W naszym przypadku używamy funkcji do rejestracji komórki widoku tabeli.

podczas rejestracji komórki widoku tabeli musisz również podać identyfikator. Jest to po prostu kojarzenie klasy komórki z nazwą, której możesz użyć później, podczas usuwania komórki w tableView(_:cellForRowAt:).

jesteś jeszcze ze mną? Ruszajmy dalej!

implementacja „numberOfSections (in:)”

pierwszą funkcją delegata, którą zamierzamy zaimplementować, jest numberOfSections(in:).

widok tabeli może mieć wiele sekcji lub grup. Każda grupa ma nagłówek, który unosi się na górze pionowego rzędu komórek. W aplikacji Kontakty można grupować kontakty Alfabetycznie. W rzeczywistości odbywa się to w aplikacji Kontakty na iPhonie, gdzie kontakty są grupowane od A do Z.

aplikacja, którą tworzymy, ma tylko jedną sekcję. Dodaj następującą funkcję do klasy:

override func numberOfSections(in tableView: UITableView) -> Int{ return 1}

proste, prawda? Funkcja zwraca 1 po wywołaniu.

implementacja „tableView(_:numberOfRowsInSection:)”

podobną funkcją jest tableView(_:numberOfRowsInSection:). Zamiast podawać liczbę sekcji, podaje liczbę wierszy w sekcji. Ponieważ widok tabeli pokazuje komórki na liście pionowej, każda komórka odpowiada wierszowi w widoku tabeli.

aplikacja, którą tworzymy, ma tylko jedną sekcję, a ta sekcja ma liczbę elementów równą liczbie elementów w tablicy contacts. Czyli contacts.count!

dodaj następującą funkcję do klasy:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return contacts.count}

widzisz, jak to działa? Po prostu zwracamy contacts.count. Jeśli miałbyś dodać inne imię i numer telefonu do contacts, to też byłoby ładnie w widoku tabeli.

zrozumienie wierszy i sekcji

nasza aplikacja kontaktów jest jednowymiarowa, pokazuje tylko jedną listę nazwisk i numerów telefonów i nie używa grup. Ale co, jeśli masz pogrupowany widok tabeli?

w większości przypadków twoje źródło danych, takie jak tablica contacts, również byłoby wielowymiarowe. Organizujesz grupy na pierwszym poziomie, a poszczególne elementy na drugim poziomie, „poniżej” grup.

- Countries - A - Afghanistan - Albania - ... - B - Bahamas - Bahrain - ... - C - Cambodia - Cameroon - ...

liczba grup jest równa countries.count, a liczba krajów w jednej grupie jest równa countries.count, gdzie x to indeks sekcji. Ten indeks sekcji jest podany jako parametr w tableView(_:numberOfRowsInSection:).

czy zauważyłeś, że te dwie funkcje mają parametr o nazwie tableView? To część zasady programowania obiektowego. Technicznie można użyć źródła danych widoku tabeli i delegować, aby dostosować wiele widoków tabeli. Używasz tableView, aby określić, z którym widokiem tabeli pracujesz.

wyobraź sobie, że masz aplikację do kontaktów, która może wyświetlać numery telefonów po imieniu lub numery telefonów zorganizowane przez firmę. Można to zaimplementować na wiele sposobów, na przykład przez ponowne użycie kontrolerów widoku tabeli. A jeśli chcesz ponownie użyć układu aplikacji Kontakty, aby wyświetlić podobne informacje, takie jak restauracje, lokale lub nazwy użytkowników Skype ’ a? Tutaj pojawia się ponowne użycie kodu z OOP!

dostarczanie komórek do kontrolera widoku tabeli

jesteśmy na miejscu! Przejdźmy do najważniejszej funkcji kontrolera widoku tabeli: tableView(_:cellForRowAt:).

zaimplementujemy tę funkcję przed zagłębianiem się w szczegóły, ale jest kilka rzeczy, które musisz zrozumieć:

  • gdy nazywa się
  • co to jest ścieżka indeksu
  • jak ponownie wykorzystuje komórki

najpierw dodaj następującą funkcję do klasy ContactsTableViewController :

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}

oto jak to działa:

  • funkcja nadpisuje swoją implementację klasy nadrzędnej z UITableViewController. Wiesz już, jak to działa, prawda? Nadpisujemy domyślną implementację i zastępujemy własną. To dlatego, że UITableViewController już zaimplementował delegat widoku tabeli i źródło danych dla nas.
  • podobnie jak poprzednio, funkcja ma jeden parametr tableView, którego możemy użyć do identyfikacji widoku tabeli, w którym ta funkcja jest wywoływana.
  • innym parametrem jest indexPath, z etykietą argumentu cellForRowAt. Ścieżka indeksu identyfikuje indeksy row i section komórki. Więcej o tym później.
  • Typ zwrotu funkcji to UITableViewCell. To interesujące. Ta funkcja jest wywoływana przez kontroler widoku tabeli, za każdym razem, gdy potrzebujemy dostarczyć komórkę widoku tabeli!

podczas przewijania kontaktów w tej aplikacji za każdym razem, gdy komórka musi być wyświetlona na ekranie, wywoływana jest funkcja tableView(_:cellForRowAt:). Za każdym razem! Zaraz ci to udowodnię.

następnie napiszmy ciało funkcji. Dodaj następujący kod wewnątrz funkcji:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)")cell.textLabel?.text = contactsreturn cell

oto co się dzieje:

  • najpierw usuwamy komórkę z identyfikatorem. To dokładnie ten sam IDENTYFIKATOR, którego użyliśmy podczas rejestracji komórki. W ten sposób Widok tabeli wie, jakiego typu komórki chcemy. Odłączona komórka jest przypisana do stałej cell. Teraz mamy komórkę widoku tabeli do pracy. Więcej o dequeuingu później.
  • następnie drukujemy pewne informacje na konsolę. To jest tak, że możemy zobaczyć, kiedy ta funkcja jest wywoływana, kiedy aplikacja działa.
  • następnie przypisujemy nazwę kontaktu do etykiety tekstowej tej komórki widoku tabeli. contacts zawiera wartość nazwy Kontaktu, do której docieramy używając indexPath.row. Każda instancja UITableViewCell ma właściwość textLabel UILabel, a każda etykieta tego typu ma właściwość text. Służy do ustawiania tekstu na etykiecie.

nie martw się, omówimy każdą z tych rzeczy bardziej szczegółowo. Najpierw sprawdź, czy możesz uruchomić aplikację. Widzisz nazwiska kontaktów? Czy widzisz wyjście debugowania w konsoli? Spróbuj przewijać aplikację!

wiersze kontrolera widoku tabeli

kiedy nazywa się „tableView(_:cellForRowAt:)”?

jeśli uruchomiłeś aplikację Kontakty i bawiłeś się przewijaniem w górę i w dół, nie możesz nie zauważyć, że za każdym razem, gdy przewijasz, dane wyjściowe debugowania pojawiają się w konsoli.

za każdym razem, gdy pojawia się komórka, która wcześniej nie była na ekranie, wywoływana jest funkcja tableView(_:cellForRowAt:) i pojawia się nowa linia w konsoli.

kiedy dzwoni tableView(_:cellForRowAt:)? Za każdym razem, gdy komórka widoku tabeli musi być wyświetlana na ekranie!

kontroler widoku tabeli określił, że komórka jest potrzebna, więc wywołuje tableView(_:cellForRowAt:). Nasza implementacja tej funkcji usuwa komórkę, zmienia ją i dostarcza z powrotem do kontrolera widoku tabeli. Kontroler widoku tabeli i framework UIKit renderują go graficznie na ekranie.

co to jest ścieżka indeksu?

za każdym razem, gdy kontroler widoku tabeli potrzebuje komórki z tableView(_:cellForRowAt:), podaje ścieżkę indeksu jako argument dla funkcji. W treści funkcji można użyć parametru indexPath, aby dokładnie wiedzieć, której komórki potrzebuje kontroler widoku tabeli.

ścieżka indeksu jest jak adres lub współrzędna w siatce. Typowy Wykres ma oś X i oś Y, więc można wyrazić współrzędną na tym wykresie jako x, y, jak 0, 1i 42, 3. Podobnie, arkusz kalkulacyjny ma wiersze i kolumny z indeksami.

widok tabeli używa sekcji i wierszy. Jak wspomniano wcześniej, możesz użyć sekcji do grupowania komórek razem. Nasza aplikacja ma tylko jedną sekcję i ma contacts.count wiersze. Wiersze widoku tabeli przebiegają od góry do dołu.

powiedział inaczej: sekcje i wiersze widoku tabeli są tym, czym kolumny i wiersze są w arkuszu kalkulacyjnym. Ścieżka indeksu definiuje lokalizację w widoku tabeli, używając wiersza i sekcji.

wiersze i sekcje są reprezentowane przez liczby, zwane indeksami. Indeksy te zaczynają się od zera, więc pierwszy wiersz i sekcja będą miały Numer indeksu 0.

kiedy spojrzysz wstecz na poprzedni zrzut ekranu, ma to o wiele większy sens. Pierwsza komórka ma ścieżkę indeksu 0, 0, druga komórka 0, 1, kontynuując do ostatniej widocznej komórki ze ścieżką indeksu 0, 11.

mechanizm ponownego wykorzystania widoku tabeli

najbardziej godny uwagi jest mechanizm ponownego wykorzystania komórek w widoku tabeli. To całkiem proste.

  • za każdym razem, gdy kontroler widoku tabeli musi pokazać komórkę na ekranie, wywoływana jest funkcja tableView(_:cellForRowAt:), jak już omówiliśmy wcześniej.
  • zamiast tworzyć nową komórkę widoku tabeli za każdym razem, gdy ta funkcja jest wywoływana, pobiera wcześniej utworzoną komórkę z kolejki.
  • komórka resetuje się do stanu pustego, usuwa jej wygląd, a komórka jest ponownie dostosowywana w tableView(_:cellForRowAt:).
  • gdy komórka jest przewijana poza ekran, nie jest niszczona. Jest dodawany do kolejki, czekając na ponowne użycie.

to całkiem sprytne, prawda? Zamiast tworzyć i usuwać komórki, po prostu używasz ich ponownie. Ale … dlaczego?

ponowne wykorzystanie komórek jest znacznie mniej intensywne. Kontroler widoku tabeli stale zapisywał do pamięci podczas tworzenia i usuwania komórek. Zarządzanie pamięcią byłoby również bardziej intensywne. Gdy komórki są ponownie używane, pamięć jest używana wydajniej i potrzeba mniej operacji na pamięci.

ponadto ITT jest nieco mniej obciążony procesorem, aby ponownie używać komórek zamiast ich tworzyć i usuwać, ponieważ po prostu jest mniej operacji związanych z ponownym użyciem w porównaniu z tworzeniem i usuwaniem komórek.

gdy szybko przewijasz widok tabeli, nie widzisz nowych komórek – widzisz te same komórki w kółko, z nowymi informacjami.

kod związany z ponownym użyciem komórki jest następujący:

let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath)

funkcja dequeueReusableCell(withIdentifier:) próbuje oddzielić komórkę. Gdy nie ma komórek w kolejce, utworzy dla nas komórkę. Identyfikator jest używany do przechowywania każdego typu komórki w ich własnej kolejce i aby upewnić się, że odpowiednia klasa jest używana do tworzenia nowych komórek.

dowiedz się, jak tworzyć aplikacje na iOS

rozpocznij pracę z iOS 14 i Swift 5

Zapisz się na mój kurs programowania na iOS i dowiedz się, jak tworzyć świetne aplikacje na iOS 14 za pomocą Swift 5 i Xcode 12.

reagowanie na interakcję z użytkownikiem

w naszym kontrolerze widoku tabeli brakuje jednej rzeczy: możliwości dzwonienia do osób z naszej listy kontaktów! Ale zanim to zrobimy, upewnijmy się, że możesz również zobaczyć numer telefonu kontaktu w kontrolerze widoku tabeli.

domyślna klasa UITableViewCell ma 4 różne typy, wyrażone w wyliczeniu UITableViewCellStyle. Możesz wybrać pomiędzy:

  • .default – prosty widok z jedną linią czarnego tekstu
  • .value1 – prosty widok z jedną linią czarnego tekstu po lewej stronie i małą niebieską etykietą po prawej stronie (używaną w aplikacji Ustawienia)
  • .value2 – prosty widok z jedną linią czarnego tekstu po prawej stronie i małą niebieską etykietą po lewej stronie (używaną w aplikacji Kontakty)
  • .subtitle – prosty widok z jedną linią czarnego tekstu i mniejszą linią szarego tekstu pod nim

większość programistów używa niestandardowych komórek widoku tabeli w dzisiejszych czasach, więc nie zobaczysz tych typów komórek tak często. Ale oni tam są!

musimy nieco dostosować kod w tableView(_:cellForRowAt:). Zastąp pierwszą linię funkcji następującym kodem:

var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier")if cell == nil{ cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier")}

jeśli przyjrzysz się bliżej, zobaczysz, że usunęliśmy część for: indexPath wywołania dequeueReusableCell(...). Zamiast tego funkcja ta zwraca teraz opcjonalne. Gdy nie może usunąć komórki, funkcja zwraca nil.

następnie wskakujemy do siebie, aby utworzyć komórkę, jeśli jest to nil. Widzisz to w drugiej części kodeksu. Aby sprawdzić, czy cell jest równe nil, należy użyć polecenia warunkowego if, a jeśli to prawda, utworzyć komórkę za pomocą inicjatora UITableViewCell(style:reuseIdentifier:).

inicjalizator otrzymuje dwa argumenty, styl komórki .subtitle i identyfikator, którego użyliśmy wcześniej.

w tym momencie mamy problem, bo cell jest teraz opcjonalne! Jego typ to UITableViewCell?, ale funkcja return type wymaga, abyśmy zwrócili instancję z nieobowiązkowym typem UITableViewCell.

na szczęście jest to jeden z tych przypadków, w których możemy bezpiecznie użyć siły rozpakowywania, aby rozpakować wartość opcjonalną. Ze względu na sposób pisania naszego kodu, cell nie może być nil poza trybem warunkowym. Możesz zagwarantować, że cell nie jest nil po instrukcji if.

upewnij się, że zaktualizowałeś funkcję, aby użyć siły rozpakowywania dla cell. Dodaj również poniższy wiersz kodu poniżej cell!.textLabel ..., aby ustawić podtytuł komórki pokaż numer telefonu kontaktu.

cell!.detailTextLabel?.text = contacts

cała funkcja wygląda teraz tak:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ var cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier") if cell == nil { cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellIdentifier") } print("\(#function) --- section = \(indexPath.section), row = \(indexPath.row)") cell!.textLabel?.text = contacts cell!.detailTextLabel?.text = contacts return cell!}

na koniec upewnij się, że usuniesz poniższą linię z viewDidLoad(). Zapobiegnie to inicjalizacji komórek niewłaściwego typu w widoku tabeli.

tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cellIdentifier")

Uruchom aplikację za pomocą polecenia + R lub przycisku Odtwórz i sprawdź, czy działa. Widzisz nazwiska i numery telefonów? Dobrze!

następnie, dla pièce-de-résistance, dodajmy tę funkcję interakcji użytkownika. Teraz, gdy nauczyłeś się zawiłości kontrolera widoku tabeli, myślę, że już wiesz, jak działa ta następna funkcja.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){ if let url = URL(string: "tel://" + contacts) { UIApplication.shared.open(url) }}

ponownie nadpisujemy domyślną implementację funkcji tableView(_:didSelectRowAt:). Funkcja ta jest wywoływana, gdy użytkownik dotknie komórki widoku tabeli i należy do protokołu UITableViewDelegate. Podobnie jak inne funkcje, zapewnia ścieżkę indeksu komórki, która jest podsłuchiwana.

w ciele funkcji po prostu tworzymy tel:// URL z numeru telefonu. Następnie powiemy aplikacji, aby otworzyła ten adres URL, co skutecznie powie iOS, aby zainicjował połączenie na ten numer. Ten kod jest tam tylko w celach poglądowych. Zauważ, że to nie działa na symulatorze iPhone ’ a, a liczby w naszej aplikacji są fałszywe. (Mimo to, można użyć tego kodu, jeśli robisz prawdziwe kontakty aplikacji!)

możesz dodać następujący kod do funkcji, jeśli chcesz sprawdzić, czy działa dobrze.

print("\(#function) --- Calling: \(contacts)")

po dotknięciu komórki widoku tabeli wyświetli się komunikat debugowania.

Czytaj dalej

i to wszystko! To była niezła podróż, ale teraz wiesz, jak działa kontroler widoku stołu.