Aktualizacja 2/16/12: Całość uaktualniona dla iOS 5.
iPhone jest niesamowitą platformą do pisania aplikacji dla niezależnych deweloperów. Jeszcze nigdy nie było tak łatwo wpaść na unikalny pomysł na aplikację, napisać ją i udostępić dla milionów potencjalnych klientów!
Ostatnio często dostaję zapytania jak zacząć programować na platformę iOS. Dlatego pomyślałem, że będzie pomocne napisanie serii przeznaczonej dla początkujących. Jednak zamiast skupiania się tylko na jednym temacie, zagłębimy się w proces tworzenia w pełni funkcjonalnej aplikacji od podstaw. Na koniec, będziesz miał wystarczającą wiedzę z wielu obszarów programowania iPhone aby poznawać te tematy dalej. Więc jaką aplikację napiszemy? No cóż, kryje się za tym pewna historia…
Pewnej nocy, zobaczyłem zdjęcie tego owada po raz pierwszy i bardzo się przestraszyłem ponieważ był wielki i obrzydliwy! Później miałem obsesję na punkcie oglądania najbardziej przerażających zdjęć owadów w internecie. Więc aby podzielić się zabawą z innymi, napiszemy aplikację do tego – oceniania najbardziej przerażających owadów!
Podczas pisania aplikacji, zapoznamy się z najczęściej stosowanymi tematami w programowaniu iPhone:
- Co potrzebujesz, żeby zacząć programować
- Jak przechowywać dane w modelu
- Jak używać Table View – włączając dodawanie i usuwanie wierszy
- Jak stworzyć widok szczegółowy dla wybranego wiersza
- Jak obsłużyć orientację poziomą oraz horyzontalną
- Jak korzystać z Navigation Controllers
- Jak korzystać z Image Picker
- Jak korzystać z kontrolek takich jak pola tekstowe, przyciski, oraz widok obrazka
- Jak dodać ikony oraz domyślne obrazy
- Bonus: Jak obsłużyć czasochłonne operacje
Lista jest bardzo przerażająca, ale nie bój się – nie boimy się żadnych owadów!
W tej części trzyczęściowej serii, poznamy jak wczytać dane listy owadów oraz wyświetlić je jako listę (table view). (Przejdź do Części drugiej lub Części trzeciej)
To jest tutorial dla początkujących programistów iOS, jednak zakładam że jesteś zaznajomiony już z językiem Objective-C i generalnie z programowaniem. Jeśli jeszcze nie znasz Objective-C, polecam zapoznanie się z dokumentacją Apple Objective-C Programming Language Guide.
Co jest potrzebne?
Najpierw – aby pisać aplikacje na iPhone, potrzebujesz Maka. Właściwie wystarczy dowolny Mak o ile jest wystarczająco mocny, aby uruchomić najnowszą wersję systemu Mac OS. Jeśli szukasz jakieś tańszej drogi, możesz wybrać Maka Mini, który również się sprawi jako maszyna dla programisty.
Następnie, potrzebujesz Xcode, jest to IDE dla iOS od Apple. Jeśli jeszcze tego nie zrobiłeś, zarejestuj darmowe konto na iPhone Dev Center oraz pobierz Xcode z Mac App Store.
Jeśli chcesz, możesz wykupić iPhone Developer Program który pozwala na publikację aplikacji w App Store, ale jeśli tylko chcesz spróbować swoich sił w programowaniu na iOS to darmowe konto w zupełności wystarczy.
Jeżeli myślisz poważnie o programowaniu na iOS, na pewno potrzebujesz również urządzenia (iPhone/iPhone 4/iPod Touch/iPad). To prawda, że możesz dużo sprawdzić tylko za pomocą Symulatora iOS, ale jest również sporo API które nie działa na Symulatorze i wtedy fizyczne urządzenie jest potrzebne. To tyle – jeśli jeszcze nie uruchomiłeś Xcode, zrób to teraz i idźmy dalej!
Witaj, Table View!
Zaczniemy od wykorzystania najczęściej stosowanej kontrolki na iPhone – widoku tabeli (Table View). Na pewno widziałeś Table View w wielu innych aplikacjach, a oto przykłady:

Wiec, nasz pierwszy ekran aplikacji będzie korzystał z tabeli aby wyświetlić listę owadów!
Zacznijmy od wybrania opcji FileNew Project w Xcode, następnie wybierz iOSApplicationMaster-Detail Application, oraz kliknij Next.

Na następnej stronie, wpisz ScaryBugs jako Product Name, wpisz unikalny indentyfikator twojej firmy (com.yourcompanyname lub com.yourname jest najlepszy), wybierz iPhone jako device family, oraz upewnij się, że opcje Use Storyboard oraz Use Automatic Reference Counting są zaznaczone. Kliknij Next kiedy będziesz gotowy.

Wybierz miejsce gdzie chcesz zapisać projekt i kliknij Create. I zanim zrobisz cokolwiek innego, sprawdźmy gdzie doszliśmy do tej pory! W Xcode w pasku narzędzi wybierz iPhone Simulator z listy i kliknij przycisk Run. Jeśli wszystko pójdzie dobrze, powinineś zobaczyć Symulator:

Możesz kliknąć przycik “+” (znak plus) aby stworzyć nowy wpis, a następnie kliknąć w nowoutworzony wiersz aby zobaczyć widok szczegółówy:

Jak widzisz, już mamy działający projekt od którego możemy zacząć po wybracji szablonu Master-Detail Application.
Zauważ, że masz dostępną pustą Table View oraz Widok Szczegółowy (detail view) ustawiony i gotowy do akcji – musimy go tylko wypełnić odpowiednimi danymi!
Aby to zrobić, stwórzmy nową klasę, przechowującą informację o naszych przerażających owadach.
Scary Data Model
Zauważ strukturę folderów w sekcji Project Navigator Xcode:

Szablon ma nadrzędną grupę (root group) oraz grupę Supporting Files. Te grupy służą wyłącznie do celu lepszej organizacji, więc możesz je ustawić tak jak sobie chcesz. W naszym przypadku, będziemy mieć trochę plików, więc zorganizujmy je trochę.
Po pierwsze, stwórz nową grupę, która będzie przechowywać pliku interfejsu (User Interface files). Aby to zrobić, kliknij przytrzymując ctrl w grupie Scary Bugs i wybierz opcję New Group. Następnie kliknij ponownie z ctrl na nowoutworzonej grupie wybierz opcję “Rename” i nazwij grupę “GUI”. Przeciągnij pliki z nadrzędnej grupy do grupy GUI (z pominięciem plików z Supporting Files). Oto jak powinna wyglądać nasza struktura plików i grup:

Teraz utwórz kolejną grupę i nawij ją “Model”, ponieważ dodamy kilka nowych klas. Struktura teraz powinna wyglądać tak:

Zanim zaczniemy, omówimy jak chcemy rozwiązać sposób przechowywania informacji:
- ScaryBugData: Zawiera nazwę owada oraz jego ocenę.
- ScaryBugDoc: Zawiera pełnowymiarowy obraz, miniaturkę oraz ScaryBugData.
Dlatego tak organizujemy dane, aby łatwiej było zrozumieć ten tutorial gdzie będziemy zapisywać dane na dysk, zaimplementujemy współdzielenie plików, itd.
A Scary Data Model: Implementacja
Ok, do dzieła! Kliknij przytrzymując Control na Modelu grupy i wybierz “New File…”. Następnie wybierz iOSCocoa TouchObjective-C class template, oraz kliknij Next.

Nazwij klasę ScaryBugData, wprowadź NSObject jako subklasę, i kliknij Next.

W ostatnim oknie kliknij Create. Jeśli wszystko poszło dobrze, w panelu nawigacji zobaczyć widok podobny do poniższego:

Ok, czas stworzyć klasę ScaryBugData. Podmień zawartość pliku ScaryBugData.h na poniższy kod:
#import <Foundation/Foundation.h> @interface ScaryBugData : NSObject @property (strong) NSString *title; @property (assign) float rating; - (id)initWithTitle:(NSString*)title rating:(float)rating; @end |
To jest proste – deklarujemy obiekt z dwoma własnościami – string dla nazwy owada, oraz float przechowującej informację o tym jak bardzo się go boimy. Korzystamy tutaj z dwóch atrybutów dla nich:
- strong: Określa fakt, aby przechowywać “strong reference” do obiektu. Znaczy to, że środowisko uruchomieniowe za pomocą ARC będzie przechowywać obiekt w pamięci tak długo jak tylko istnieje referencja do niego, oraz dealokuje go, gdy nie będzie już żadnych referencji. Więcej informacji znajdziesz w tutorialu: Wprowadzenie do ARC w iOS 5.
- assign: To znaczy, że własność jest ustawiania bezpośrednio. To jest atrybut ustawiony dla typów prostych (a nie obiektów) takich jak float.
Również zdefinujemy niestandardowy initializer dla klasy, a więc będziemy mogli podać tytuł oraz rating gdy tworzymy obiekt.
Przełącz się do pliku ScaryBugData.m i zamień go na poniższy:
#import "ScaryBugData.h" @implementation ScaryBugData @synthesize title = _title; @synthesize rating = _rating; - (id)initWithTitle:(NSString*)title rating:(float)rating { if ((self = [super init])) { self.title = title; self.rating = rating; } return self; } @end |
Ponownie, bardzo prosty kod. Korzystamy ze słowa kluczoego synthesize, oraz pozwalamy naszej metodzie inicjalizującej uzupełnić wartości tych zmiennych. Zauważ, że nie musimy definiować metody dealloc, skoro używamy ARC.
Ok, to tyle jeśli chodzi o ScaryBugData. Teraz wykonaj te same kroki co wcześniej aby utworzyć kolejną subklasę NSObject tym razem o nazwie ScaryBugDoc.
Zamień zawartość pliku ScaryBugDoc.h na poniższy kod:
#import <Foundation/Foundation.h> @class ScaryBugData; @interface ScaryBugDoc : NSObject @property (strong) ScaryBugData *data; @property (strong) UIImage *thumbImage; @property (strong) UIImage *fullImage; - (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(UIImage *)thumbImage fullImage:(UIImage *)fullImage; @end |
Zauważ nic specjalnego tutaj – tylko stworzenie kilku własności oraz zdefiniowanie metody niestandarowego inicjalizera.
Zamień zawartość pliku ScaryBugDoc.m na poniższy kod:
#import "ScaryBugDoc.h" #import "ScaryBugData.h" @implementation ScaryBugDoc @synthesize data = _data; @synthesize thumbImage = _thumbImage; @synthesize fullImage = _fullImage; - (id)initWithTitle:(NSString*)title rating:(float)rating thumbImage:(UIImage *)thumbImage fullImage:(UIImage *)fullImage { if ((self = [super init])) { self.data = [[ScaryBugData alloc] initWithTitle:title rating:rating]; self.thumbImage = thumbImage; self.fullImage = fullImage; } return self; } @end |
I to tyle – nasz model danych jest gotowy! Czas stworzyć przykładowe dane i wyświetlić je za pomocą tabeli.
A Different Kind of Bug List
Po pierwsze, ustawimy kontrolkę tabele view aby mógła ona wyświetlać listę ScaryBugDocs. Najpierw musimy zmienić jej opcje, aby zwracała dynamiczną liczbę wierszy.
Aby to zrobić otwórz MainStoryboard.storyboard. W tym pliku Xcode pozwala Ci wizualnie projektować layout poszczególnych widoków twojej aplikacji. Jak widzisz, aplikacje posiada kontroler nawigacji (pozwala on na łatwe przemieszczanie się między różnymi widokami), z głównym kontrolerem “master”, oraz z drugim kontrolerem “detail”.

Zaznacz Master View Controller i z panelu z lewej strony wybierz table view. W inspektorze z prawej upewnij się, że atrybut Content jest ustawiony Dynamic Prototypes.

To pozwala utworzyć pojedyńczy wiersz według twojego uznania w pliku Storyboard i w łatwy sposób utworzyć jej instancje z poziomu kodu. Potrzebujemy prostej komórki, więc upewnijmy się że jej wybrany styl jest ustawiony na Basic style.
Wybierz table view cell z lewej, i w Attributes Inspector upewnij się że Style jest ustawiony na Basic. Ustaw też Identifier na MyBasicCell.

Więcej informacji na temat własnych i niestandardowych komórek znajdziesz w tutorialu: Wprowadzenie do Storyboards w iOS 5.
OK, teraz ustawiliśmy poprawnie table view, ale jeszcze musimy uzupełnić z poziomu kodu jej zawartość (listę przerażających owadów!).
Dane ScaryBugDocs przechowywane są w NSMutableArray w kolekcji, która umożliwia dynamiczną zmianę jej rozmiaru.
Dodaj poniższy kod do pliku MasterViewController.h, pomiędzy liniami zawierającymi @interface oraz @end:
@property (strong) NSMutableArray *bugs; |
To będzie nasza zmienna, która będzie przechowywać listę owadów.
Przejdź do pliku MasterViewController.m i wykonaj poniższe zmiany:
// Na początku pliku #import "ScaryBugDoc.h" #import "ScaryBugData.h" // zaraz pod słowem @implementation @synthesize bugs = _bugs; // na końcu metody viewDidLoad self.title = @"Scary Bugs"; // zamień return w metodzie shouldAutorotateToInterfaceOrientation na: return YES; // Zamień return w metodzie tableView:numberOfRowsInSection na: return _bugs.count; // Replace tableView:cellForRowAtIndexPath with the following - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyBasicCell"]; ScaryBugDoc *bug = [self.bugs objectAtIndex:indexPath.row]; cell.textLabel.text = bug.data.title; cell.imageView.image = bug.thumbImage; return cell; } |
Ok, w końcu mamy coś interesującego do dyskusji!
Po pierwsze, zauważ, że ustawiliśmy property “title” na string “Scary Bugs.” “title” jest specjalną własnością dla kontrolerów widoku. Kiedy Kontroler nawigacji wyświetla kontroler, wyświetla właśność title na pasku nawigacji.
Następnie, zauważ, że zwracamy wartość yes w metodzie shouldAutorotateToInterfaceOrientation, która mówi OS, że chcemy wspierać wszystkie możliwości orientacji urządzenia – pionowo, poziomo oraz do góry nogami. Odkąd używamy klasy UITableViewController, nie musimy się niczym innym martwić!
Następnie, tworząc table view z dynamicznymi wartościami musimy nadpisać metodę numberOfSectionsInTableView oraz numberOfRowsInSection która mówi ile sekcji oraz wierszy (w każdej z sekcji) powinno być wyświetlonych w table view. W naszym przypadku mamy tylko jedną sekcję, więc nie musimy nic zmieniać powieważ w wybranym szablonie jest to domyślne zachowanie. A dla liczby wierszy zwracamy liczbę obiektów w naszej tablicy.
Na końcu, uzupełniamy metodę tableView:cellForRowAtIndexPath, która jest prawdopodobnie najważniejsza, gdy mówimy o table view. Ta metoda jest wywoływana dla każdego wiersza i każdy z nich może mieć inną zawartość.
Let’s take a look this method in detail, since this is particularly important:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyBasicCell"]; ScaryBugDoc *bug = [self.bugs objectAtIndex:indexPath.row]; cell.textLabel.text = bug.data.title; cell.imageView.image = bug.thumbImage; return cell; } |
Pierwsza linia wywołuje pomocniszą funkcję o nazwie “dequeueReusableCellWithIdentifier” aby zwróciła wiersz do ponownego wykorzystania. O co tutaj chodzi?
Cóż, jest to bardzo ważne zagadnienie związane z optymalizacją. Miej na uwadze, że tabele mogą zawierać bardzo duże liczby wierszy, ale tylko kilka z nich faktycznie jest wyświetlanych na ekranie. Zamiast tworzyć dla każdej z nich nową komórkę OS potrafi zwiększyć wydajność przez ponowne wykorzystanie komórek, które zostały już wcześniej utworzone, ale zostały przesunięte poza ekran.
Dlatego wywołujemy dequeueReusableCellWithIdentifier. Jeśli nie ma żadnej komórki, którą moglibyśmy wykorzystać, musimy po prostu taką utworzyć, np. na bazie Interface Buildera (pamiętasz jak ustawiliśmy style komórki na basic, a jej identyfikator na “MyBasicCell”?).
W pliku Storyboard możesz dowolnie utworzyć zawartość komórki, lub wykorzystać jedną z przygotowanych przez Apple. W naszym wypadku, wybraliśmy styl basic, który składa się z etykiety oraz z obrazka, który możesz ustawić.
Jeśli jesteś ciekawy, jak wyglądają te standardowe komórki, sprawdź sekcję “Standard Styles for Table-View Cells” w dokumentacji Table View Programming Guide.
Na końcu, ustawiamy dane komórki za pomocą własności textLabel oraz imageView (które są dostępne w stylu Basic).
Uwierz bądź nie, ale to wszystko co potrzebujemy! Teraz potrzebujemy trochę przykładowych danych!
Scary Bug Pictures!
Oczywiście, potrzebujemy obrazków tych przerażających owadów! Możesz przeglądać internet w ich poszukiwaniu, lub pobrać te Przerażające obrazki owadów, które znalazłem na stock.xchng.
Jak już je pobrałeś lub zebrałeś własny zestaw, przeciągnij je wszystkie do głównej grupy w Nawigatorze Projektu. Gdy pojawi się okienko, wybierz opcję “Copy items into destination group’s folder (if needed)” i kliknij Add.

Teraz otwórz plik AppDelegate.m i wykonaj następujące zmiany:
// Na początku pliku #import "MasterViewController.h" #import "ScaryBugDoc.h" // na początku metody application:didFinishLaunchingWithOptions ScaryBugDoc *bug1 = [[ScaryBugDoc alloc] initWithTitle:@"Potato Bug" rating:4 thumbImage:[UIImage imageNamed:@"potatoBugThumb.jpg"] fullImage:[UIImage imageNamed:@"potatoBug.jpg"]]; ScaryBugDoc *bug2 = [[ScaryBugDoc alloc] initWithTitle:@"House Centipede" rating:3 thumbImage:[UIImage imageNamed:@"centipedeThumb.jpg"] fullImage:[UIImage imageNamed:@"centipede.jpg"]]; ScaryBugDoc *bug3 = [[ScaryBugDoc alloc] initWithTitle:@"Wolf Spider" rating:5 thumbImage:[UIImage imageNamed:@"wolfSpiderThumb.jpg"] fullImage:[UIImage imageNamed:@"wolfSpider.jpg"]]; ScaryBugDoc *bug4 = [[ScaryBugDoc alloc] initWithTitle:@"Lady Bug" rating:1 thumbImage:[UIImage imageNamed:@"ladybugThumb.jpg"] fullImage:[UIImage imageNamed:@"ladybug.jpg"]]; NSMutableArray *bugs = [NSMutableArray arrayWithObjects:bug1, bug2, bug3, bug4, nil]; UINavigationController * navController = (UINavigationController *) self.window.rootViewController; MasterViewController * masterController = [navController.viewControllers objectAtIndex:0]; masterController.bugs = bugs; |
Tutaj wykorzystaliśmy metodę inicjalizującą ScaryBugDoc do stworzenia czterech przykładowych owadów, przekazująć nazwę (title), rating, oraz obrazki dla każdego z nich. Dodajemy je wszystkie do NSMutableArray, i ustawiamy table view.
I to wszystko! Skompiluj i uruchom aplikację, i jeśli wszystko działa należycie, powinieneś zobaczyć listę (prawdopodobnie) najbardziej przerażających owadów!

Co dalej?
Tutaj znajduje się przykładowy projekt, który zawiera cały dotychcasowy kod. Proszę poinformuj mnie, jeśli jakieś informacje są niejasne lub potrzebne jest bardziej dokładny opis. W nastepnej cześci serii, przedstawię jak utworzyć ekran z dodatkowymi informacjami abyśmy mogli je edytować oraz oceniać!
polski
简体中文
English
Français
日本語
Русский
Español
العربية
हिन्दी
Magyar
Indonesia
한국어
Português
Română
Türkçe 














