13 May 2013

Jak stworzyć prostą aplikację dla iPhone iOS 5: Część 1/3

iPhone programming is like a ladybug - fun and only a little scary!

iPhone programming is like a ladybug – fun and only a little scary!

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:

UITableView Examples
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.
Creating an app with the master detail application template
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.
Project Settings for scary bugs app
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:
The main screen created by the master detail template
Możesz kliknąć przycik “+” (znak plus) aby stworzyć nowy wpis, a następnie kliknąć w nowoutworzony wiersz aby zobaczyć widok szczegółówy:
Detail view created by master detail application template
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:
The project navigator in 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:
Organizing Project Navigator tree, part 1
Teraz utwórz kolejną grupę i nawij ją “Model”, ponieważ dodamy kilka nowych klas. Struktura teraz powinna wyglądać tak:
Creating a group for the model
Zanim zaczniemy, omówimy jak chcemy rozwiązać sposób przechowywania informacji:

  1. ScaryBugData: Zawiera nazwę owada oraz jego ocenę.
  2. 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.
Creating a file with the Objective-C class template
Nazwij klasę ScaryBugData, wprowadź NSObject jako subklasę, i kliknij Next.
Creating a class that derives from NSObject in Xcode
W ostatnim oknie kliknij Create. Jeśli wszystko poszło dobrze, w panelu nawigacji zobaczyć widok podobny do poniższego:
Project organization, part 3
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”.
Main Storyboard layout
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.
Setting table view to use dynamic prototype cells
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.
Setting cell style and reuse identifier
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.
Adding scary bugs files to project
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!
Scary Bugs Table View

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ć!

Tagi: , , ,

10 May 2013

iPad dla delweloperów iPhone’a 101 w iOS 6: Tutorial korzystania z Custom Input View.

You’ll be making a Custom Input View that looks like this.

Ostatnia aktualizacja 3/7/2013: Pełna aktualizacja iOS 6 (autorem artykułu jest Ray Wenderlich, zaktualizowany przez Ellen Shapiro).
Jest to druga część, trzy częściowej serii pomagającej deweloporom iPhone’a w programowania na urządzenie iPad poprzez zwrócenie uwagi na trzy popularne klasy : UISplitView, UIPopoverController i Custom Input Views.

pierwszej części, zrobiliśmy aplikację bazującą na kontrolerze UISplitViewController, która wyświetlała listę potworków w lewym panelu, a szczegóły wybranego stworka w jego prawej części.

drugiej części, dodaliśmy widok Popover’a, aby za jego pomocą móc zmieniać kolor etykiety wyświetlającej nazwę potworka.

W tej części, zamierzamy dodać widok wyboru (lub klawiature) aby móc wybrać nową broń dla każdego z naszych potworków.

Zaczniemy od miejsca w którym skończyliśmy część drugą, dlatego też jeżeli nie masz do tej pory pełnego projektu, możesz go pobrać_tutaj.

Zanim zaczniemy: Szybka refaktoryzacja kodu

W tym tutorialu użyjemy właściwości broni naszego stworka do wielu więcej rzeczy, a niżeli było to na początku zaplanowane. Dlatego też swtorzymy dla niego osobną klasę.

Nigdy nie bój się refaktoryzacji swojego kodu ,a w szczególności gdy coś było na początku na prawdę małym obiektem, a w końcowej fazie przerodziło się to w naprawdę spory obiekt – na początku może to być trochę problematyczne, lecz w rezultacie Twój kod stanie się czytelniejszy, bardziej zrozumiały i łatwiejszy do utrzymania.

Aby zacząć przejdźmy do  File>New>File i wybierzmy szablon  iOS>CocoaTouch>Objective-C class. Klasę nazwijmy Weapon, dziediczącą z  NSObject, kliknij  Next, a następnie Create. Pierwsze co musimy zrobić to poprzenosić kilka rzeczy z pliku Monster (zawierającego dane o naszych potworkach), do nowostworzonego pliku Weapon. Przeniesiemy typ wyliczeniowy enum obecnie nazwany jako Weapon do pliku Weapon.h i zmieńmy nazwę na WeaponType w celu uchronienie się przęd błędami kompliacji. Stworzymy także właściwość do przechowywania rodzaju broni WeaponType.

Następnie przenieśmy deklarację metody  weaponImage do pliku  Weapon.h, a jej implementację do Weapon.m i oczywiście poprawmy ją używając już tym razem właściwości WeaponType zamaist poprzedniej: czyli właściwości Weapon, która była zawarta w pliku Monster.h. Ostatecznie, dodamy prostą metodę do tworzenia nowej broni dla naszego potworka.

Aby to wszystko zrobić, zastąp plik Weapon.h następującym kodem:

#import <Foundation/Foundation.h>
typedef enum {
    Blowgun = 0,
    NinjaStar,
    Fire,
    Sword,
    Smoke,
} WeaponType;
@interface Weapon : NSObject
@property (nonatomic, assign) WeaponType weaponType;
//Metoda tworzaca nowy obiekt broni z odpowiednim typem.
+(Weapon *)newWeaponOfType:(WeaponType)weaponType;
//Metoda zwracajaca obiekt UIImage reprezentujacy bron.
-(UIImage *)weaponImage;
@end

Zastąp zawartość Weapon.m następującym kodem:

#import "Weapon.h"
@implementation Weapon
+(Weapon *)newWeaponOfType:(WeaponType)weaponType
{
    Weapon *weapon = [[Weapon alloc] init];
    weapon.weaponType = weaponType;
 
    return weapon;
}
-(UIImage *)weaponImage
{
    switch (self.weaponType) {
        case Blowgun:
            return [UIImage imageNamed:@"blowgun.png"];
            break;
        case Fire:
            return [UIImage imageNamed:@"fire.png"];
            break;
        case NinjaStar:
            return [UIImage imageNamed:@"ninjastar.png"];
            break;
        case Smoke:
            return [UIImage imageNamed:@"smoke.png"];
            break;
        case Sword:
            return [UIImage imageNamed:@"sword.png"];
        default:
            //Cokolwiek co nie zostalo zdefiniowane w typie wyliczeniowym enum.
            return nil;
            break;
    }
}
@end

Należy także zaktualizować plik Monster.h, ponieważ część tej klasy została przeniesiona do klasy Weapon:

#import <Foundation/Foundation.h>
@class Weapon;
@interface Monster : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) NSString *iconName;
@property (nonatomic, strong) Weapon *weapon;
//Metoda zwracajaca nowego potworka(ang. factory method)
+(Monster *)newMonsterWithName:(NSString *)name description:(NSString *)description 
    iconName:(NSString *)iconName weapon:(Weapon *)weapon;
@end

Zaktualizujmy także Monster.m :

#import "Monster.h"
#import "Weapon.h"
@implementation Monster
 
+(Monster *)newMonsterWithName:(NSString *)name description:(NSString *)description 
    iconName:(NSString *)iconName weapon:(Weapon *)weapon
{
    Monster *monster = [[Monster alloc] init];
    monster.name = name;
    monster.description = description;
    monster.iconName = iconName;
    monster.weapon = weapon;
 
    return monster;
}
 
@end

A także dodaj import do pliku LeftViewController.m:

#import "Weapon.h"

Zaktualizujmy część metody initWithCoder: dodając obiekty Monster do tablicy i prz tym skorzystamy z obiektu Weapon: 

//Stworz obiekty Monster i dodoaj je do tablicy
[_monsters addObject:[Monster newMonsterWithName:@"Cat-Bot" description:@"MEE-OW"
    iconName:@"meetcatbot.png" weapon:[Weapon newWeaponOfType:Sword]]];
[_monsters addObject:[Monster newMonsterWithName:@"Dog-Bot" description:@"BOW-WOW" 
    iconName:@"meetdogbot.png" weapon:[Weapon newWeaponOfType:Blowgun]]];
[_monsters addObject:[Monster newMonsterWithName:@"Explode-Bot" description:@"Tick, tick, BOOM!" 
    iconName:@"meetexplodebot.png" weapon:[Weapon newWeaponOfType:Smoke]]];
[_monsters addObject:[Monster newMonsterWithName:@"Fire-Bot" description:@"Will Make You Steamed" 
    iconName:@"meetfirebot.png" weapon:[Weapon newWeaponOfType:NinjaStar]]];
[_monsters addObject:[Monster newMonsterWithName:@"Ice-Bot" description:@"Has A Chilling Effect" 
    iconName:@"meeticebot.png" weapon:[Weapon newWeaponOfType:Fire]]];
[_monsters addObject:[Monster newMonsterWithName:@"Mini-Tomato-Bot" description:@"Extremely Handsome" 
    iconName:@"meetminitomatobot.png" weapon:[Weapon newWeaponOfType:NinjaStar]]];

Ostatecznie w pliku RightViewController.m, dodaj import na początku pliku:

#import "Weapon.h"

I zaktualizuj inicjajcje obrazka dla właściwości WeaponImageView:

_weaponImageView.image = [_monster.weapon weaponImage];

Uruchom aplikacje – wszystko powinno wyglądać identycznie tak jak wcześniej, z małymi różnicami wewnątrz kodu, co sprawia, że teraz możemy zaimplementować własne widoki, do wyboru broni dla każdego z potwtorków.

Custom Input View – Wprowadzenie

Aby wyświetlić custom input view, to wszystko będzie zależeć od tego czy używasz elementu UITextView, UITextField, czy może czegoś jeszcze innego.
Jeżeli użuwasz UITextView czy UITextField, masz szczęście . Wszystko co musisz zrobić to zwrócić custom view dla właściwości “inputView”.
Jednakże jeżeli używasz czegoś innego  (jak w tym wypadku np. UIImageView), będziesz musiał stworzyć podklasę dla swojego widoku i w ten sposób będziesz mógł nadpisać getter i setter dla właściwości inutView.
w tym wypadku będziesz musiał napisać dwie nowe klasy: zmodyfikowany UIImageView, oraz kontroler widoku dla Twojego zmodyfikowanego widoku. Zacznijmy od tworzenia kontrolera widoku.

Tworzenie Kontrolera wyboru (ang. Custom Input View Controller)

Przejdź do File>New>File… i wybierz szablon iOSCocoaTouchObjective-C class. Nazwij klasę jako WeaponInputViewController, a jako klasę nadrzędną podaj UIViewController. Zaznacz dwa checkboxy: Targeted for iPad i With XIB for user interface. Ponieważ ten widok nie będzie częścią hierarchii nawigacyjnej, będzie odpowiedzialny za swój własny plik .xib, zamiast przypisywania odpowiedzialności do pliku Storyboard. Kliknij Next ,a następnie Create.

Otwórz WeaponInputViewController.xib. Domyślnie ten widok powinien mieć rozmiar iPad’owego ekranu, ale my będziemy potrzebowaliu czegoś o znacznie mniejszej wysokości . W sekcji Simulated Metrics w inspektorze atrybutów (ang. Attributes Inspector),ustaw zmienną Size na “None”  pozwoli to Tobie zmieniać rozmiar widoku, a także ustaw zmienną Status Bar na “None” aby usunąć  element: status bar.
Teraz poprzez manulane zmniejszenie widoku, bądź poprzez wykoprzystanie inspektora rozmiaru (ang. Size Inspector ),ustaw szerokość widoku na 768, a wysokość na 110.
Stwórz 5 przycisków o rozmiarze 70×70, usuwająć przy tym ich tytyły, a na samym końcu stwórz przycisk z tytułem “Close”:

Creating the Custom Input View, Part 1
Dla rzeczy związanych z auto-layout’em, powinieneś  przypiąć (ang. pin) pierwszy przycisk z lewej do lewej i górnej krawędzi widoku nadrzędnego ,następnie dla każdego dużego przycisku przypnij wyrównanie do górnej krawędzi widoku nadrzędnego. Powinieneś także  przypiąć na stałe szerokość i wysokość każdego z kwadratowych przycisków. Następnie przypnij  wartość “vertical centers” dużych przycisków do wartości “vertical center” małego przycisku,w ten sposób mały przycisk będzie na wysokości środka pozostałych przycisków.

Kiedy skończysz robić wszystkie rzeczy związane z AutoLayout, zmień tło głównego okna widoku na “Light Gray Color”, aby trochę się wyróżniało. Potem zmień typ każdego przycisku z “Rounded Rect” na “Custom” i ustaw dla każdego z nich obrazek przedstawiający broń tak jak przedstawia to poniższy rysunek:
Creating a Custom Input View, Part 2
Teraz zajmijmy się definicją klasy. Zastąp zawartość WeaponInputViewController.h następującym kodem:

#import <UIKit/UIKit.h>
#import "Weapon.h" //Dostarcza dostęp do typu wyliczeniowego WeaponType.
@protocol WeaponInputDelegate 
@required
-(void)selectedWeaponType:(WeaponType)weaponType;
-(void)closeTapped;
@end
@interface WeaponInputViewController : UIViewController
@property (nonatomic, weak) IBOutlet UIButton *blowgunButton;
@property (nonatomic, weak) IBOutlet UIButton *fireButton;
@property (nonatomic, weak) IBOutlet UIButton *ninjaStarButton;
@property (nonatomic, weak) IBOutlet UIButton *smokeButton;
@property (nonatomic, weak) IBOutlet UIButton *swordButton;
@property (nonatomic, weak) id delegate;
-(IBAction)weaponButtonTapped:(UIButton *)sender;
-(IBAction)closeTapped;
@end

Wszystko to powinno wyglądać już znajomo – ustawiłeś protokół, więc możesz informować obserwatora, gdy dany typ broni zostaje wybrany (lub w przypadlu naciśnięcia przycisku close), zostały wprowadzone także właściwości dla każdej broni z osobna oraz metoda IBAction, która jest przeznaczona dla klażdego z przycisków (parametr sender tej metody będzie przechwytywał który dokładnie przycisk został przyciśnięty) i na końcu znów metoda  IBAction, która będzie jedynie służyła przyciskowi “Close”.

Skupmy się na razie na metodach akcji. Wróćmy do pliku WeaponInputViewController.xib i kliknijmy na  “File’s Owner” przetrzumując przycisk “control” aby otworzyć listę outletów i akcji. Na początek połącz każdy IBOutlet broni z odpowiednim przyciskiem.

Następnie, przeciągnij i połącz każdy przycisk z bronią z metodą  weaponButtonTapped. Także połącz przycisk “Close” z  metodą closeTapped. Kiedy skończysz powinieneś mieć 5 przycisków połączonych z metodą  weaponButtonTapped: i jeden z metodą closeTapped jak przedstawia to poniższy rysunek:

IBAction hooked up to multiple UIButtons
Następnie w pliku WeaponInputViewController.m umieść implementacje metod:

#pragma mark - IBActions
-(IBAction)closeTapped
{
    //Powiadom delegata jeżeli istnieje.
    if (_delegate != nil) {
        [_delegate closeTapped];
    }
}
-(IBAction)weaponButtonTapped:(UIButton *)sender
{
    //Stworz zmienna do przechowywania rodzaju broni.
    WeaponType selectedWeaponType;
 
    //Ustaw wybrana bron w zaleznosci od przycisnietego przycisku.
    if (sender == _blowgunButton) {
        selectedWeaponType = Blowgun;
    } else if (sender == _fireButton) {
        selectedWeaponType = Fire;
    } else if (sender == _ninjaStarButton) {
        selectedWeaponType = NinjaStar;
    } else if (sender == _smokeButton) {
        selectedWeaponType = Smoke;
    } else if (sender == _swordButton) {
        selectedWeaponType = Sword;
    } else {
        NSLog(@"Oops! Unhandled button click.");
    }
 
    //Powiadom delegata o wyborze, jezeli istnieje.
    if (_delegate != nil) {
        [_delegate selectedWeaponType:selectedWeaponType];
    }
}

Jak sam widzisz, nic nadzwyczajnego się tutaj nie dzieje. Wszystko co robisz to informaowanie delegata,w momencie gdy jakis przycisk został naciśnięty. Obecny ViewController nie ma informacji, że ten widok jest aktualnie używany jako  custom input controller – musisz go o tym poinformować.

Custom View oraz Custom Input Controller

Aby Twoja aplikacja zaczęła działać wedle określonego celu, powinna w momencie naciśnięcia na obrazek z broną wyświetlić widok kontrolera, który właśnie zrobiliśmy. Dlatego tak jak ustaliliśmy wcześniej musisz stworzyć klasę dziedziczącą z  UIImageView aby móc zwrócić widok z opcją wyboru .

Musisz zatem zrobić klilka rzeczy dla widoku obrazu (ang. Image view) . Domyślnie, UIImageViews nie akceptuje żadnych zdarzeń na nim wywyłanych, a także na nie nie odpowiada, dlatego musisz umożliwić tego typu obsługę. Pora się tym zająć.

Przejdź do File>New>File… i wybierz szablon  iOS>Cocoa Touch>Objective-C class. Klasę nazwij WeaponSelectorImageView, niech będzie to podklasa dla UIImageView, kliknij Next, a następnie Create.
Plik WeaponSelectorImageView.h zaktualizuj poniższym kodem:

#import <UIKit/UIKit.h>
#import "WeaponInputViewController.h" //Has Input delegate as well.
@class Weapon;
@protocol WeaponSelectorDelegate 
-(void)selectedWeapon:(Weapon *)weapon;
@end
@interface WeaponSelectorImageView : UIImageView 
@property (nonatomic, strong) Weapon *weapon;
@property (nonatomic, strong) WeaponInputViewController *weaponInputController;
@property (nonatomic, strong) IBOutlet id delegate;
@end

Wyjaśnijmy parę rzeczy. Po piwerwsze tworzysz delegata, w ten sposób możesz informować obserwatora w momencie gdy następuje zmiana broni. Musimy takżę otrzymywać infrmacje o rodzaju broni (WeaponType), których użytkownik chce użyć, ale także musimy informować obiekt jakiego rodzaju obiekt broni chcesz użyć.

Następnie deklarujesz tę klasę jako WeaponInputControllerDelegate, ponieważ będziemy chcieli wiedzieć, w którym momencie użytkownik wybierze przycisk w widoku wyboru. Przechowujesz wybraną broń oraz wskaźnik na WeaponSelectorDelegate aby informować kiedy się zmienia. Delegat oznaczony jest jako IBOutlet, dlatego też możesz przypisać go z poziomu Interface Builder.

Otwórz WeaponSelectorImageView.m a następnie dodaj poniższy kod.  Zacznijmy od nadpisania setter’a, aby ustawiać odpowiedni obrazek w zależności od wyboru broni:

#import "WeaponSelectorImageView.h"
#import "Weapon.h"
@implementation WeaponSelectorImageView
#pragma mark - Nadpisany setter
-(void)setWeapon:(Weapon *)weapon
{
    //First make sure you're actually changing the weapon
    if (_weapon != weapon) {
        _weapon = weapon;
 
        //Update your image to use the weapon's image.
        self.image = [_weapon weaponImage];
    }
}

Metoda ta będzie wywyoływana w dwóch wypadkach, kiedy broń jest ustwawiana w metodzie refreshUI pliku RightViewController.m oraz kiedy broń jest ustwaiana w metodzie delegata, którą zaimplementujemy za chwilę.

Następnie nadpiszesz kilka metod nadklasy UIResponder aby umożliwić pokazanie widoku wyboru broni.:

#pragma mark - nadpisanie metod nadklasy
-(BOOL)canBecomeFirstResponder
{
    //Mowi, ze ten widok moze pokazac nasz widok wyboru.
    return YES;
}
-(UIView *)inputView
{
    //Upewnij sie, ze weaponInputController isnieje, a jezeli nie stworz go.
    if (_weaponInputController == nil) {
        _weaponInputController = [[WeaponInputViewController alloc] initWithNibName:nil bundle:nil];
        _weaponInputController.delegate = self;
    }
 
    //Return the WeaponInputController's view as the input view.
    return _weaponInputController.view;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //Pokaz widok wybory w momencie gdy klikniecia na imageView, 
	//jezeli w tym momencie jest nie widoczny.
    if (![self isFirstResponder]) {
        [self becomeFirstResponder];
    }
}

Metoda inputView jest najważniejsza – mówi systemowi, który widok powinien zostać użyty jako skastomizowany widok wyboru w momencie kiedy będzie odpowiadał jako firstResponder. Mechanizm jest prosty, mówimy , “ Zamiast pokazywać klawiaturę, kiedy zostaję  first responder’em, użyj tego widoku, który stworzyłem.”
Większość widoków typu inputViews dostarczone przez Apple to po prostu klawaitury , ale możesz zwrócić dowolny widok jaki chcesz przez nadpisanie tej metody, pośrednich lub bezpośrednich podklas UIResponder .

Szczegóły techniczne można znaleźć w dokumentacji Apple Custom Views for Data Input.
Ostatecznie, implementujemy metody WeaponInputDelegate, aby obsłyżyć wybór broni oraz naciśięcie przycisku close:

#pragma mark - metody delegata WeaponInputDelegate
-(void)closeTapped
{
    //schowaj input view.
    [self resignFirstResponder];
}
-(void)selectedWeaponType:(WeaponType)weaponType
{
    //ustaw zmienna instancji
    [self setWeapon:[Weapon newWeaponOfType:weaponType]];
 
    //schowaj input view.
    [self resignFirstResponder];
 
    //Jezeli delegat istnieje, to poinformuj go o zmianie.
    if (_delegate != nil) {
        [_delegate selectedWeapon:_weapon];
    }
}
@end

Zwróć uwagę, że ilekroć wywołujesz resignFirstResponder, powoduje to automatyczne usunięcie widoku inputView w ten sam sposób jak ma to miejsce przy chowaniu klawiatury, gdy  UITextView lub UITextField traci   atrybut first responder.

Do tej pory zrobiłeś ogromną ilość pracy. Prawie już skończyłeś – wszystko co musisz teraz zrobić to zastąpić plain vanilla UIImageView z Twoim widokiem, i przechwycić weaponChanged callback.

Integracja z RightViewController

Otwórz MainStoryboard_iPad.storyboard, i w Right View Controller zaznacz UIImageView obecnie nazwane jako weaponImageView obok etykiety z nazwą “Preferred way to kill”. Przejdź do inspektora tożsamości (trzecia zakładka)i zmień nazwę klasy z  UIImageView na “WeaponSelectorImageView”.

Także,w inspektorze atrybutów (czarta zakładka), upewnij się, że checkbox  “User Interaction Enabled”  jest zaznaczony – jeżeli nie, funkcja: touchesBegan:withEvent: nigdy się nie wywoła, a Twój widok nigdy się nie ukaże.

Ostatecznie połącz  poprzez przeciągnięcie WeaponSelectorImageView z RightViewController, ustwiając  RightViewController jako delegata wyboru broni.

Przejdź do pliku RightViewController.h i tam zaktualizuj klika rzeczy.Po pierwsze dodaj import:

#import "WeaponSelectorImageView.h" //Takze zawiera protokol WeaponSelectorDelegate

Zaktualizuj deklarację klasy, aby pokazać, że klasa odpowiada protokołowi  WeaponSelectorDelegate:

@interface RightViewController : UIViewController <MonsterSelectionDelegate, UISplitViewControllerDelegate, ColorPickerDelegate, WeaponSelectorDelegate>

Zaktualizuj także właściwość weaponImageView zmieniając klasę z  UIImageView na własną klasę  WeaponSelectorImageView:

@property (nonatomic, weak) IBOutlet WeaponSelectorImageView *weaponImageView;

W RightViewController.m, zacznijmy od aktualizacji metody refreshUI:

-(void)refreshUI
{
    _nameLabel.text = _monster.name;
    _iconImageView.image = [UIImage imageNamed:_monster.iconName];
    _descriptionLabel.text = _monster.description;
 
    //Wybranie broni widoku wyboru spowoduje automatyczne ustawienie obrazka.
    _weaponImageView.weapon = _monster.weapon;
}

Na samym końcu dodaj metodę delegata WeaponSelectorDelegate aby aktualizować wybraną broń:

#pragma mark -metoda delegata WeaponSelectorDelegate
-(void)selectedWeapon:(Weapon *)weapon
{
    //Upewnij sie, czy bron zostala zmieniona.
    if (_monster.weapon != weapon) {
        //Zaktualizuj bron
        _monster.weapon = weapon; 
    }
}

Poprzez dodanie tej metody, kiedy zmieniasz broń potworka, aktualizujesz obiekt, przez co Twój wybór jest zapamiętywany przez całą długość działania aplikacji.
Uruchom aplikację i jeżeli wszystko działa poprawnie to powinieneś móc wywołać widok wybory broni poprzez naciśnięcie na obrazek z bronią:
Finished Custom Input View

Zobacz, że widok wybory broni, będzie miał zawsze taką szerokość jak szerokość klawiatury. Poza tym, dokumentacja Apple ostrzega: “Chociaż wysokość tych widoków może być jaka zechcesz, to szerokość musi być taka sama jak szerokość klawiatury.”.Prawie we wszystkich przypadkach, jest to szerokość całego ekranu a niżeli kontrolera widoku, w którym wyświetlony jest widok wyboru.
Pamiętaj aby wziąć to pod uwagę gdy używasz funkcji  AutoLayout do zbudowania skastozmiwzowanego widoku wyboru. – w przeciwnym wypadku może to spowodować zniknięcie części widoku gdy obrucisz urządzenie w określoną orientację.

Pokarz mi swój kod!

Tutaj znajdziesz cały kod ktory zostal zbudowany do tego momentu.
Kończy to trzyczęściową serię iPad dla deweleoperów iPhopne’a. Mamy nadzięję, że przez nią mogłeś się wiele nauczyć – jeżeli masz jakieś pytania bądź komentarze, proszę dołącz do forum dyskusyjnego!

Tagi: , , , ,

2 May 2013

iPad dla delweloperów iPhone’a 101 w iOS 6: Tutorial używania elementu UIPopoverController

Finished Popover Changing Text Color
Ostatnia aktualizacja 3/7/2013: Pełna aktualizacja iOS 6 (autorem artykułu jest Ray Wenderlich, zaktualizowany przez Ellen Shapiro).
Jest to druga część, trzy częściowej serii pomagającej deweloporom iPhone’a w programowania na urządzenie iPad poprzez zwrócenie uwagi na trzy popularne klasy : UISplitView, UIPopoverController i Custom Input Views.

W pierwszej części, zrobiliśmy aplikację bazującą na kontrolerze UISplitViewController, która wyświetlała listę potworków w lewym panelu, a szczegóły wybranego stworka w jego prawej części.

W drugiej części, zamierzamy wypróbować widok Popover’a w prostym przykładzie: dodamy Popover pozwalający użytkownikom aplikacji na wybranie koloru , powodując tym samym zmianę koloru w elemencie UILabel , wyświetlającej nazwę potworka. (Możesz także od razu przejść do  części 3 która przedstawia temat dotyczący:  Custom Input Views.)

Zaczynamy od miejsca w którym skończyliśmy część pierwszą , dlatego pobierz kopię projektu jeżeli jej jeszcze nie masz. Czytaj dalej!

Tagi: , , , ,

29 April 2013

iPad dla delweloperów iPhone’a 101 w iOS 6: Tutorial używania elementu UISplitView

Let's Display a List of Monsters in a Split View!

Let’s Display a List of Monsters in a Split View!

Ostatnia aktualizacja  3/7/2013: Pełna aktualizacja dla iOS 6 (autorem artykułu jest Ray Wenderlich, zaktualizowany przez Ellen Shapiro).

Jest to pierwsza część, trzy częściowej serii pomagającej deweloporem iPhone’a w programowania na urządzenie iPad poprzez zwrócenie uwagi na trzy popularne klasy : UISplitView, UIPopoverController i  Custom Input Views. (Przejdź do czesci 2 lub czesci 3 .)

W tej serii zrobisz aplikację na urządzenie  iPad od samych podstaw.Po pierwsze aplikacja wyświetli listę potworków z  jednej z gier stworzonej w Cocos2D przez Ray’a w widoku podzielonym (ang. split view). Następnie zmienisz kolor dla etykiety używającej widoku popover. Ostatecznie aplikacja będzie potrafiła zmieniać broń dla danego potworka poprzez zastosowanie własnego widoku wyboru (ang. custom input view).

Dzięki temu tutotorialowi, zrozumiesz wiele istotnych cech dewelopmentu na urządzeniu iPad!

Czytaj dalej!

Tagi: , , , ,

26 February 2013

iOS dla uczniów szkół średnich: Twoja pierwsza aplikacja iOS: Część 2/2

Learn how to make an iOS app.

Autorem tego artykułu jest Mike Jaoudi (współtworzący Tutorial Team), ukończył  Informatykę na Uniwersytecie w Nowym Jorku.

 

Witaj ponownie w kursie iOS dla uczniów szkół średnich:  Twoja pierwsza aplikacja!
Podczas pierwszej części, stworzyłeś prostą lecz rozrwkową grę, w której należało klikać tak szybko jak tylko dałeś radę.
Jednakże, aplikacja nie wyglądała zbyt dobrze! W tej części, nauczysz się jak to poprawić :]
Dokładniej, nauczysz się jak dodawać niestandardowe grafiki oraz dźwięki do gry, aby użytkownik był zadowolony z aplikacji.
Tą część kontynuujemy tam gdzie ostatnio skończyliśmy. Jeśli nie posiadasz wcześniejszego kodu, to tutaj znajdziesz projekt, który jest finalną wersją ostatniej części. Czytaj dalej!

Tagi: , , , , ,

iOS dla uczniów szkół średnich: Twoja pierwsza aplikacja iOS: Część 1/2

Jak napisać aplikację na iOS?

Autorem tego artykułu jest Mike Jaoudi (współtworzący Tutorial Team), ukończył  Informatykę na Uniwersytecie w Nowym Jorku.

 

Witaj ponownie w naszym kursie programowania aplikacji iOS dla uczniów szkół średnich!
W pierwszych dwóch częściach nauczyłeś się podstaw języka Objective-C. Podsumowując:

  • W pierwszej-czesci, nauczyłeś się jak zrobić grę  ”Czy jesteś CZARODZIEJEM?”, podczas którego poznałeś zmienne, instrukcje warunkowe oraz pętle while.
  • W drugiej części, nauczyłeś się jak zrobić grę przygodową (sterowaną poleceniami tekstowymi), podczas którego poznałeś tablice (arrays), klasy (classes), obiekty (objects), methody (methods) oraz właściwości (properties).

Nauczyłeś się bardzo dużo z tych tutoriali, ale mógłbyś zapytać – “Chwileczkę, myślałem, że celem jest robienie aplikacji iOS a do tej pory były tylko aplikacje sterowane z lini poleceń!”
No cóż, dobre wieści – nie musisz dalej czekać! Jesteś gotowy aby w końcu napisać swoją pierwszą aplikację iOS!
W tym kursie, napiszesz grę w której musisz tapnąć tyle razy ile zdążysz w ciągu 30 sekund. Tylko się tak nie ekscytuj i nie zmiażdż swojego ekranu! :]
W tej pierwszej częście, stworzysz podstawową aplikację zawierającą całą postawową funkcjonalność. W drugiej części tego tutoriala, dodasz grafiki oraz dźwięki aby nadać jej przyjemnego kształtu!
Brzmi dobrze? Zatem czas zaczynać! Czytaj dalej!

Tagi: , , , ,