Aplikacja na iOS: praca z selektorem wielu składników



Ten blog dotyczy tworzenia aplikacji na iOS, która wyświetla konwersję z jednej jednostki na drugą. Opisuje działanie Mutlicomponent Picker, Alerty itp.

Aby uzyskać dokładny wgląd, przeczytaj . To drugi blog z serii aplikacji na iOS.





Jeśli jesteś doświadczonym programistą i ciekawi Cię jak działa selektor MultiComponent, to trafiłeś na właściwy blog. Na tym blogu opowiem o tym, jak rozszerzyć naszą aplikację do konwersji o większą funkcjonalność poprzez implementację wieloskładnikowego selektora, a także jak wykonać wyjątkową obsługę za pomocą alertów.

wostatni blog,widzieliśmy to kiedy wpisujemy coś w polu tekstowym, pojawia się klawiatura. Wartość do konwersji jest wpisywana w polu tekstowym, a następnie widzimy, że klawiatura nie znika.



Aby rozwiązać ten problem, musimy dodać przycisk obejmujący cały widok. Kiedy użytkownik dotknie dowolnego miejsca w tle, klawiatura powinna zniknąć.

Teraz przejdźmy dalej i zróbmy to. Przeciągnij przycisk, ustaw typ przycisku jako niestandardowy, a kolor tekstu jako czysty kolor z inspektora atrybutów.

Inspektor atrybutów



i wybierz Edytor> Ułóż> Przesuń na spód

i zmień rozmiar przycisku w taki sposób, aby pasował do całego widoku.

Ten przycisk działa teraz jako niewidoczny przycisk w tle, którego kliknięcie powoduje zniknięcie klawiatury. Napiszmy dla tego samego IBAction, wybierz tryb edytora asystenta i kontroluj + przeciągnij do ViewController.h. Ustaw połączenie na działanie i nazwę na BackgroundButton i kliknij połącz.

Kod kontrolera widoku wygląda teraz tak.

#import @interface ViewController: UIViewController @property (silna, nieatomowa) IBOutlet UITextField * ValueTextField @property (mocna, nieatomowa) IBOutlet UIPickerView * picker2 @property (silna, nieatomowa) NSArray * data @property (silna, nieatomowa) * IBOutlet UILabel - (IBAction) Convert: (UIButton *) sender - (IBAction) backgroundButton: (id) sender @end

Przejdź do ViewController.m, a następnie napisz następujący kod.

- (IBAction) backgroundButton: (id) sender {[_ValueTextField resignFirstResponder] [_picker2 resignFirstResponder] [_ResultLabel resignFirstResponder]}

Tutaj kod mówi wszystkim innym obiektom, aby po wykryciu dotknięcia przekazały stan pierwszej osoby odpowiadającej. Teraz uruchom aplikację i zobacz. Będziesz mógł stwierdzić, że klawiatura znika po dotknięciu tła. Teraz, aby klawiatura działała po zakończeniu pisania, wywołaj metodę backgroundButton w metodzie didselectRow () selektora. Więc kod metody będzie następujący.

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) wiersz inComponent: (NSInteger) składnik {selectedValue = _data [wiersz] [self backgroundButton: 0]}

Teraz możesz pracować nad częścią upiększającą aplikacji, na przykład dodając tło, a może nawet nadając fantazyjny obraz przycisku. Jednak w moim ustawię obraz tła.
Aby to zrobić, najpierw znajdź odpowiedni obraz! Następnie dodaj go do folderu Images.xcassets i zmień obraz z 1x na 2x ekran na uniwersalny.

różnica między zmiennymi a niezmiennymi

Uruchom aplikację i sprawdź, czy działa dobrze.

Jeśli zmienię urządzenie na iphone 5s.

I uruchom aplikację.

Tutaj widzimy, że wszystko działa zgodnie z oczekiwaniami. A co jeśli chciałbym dodać tło do mojego przycisku i nadać mu wygląd bardziej przypominający przycisk? Aby to zrobić, najpierw dodałbym IBOutlet dla przycisku konwersji do ViewController.h

@property (silna, nieatomowa) Konwersja IBOutlet UIButton *

a następnie dodaj następujący kod w metodzie viewDidLoad ()

self.convert.backgroundColor = [UIColor colorWithRed: 0,4 zielony: 0,8 niebieski: 1,0 alpha: 1,0] [_convert setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal]

Uruchommy naszą aplikację i zobaczmy, czy nam się to podoba.

Ok świetnie! Musiałeś zauważyć, że zmieniłem również pozycje etykiety wynikowej, powód zmiany jest czymś, co wyjaśnię później.

Wiemy, że nasza aplikacja konwertuje tylko stopnie Celsjusza na Fahrenheita i odwrotnie. A co powiesz na dodanie kilku dodatkowych funkcji lub jednostek do konwersji? Aby to zrobić, musimy dodać jeszcze jeden składnik do UIPickerView, który zapewni odpowiedni wybór, gdy jednostka zostanie wybrana w pierwszym składniku selektora.

Aby selektor był podzielony na dwa komponenty, musimy dodać nowy NSArray data2, który będzie zawierał dane dla drugiego komponentu. Zdefiniuj również dwie stałe, które będą reprezentować nasze dwa komponenty. Tutaj, lewy komponent jest zadeklarowany jako 0, a prawy jako 1 dla uproszczenia programowania.

Twój plik ViewController.h wygląda tak

#import # define data1comp 0 # define data2comp 1 @interface ViewController: UIViewController @property (strong, nonatomic) IBOutlet UITextField * ValueTextField @property (silna, nieatomowa) IBOutlet UIPickerView * picker2 @property (silna, nieatomowa) NSArray * data1 silny, nieatomowy) NSArray * data2 @property (silny, nieatomowy) IBOutlet UILabel * ResultLabel @property (silny, nieatomowy) IBOutlet UIButton * convert - (IBAction) Convert: (UIButton *) sender - (IBAction) backgroundButton: (id) nadawca @koniec

Teraz zdefiniuj tablicę data2 w metodzie ViewDidLoad (). Teraz, gdy mamy oba źródła danych, musimy być w stanie napisać kod dla selektora w taki sposób, że gdy wybierzemy element z pierwszego składnika selektora, drugi składnik powinien zostać automatycznie zmieniony na odpowiednią wartość. Drugi składnik zależy od wyboru pierwszego.
W tym celu musimy zdefiniować słownik, w którym będą przechowywane klucze i wartości. Klucze zawierają dane odpowiadające pierwszemu składnikowi selektora, a wartości zawierają dane odpowiadające drugiemu składnikowi selektora.

- (void) viewDidLoad {[super viewDidLoad] // Wykonaj dodatkowe ustawienia po załadowaniu widoku, zwykle z końcówki. _data1 = [NSArray arrayWithObjects: @ 'Celsius', @ 'Fahrenheit', @ 'Meter', @ 'Centimeter', nil] data2 = [NSArray arrayWithObjects: @ 'Centimeter', @ 'Meter', @ 'Fahrenheit', @ 'Celsius', nil] Dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @ 'Celcius', @ 'Farenheit', @ 'Farenheit', @ 'Celcius', @ 'Meter', @ 'Centimeter', @ 'Centimeter', @ 'Meter ', nil] self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: (@' bg2.png ')]]}

Teraz musimy zmienić źródło danych i delegować metody bieżącego selektora na następujące, tak aby dane były wypełnione w obu komponentach.

- (NSInteger) numberOfComponentsInPickerView: (UIPickerView *) pickerView {return 2} - (NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {if (component == data1comp) {return [self.data1 count]} return [self.data2 count]} - (NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) wiersz forComponent: (NSInteger) component {if (component == data1comp) {return [self.data1 objectAtIndex: row]} return [self.data2 objectAtIndex: row]} - (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: row] NSArray * a = [słownik objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animowany: YES] [_picker2 reloadComponent: data2comp] selectedRow = wiersz}}

Tutaj w naszej metodzie didSelectRow () pobieramy wybraną wartość pierwszego komponentu, następnie przekazujemy ją jako argument do metody objectForKey () słownika i pobieramy odpowiednią wartość dla klucza. Aby znaleźć odpowiednią pozycję dla wartości w drugiej tablicy, tj. Data2, używamy metody indexOfObject () tablicy i przechowujemy wynik jako wartość całkowitą.
Następnie przekazujemy tę wartość całkowitą do metody selektora selectRow: row inComponent: component (). I przeładuj komponent selektora za pomocą reloadComponent ().
Gdy już to zrobimy, ponieważ wybieramy jeden element z pierwszego komponentu, odpowiadający element zostanie wybrany w drugim komponencie selektora.

Kod dla didSelectRow ()

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) row inComponent: (NSInteger) komponent {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: row] NSArray * a = [słownik objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animated: YES] [_picker2 reloadComponent: data2comp] selectedValue = data11 selectedRow = row}}

Teraz uruchom aplikację i zobacz, czy selektor działa zgodnie z oczekiwaniami.

Voila! to działa!

Kontynuujmy więc kodowanie naszego przycisku konwersji. Wcześniejszy selektor miał tylko dwie wartości do dopasowania, tj. Stopnie Celsjusza i Fahrenheita, a następnie obliczono wynik. Ale teraz mamy cztery wartości Celsjusza, Fahrenheita, Metra i Centymetra. Więc użyłem instrukcji przełącznika, która oblicza wartość na podstawie wybranej zmiennej wiersza.

- (IBAction) Convert: (UIButton *) sender {float val = [_ ValueTextField.text floatValue] NSLog (@ 'value% f', val) switch (selectedRow) {case 0: // Celsjusza na Fahrenheit res = (val * 1.8) + 32 break case 1: // Fahrenheit to Celsius res = (val-32) /1.8break case 2: // metr do centymetra res = val * 100 break case 3: // Centymetr to metr res = val * 0,01 break domyślnie: res = 0.0} NSString * final = [NSString stringWithFormat: @ '%. 02f', res] _ResultLabel.text = final}

jeśli uruchomisz aplikację, zobaczymy, że wszystko działa dobrze.

Teraz możemy sprawdzić wyjątki, które mogą wystąpić w naszej aplikacji. Na przykład w polu tekstowym nie ma wartości. Albo próbujemy przeliczyć stopnie Celsjusza na metr lub centymetr, co w rzeczywistości nie jest możliwe. Tego typu sytuacje nazywane są wyjątkami i musimy ich unikać, pisząc kod obsługujący takie błędy.

jak zadeklarować zmienną instancji w java

Rozwiążmy pierwszy rodzaj błędu, który może wystąpić podczas uruchamiania naszej aplikacji. Oznacza to, że brakuje nam wpisywania naszej wartości do konwersji w polu tekstowym. W tym scenariuszu musimy ostrzec naszych użytkowników, aby wprowadzili wartość, a następnie kontynuowali.

Możemy do tego użyć UIAlertView. Możemy napisać metodę o nazwie showAlertWithMessage (NSString *) wiadomość. W tej metodzie możemy zadeklarować alertView, a następnie wyświetlić go za pomocą metody show (). Kod metody będzie następujący.

- (void) showAlertWithMessage: (NSString *) wiadomość {UIAlertView * alertView = [[UIAlertView Alok] initWithTitle: @ Komunikat „Błąd”: delegat wiadomości: self cancelButtonTitle: nil otherButtonTitles: @ 'Okay', nil] alertView.tag = 100 _ResultLabel.text=@'No Result '[alertView show]}

Teraz ta metoda, gdy użytkownik kliknie przycisk konwersji, musi zostać wywołana jako konwersja. Konwersji nie należy wykonywać bez wpisania wartości. Dlatego w definicji metody do konwersji musimy sprawdzić, czy długość pola tekstowego jest większa lub równa zero, czy nie. Jeśli tak, wykonaj konwersję, w przeciwnym razie wyświetl ostrzeżenie. Dlatego kod przycisku konwersji wyglądałby tak:

- (IBAction) Convert: (UIButton *) sender {if ([_ ValueTextField.text length]<= 0) { [self showAlertWithMessage:@' Please enter the value'] } else { float res=0.0 float val=[_ValueTextField.text floatValue] NSLog(@'value %f',val) switch(selectedRow) { case 0:// Celsius to Fahrenheit res=(val*1.8)+32break case 1: // Fahrenheit to Celsius res=(val-32)/1.8break case 2: // meter to centimeter res= val*100 break case 3://centimeter to meter res=val*0.01 break default: res=0.0 } NSString *final= [NSString stringWithFormat:@'%.02f',res] _ResultLabel.text = final } }

Teraz uruchom aplikację i spróbuj kliknąć przycisk konwersji bez wprowadzania wartości w polu tekstowym.

Drugi typ wyjątku, który może wystąpić, to sytuacja, gdy wartość w pierwszym składniku nie jest zgodna z wartością w drugim składniku UIPickerView. W tym celu sprawdzamy, czy bieżąca wartość wiersza wybranego składnika drugiego składnika jest równa wartości wiersza wartości zwróconej przez delegata metody didSelectRow (). Jeśli warunek nie jest zgodny, konwersja nie jest możliwa, a jeśli wartości są zgodne, konwersja może być wykonana.

Możemy zaimplementować tę logikę w następujący sposób:

- (IBAction) Convert: (UIButton *) sender {if ([_ ValueTextField.text length]<= 0) { [self showAlertWithMessage:@' Please enter the value'] } else { _ResultLabel.textColor= [UIColor blackColor] float res=0.0 NSInteger n =[_picker2 selectedRowInComponent:data2comp] if(n==secondrow) { float val=[_ValueTextField.text floatValue] NSLog(@'value %f',val) switch(selectedRow) { case 0:// Celsius to Fahrenheit res=(val*1.8)+32break case 1: // Fahrenheit to Celsius res=(val-32)/1.8break case 2: // meter to centimeter res= val*100 break case 3://centimeter to meter res=val*0.01 break default: res=0.0 } NSString *final= [NSString stringWithFormat:@'%.02f',res] _ResultLabel.text = final } else { // code for displaying error. _ResultLabel.textColor= [UIColor redColor] _ResultLabel.text = @'Result cannot be calculated' } }

Teraz uruchom aplikację i zobacz, zmieniając wartość w drugim składniku po dokonaniu wyboru w pierwszym składniku.

Możesz zobaczyć komunikat o błędzie, że nie można obliczyć wyniku. Zauważysz, że komunikat o błędzie został wydrukowany na tej samej etykiecie wynikowej i że jest on długi. Dlatego też etykieta została przesunięta w dół z wcześniejszej orientacji.

Tak więc nasza aplikacja do konwersji jest kompletna. Możesz dodać więcej funkcji do aplikacji zgodnie z własnym wyborem i uczynić ją piękniejszą zgodnie ze swoją kreatywnością.

Masz do nas pytanie? Wspomnij o nich w sekcji komentarzy, a my skontaktujemy się z Tobą.

Powiązane posty: