Aplicació per a iOS: treballar amb el selector de components múltiples

Aquest bloc tracta de crear una aplicació iOS que mostri la conversió d’una unitat a una altra. Descriu el funcionament d'un selector de components múltiples, alertes, etc.



Per obtenir una visió completa, llegiu . Aquest és el segon bloc de la sèrie d'aplicacions ios.



Si sou un desenvolupador experimentat i interessat en el funcionament del selector MultiComponent, heu arribat al bloc adequat. En aquest bloc, parlaré de com ampliar la nostra aplicació de conversió amb més funcionalitats mitjançant la implementació d’un selector multicomponent i també de com realitzar una manipulació excepcional mitjançant alertes.

A laúltim bloc,ho hem vist quan escrivim alguna cosa al camp de text, apareix el teclat. El valor que voleu convertir s’escriu al camp de text i després veiem que el teclat no desapareix.



Per solucionar aquest problema hem d'afegir un botó que cobreixi tota la vista. Quan l'usuari toca qualsevol lloc del fons, el teclat hauria de desaparèixer.

Ara, anem endavant i ho fem. Arrossegueu un botó, configureu el tipus de botó com a personalitzat i el color del text com a color clar des de l'inspector d'atributs.

Inspector d



com sortir d’un programa Java

i seleccioneu Editor> Organitza> Enviar a enrere

i canvieu la mida del botó de manera que s'adapti a tota la visualització.

Aquest botó ara actua com un botó invisible de fons que es fa clic perquè el teclat desaparegui. Escrivim l’acció IBA per al mateix, seleccioneu el mode d’assistent d’editor i control + arrossegueu fins al ViewController.h. Establiu la connexió a Acció i el nom a BackgroundButton i feu clic a connecta.

El codi del controlador de visualització té aquest aspecte ara.

#import @interface ViewController: UIViewController @property (strong, nonatomic) IBOutlet UITextField * ValueTextField @property (strong, nonatomic) IBOutlet UIPickerView * picker2 @property (strong, nonatomic) NSArray * data @property (strong, nonatomic) IBOutlet UIL - (IBAction) Converteix: (UIButton *) remitent - (IBAction) backgroundButton: (id) sender @end

Canvieu a ViewController.m i, a continuació, escriviu el codi següent.

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

Aquí el codi indica a la resta d’objectes que donin l’estat del primer contestador quan es detecti un toc. Ara, executeu l'aplicació i veureu. Podreu comprovar que el teclat desapareix quan toqueu el fons. Ara, per acabar el teclat, escriviu el mètode backgroundButton al mètode didselectRow () del selector. Per tant, el codi del mètode serà el següent.

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) fila inComponent: (NSInteger) component {selectedValue = _data [fila] [self backgroundButton: 0]}

Ara podeu treballar a la part d’embelliment de l’aplicació, com ara afegir un fons i, fins i tot, donar una imatge de botó elegant. No obstant això, a la meva, definiré una imatge de fons.
Per fer-ho, primer busqueu una imatge adequada. A continuació, afegiu-la a la carpeta Images.xcassets i canvieu la imatge de la pantalla 1x a 2x en universal.

Executeu l'aplicació i vegeu si funciona bé.

Si canvio el dispositiu per l'iPhone 5s.

I executeu l'aplicació.

Aquí podem veure que tot funciona bé com s’esperava. Ara, i si volgués afegir un fons al meu botó i fer que l’aspecte s’assemblés més a un botó? Per fer-ho, primer afegiria un IBOutlet per al botó de conversió al ViewController.h

@property (fort, no atòmic) IBOutlet UIButton * convert

i, a continuació, afegiu el codi següent al mètode viewDidLoad ()

self.convert.backgroundColor = [UIColor colorWithRed: 0,4 verd: 0,8 blau: 1,0 alfa: 1,0] [_convert setTitleColor: [UIColor whiteColor] forState: UIControlStateNormal]

Executem la nostra aplicació i comprovem si és com ens agrada.

D'acord perfecte! Us heu adonat que també he canviat les posicions de l’etiqueta de resultats, la raó del canvi és alguna cosa que explicaré més endavant.

Sabem que la nostra aplicació converteix només de Celsius a Fahrenheit i viceversa. Llavors, què us sembla afegir algunes funcions o unitats més per convertir? Per fer-ho, hem d’afegir un component més a UIPickerView que doni la selecció adequada quan es selecciona una unitat al primer component del selector.

rols i responsabilitats d'administrador del sistema linux

Per fer un selector dividit en dos components, hem d'afegir una nova NSArray data2, que contindrà les dades del segon component. A més, definiu dues constants que representaran els nostres components. Aquí, el component esquerre es declara 0 i el component dret es declara 1 per la simplicitat de la programació.

El vostre fitxer ViewController.h té l’aspecte següent

#import # define data1comp 0 # define data2comp 1 @interface ViewController: UIViewController @property (strong, nonatomic) IBOutlet UITextField * ValueTextField @property (strong, nonatomic) IBOutlet UIPickerView * picker2 @property (strong, nonatomic) NSArray * data1 @ strong, nonatomic) NSArray * data2 @property (strong, nonatomic) IBOutlet UILabel * ResultLabel @property (strong, nonatomic) IBOutlet UIButton * convertir - (IBAction) Convertir: (UIButton *) remitent - (IBAction) backgroundButton: (id) remitent @final

Ara definiu la matriu data2 al mètode ViewDidLoad (). Ara que tenim les dues fonts de dades, hem de poder escriure codi per al selector de manera que quan seleccionem un element del primer component del selector, el segon component hauria de canviar automàticament al valor corresponent. El segon component depèn de la selecció del primer.
Per a això, hem de definir un diccionari que emmagatzemi les claus i els valors. Les claus contenen les dades corresponents al primer component del selector i els valors contenen les dades corresponents al segon component del selector.

- (void) viewDidLoad {[super viewDidLoad] // Feu qualsevol configuració addicional després de carregar la vista, normalment des d’un punt. _data1 = [NSArray arrayWithObjects: @ 'Celsius', @ 'Fahrenheit', @ 'Meter', @ 'Centimeter', zero] data2 = [NSArray arrayWithObjects: @ 'Centimeter', @ 'Meter', @ 'Fahrenheit', @ 'Celsius', nul] dictionary = [NSDictionary dictionaryWithObjectsAndKeys: @ 'Celcius', @ 'Farenheit', @ 'Farenheit', @ 'Celcius', @ 'Meter', @ 'Centimeter', @ 'Centimeter', @ 'Meter ', nul] self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: (@' bg2.png ')]]}

Ara, hem de canviar la font de dades i delegar els mètodes del selector actual al següent, de manera que tinguem dades emplenades ambdós components.

- (NSInteger) numberOfComponentsInPickerView: (UIPickerView *) pickerView {return 2} - (NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {if (component == data1comp) {return [self.data] [self.data2 count]} - (NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) fila forComponent: (NSInteger) component {if (component == data1comp) {return [self.data1 objectAtIndex: row]} return [self.data2 objectAtIndex: row]} - (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) fila inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: fila] NSArray * a = [diccionari objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animat: SÍ] [_picker2 reloadComponent seleccionat: data2compod = fila}}

Aquí, amb el nostre mètode didSelectRow (), obtenim el valor seleccionat del primer component, després el passem com a argument al mètode objectForKey () del diccionari i obtenim el valor corresponent per a la clau. Per trobar la posició corresponent al valor de la segona matriu, és a dir, dades2, fem servir el mètode indexOfObject () de la matriu i emmagatzemem el resultat en un valor enter.
A continuació, passem aquest valor enter al mètode selector selectRow: row inComponent: component (). I torneu a carregar el component del selector mitjançant reloadComponent ().
Un cop fet això, a mesura que seleccionem un element del primer component, se seleccionarà l'element corresponent al segon component del selector.

El codi del didSelectRow ()

- (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) fila inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: row] NSArray * a = [diccionari objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp animat: SÍ] [_picker2 reloadComponent: data2comp] selectedValue = data11 selectedRow = fila}}

Ara executeu l'aplicació i veureu si el selector funciona tal com s'esperava.

Voila! funciona!

Per tant, continuem codificant el nostre botó de conversió. El selector anterior només tenia dos valors per coincidir, és a dir, Celsius i Fahrenheit, i es calculà el resultat. Però ara tenim quatre valors Celsius, Fahrenheit, Meter i Centimeter. Per tant, he utilitzat una instrucció switch, que calcula el valor en funció de la variable de fila seleccionada.

- (IBAction) Converteix: (UIButton *) remitent {float val = [_ ValueTextField.text floatValue] NSLog (@ 'value% f', val) switch (selectedRow) {case 0: // Celsius to Fahrenheit res = (val * 1.8) + 32 casos de ruptura 1: // Fahrenheit a centígrads res = (val-32) /1.8 cas de ruptura 2: // Meter a centímetre res = val * 100 casos de trencament 3: // Centímetre a metre res = val * 0,01 interrupció per defecte: res = 0.0} NSString * final = [NSString stringWithFormat: @ '%. 02f', res] _ResultLabel.text = final}

si executeu l'aplicació, podem veure que tot funciona bé.

Ara podem comprovar si hi ha excepcions a la nostra aplicació. Per exemple, no hi ha cap valor al quadre de text. O estem intentant convertir de centígrads a metre o centímetre, cosa que en realitat no és possible. Aquest tipus de situacions s’anomenen excepcions i hem d’evitar-ho escrivint codi per gestionar aquests errors.

Solucionem el primer tipus d'error que es pot produir quan executem la nostra aplicació. És a dir, trobem a faltar escriure el nostre valor per convertir-lo al camp de text. Per a aquest escenari, hem d’avisar els nostres usuaris perquè introdueixin el valor i després continuar.

Podem utilitzar UIAlertView per a això. Podem escriure un mètode anomenat missatge showAlertWithMessage (NSString *). En aquest mètode, podem declarar un alertView i, finalment, mostrar-lo mitjançant el mètode show (). El codi del mètode serà el següent.

- (void) showAlertWithMessage: missatge (NSString *) {UIAlertView * alertView = [[UIAlertView alloc] initWithTitle: @ Missatge 'Error': delegat del missatge: auto cancelButtonTitle: nil otherButtonTitles: @ 'OK', nil] alertView.tag = 100 _ResultLabel.text=@'No result '[alertView show]}

Ara, aquest mètode quan l'usuari fa clic al botó de conversió s'ha de cridar com a conversió. La conversió no s'hauria de fer sense introduir el valor. Per tant, a la definició del mètode per convertir, hem de comprovar si la longitud del camp de text és superior o igual a zero o no. Si és així, feu la conversió, sinó mostreu l'alerta. Per tant, el codi del botó de conversió seria el següent:

- (IBAction) Converteix: (UIButton *) remitent {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 } }

Ara executeu l'aplicació i proveu de fer clic al botó Converteix sense introduir valors al camp de text.

El segon tipus d’excepció que es pot produir és si el valor del primer component no coincideix amb el valor del segon component de l’UIPickerView. Per a això, comprovem si el valor de fila del component seleccionat actual del segon component és igual al valor del valor de fila retornat pel delegat didSelectRow () del mètode. Si la condició no coincideix, la conversió no és possible i si els valors coincideixen, es pot fer la conversió.

Podem implementar aquesta lògica de la següent manera,

- (IBAction) Converteix: (UIButton *) remitent {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' } }

Ara executeu l'aplicació i veureu canviant el valor del segon component després de fer la selecció al primer component.

Podeu veure el missatge d'error que indica que no es pot calcular el resultat. Notareu que el missatge d'error s'ha imprès a la mateixa etiqueta de resultats i que el missatge és llarg. Per això, l'etiqueta es va moure cap avall des de l'orientació anterior.

Per tant, la nostra aplicació de conversió s’ha completat. Podeu afegir més funcionalitats a l'aplicació segons la vostra elecció i fer-la més bella segons la vostra creativitat.

Tens alguna pregunta? Esmenteu-los a la secció de comentaris i us respondrem.

Articles Relacionats: