iOS-app: werken met MultiComponent Picker



Deze blog gaat over het maken van een ios-app die de conversie van de ene eenheid naar de andere weergeeft. Het beschrijft de werking van een Mutlicomponent Picker, Alerts etc.

Lees voor een grondig inzicht . Dit is de tweede blog van de ios-app-serie.





Ben je een ervaren developer die nieuwsgierig is naar de werking van MultiComponent picker dan ben je bij ons aan het juiste adres. In deze blog zal ik het hebben over hoe we onze conversie-app kunnen uitbreiden met meer functionaliteit door een multicomponent-picker te implementeren, en ook hoe we uitzonderlijke afhandeling kunnen uitvoeren met behulp van waarschuwingen.

In delaatste blog,dat hebben we gezien wanneer we iets in het tekstveld typen, verschijnt het toetsenbord. De te converteren waarde wordt in het tekstveld getypt en dan zien we dat het toetsenbord niet weggaat.



Om dit probleem op te lossen, moeten we een knop toevoegen die de hele weergave beslaat. Wanneer de gebruiker ergens op de achtergrond aanraakt, zou het toetsenbord moeten verdwijnen.

Laten we nu doorgaan en het doen. Versleep een knop, stel het type van de knop in als aangepast en de tekstkleur als duidelijke kleur vanuit de attributencontrole.

Attributen Inspector



en selecteer Editor> Schikken> Naar achtergrond verzenden

en pas het formaat van de knop aan zodat deze in de hele weergave past.

Deze knop fungeert nu als een onzichtbare achtergrondknop waarop wordt geklikt om het toetsenbord te laten verdwijnen. Laten we IBAction voor hetzelfde schrijven, de modus Assistent-editor selecteren en control + slepen naar de ViewController. H. Stel de Connection in op Action en de naam op BackgroundButton en klik op Connect.

De view controller code ziet er nu zo uit.

#import @interface ViewController: UIViewController @property (sterk, niet-atomair) IBOutlet UITextField * ValueTextField @property (sterk, niet-atomair) IBOutlet UIPickerView * picker2 @property (sterk, niet-atomair) NSArray * data @property (sterk, niet-atomair) IBOutlet UILabel - (IBAction) Converteren: (UIButton *) afzender - (IBAction) backgroundButton: (id) afzender @end

Schakel over naar ViewController.m en schrijf de volgende code.

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

Hier vertelt de code alle andere objecten om de eerste responderstatus te geven wanneer een aanraking wordt gedetecteerd. Start nu de app en kijk. U zult zien dat het toetsenbord verdwijnt wanneer u de achtergrond aanraakt. Om het toetsenbord te gebruiken als u klaar bent met typen, roept u de methode backgroundButton op in de methode didselectRow () van de kiezer. Dus de methodecode is als volgt.

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

Nu kunt u werken aan het verfraaiingsgedeelte van de app, zoals het toevoegen van een achtergrond en misschien zelfs een mooie knopafbeelding geven. In de mijne zal ik echter een achtergrondafbeelding instellen.
Om dat te doen, zoek eerst een geschikte afbeelding duh! Voeg het vervolgens toe aan de map Images.xcassets en verander de afbeelding van 1x naar 2x scherm in universeel.

Start de app en kijk of deze goed werkt.

Als ik het apparaat verander naar iphone 5s.

En voer de app uit.

Hier kunnen we zien dat alles naar behoren werkt zoals verwacht. Wat als ik nu een achtergrond aan mijn knop wil toevoegen en het uiterlijk meer als een knop wil laten lijken? Om dat te doen, zou ik eerst een IBOutlet voor de converteerknop aan de ViewController.h toevoegen

hoe classpath in java in te stellen
@property (sterk, niet-atomair) IBOutlet UIButton * converteren

en voeg vervolgens de volgende code toe in de viewDidLoad () - methode

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

Laten we onze app uitvoeren en kijken of het is zoals we het leuk vinden.

Ok geweldig! U moet hebben gemerkt dat ik ook de posities van het resultaatlabel heb gewijzigd, de reden voor de verandering zal ik later uitleggen.

We weten dat onze app alleen converteert van Celsius naar Fahrenheit en vice versa. Dus, hoe zit het met het toevoegen van een paar extra functies of eenheden om te converteren? Om dit te doen, moeten we nog een component toevoegen aan de UIPickerView die de juiste selectie geeft, wanneer een eenheid wordt geselecteerd in de eerste component van de picker.

Om een ​​kiezer op te splitsen in twee componenten, moeten we een nieuwe NSArray data2 toevoegen, die de gegevens voor de tweede component zal bevatten. Definieer ook twee constanten die onze twee componenten vertegenwoordigen. Hier wordt de linkercomponent gedeclareerd 0 en de rechtercomponent 1 verklaard voor de eenvoud van programmeren.

wat is substring in java

Uw ViewController.h-bestand ziet eruit als

#import # definieer data1comp 0 # definieer data2comp 1 @interface ViewController: UIViewController @property (sterk, niet-atomair) IBOutlet UITextField * ValueTextField @property (sterk, niet-atomair) IBOutlet UIPickerView * picker2 @property (sterk, niet-atomair) NSArray * data1 @property sterk, niet-atomair) NSArray * data2 @property (sterk, niet-atomair) IBOutlet UILabel * ResultLabel @property (sterk, niet-atomair) IBOutlet UIButton * converteren - (IBAction) Converteren: (UIButton *) afzender - (IBAction) backgroundButton: (id) afzender @einde

Definieer nu de array data2 in de ViewDidLoad () - methode. Nu we beide databronnen hebben, moeten we in staat zijn om code voor de picker te schrijven, zodat wanneer we een item uit de eerste component van de picker selecteren, de tweede component automatisch moet worden gewijzigd in de overeenkomstige waarde. De tweede component is afhankelijk van de selectie van de eerste.
Hiervoor moeten we een woordenboek definiëren waarin de sleutels en waarden worden opgeslagen. Sleutels bevatten de gegevens die overeenkomen met de eerste component van de kiezer, en waarden bevatten de gegevens die overeenkomen met de tweede component van de kiezer.

- (void) viewDidLoad {[super viewDidLoad] // Voer eventuele aanvullende instellingen uit na het laden van de weergave, meestal vanaf een punt. _data1 = [NSArray arrayWithObjects: @ 'Celsius', @ 'Fahrenheit', @ 'Meter', @ 'Centimeter', nil] data2 = [NSArray arrayWithObjects: @ 'Centimeter', @ 'Meter', @ 'Fahrenheit', @ 'Celsius', nihil] woordenboek = [NSDictionary dictionaryWithObjectsAndKeys: @ 'Celcius', @ 'Farenheit', @ 'Farenheit', @ 'Celcius', @ 'Meter', @ 'Centimeter', @ 'Centimeter', @ 'Meter ', nil] self.view.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: (@' bg2.png ')]]}

Nu moeten we de gegevensbron en de delegatiemethoden van de huidige kiezer wijzigen in het volgende, zodat we gegevens hebben die zijn ingevuld in beide componenten.

- (NSInteger) numberOfComponentsInPickerView: (UIPickerView *) pickerView {return 2} - (NSInteger) pickerView: (UIPickerView *) pickerView numberOfRowsInComponent: (NSInteger) component {if (component == data1comp) {return [self.data1 count]} retourneren [self.data2 count]} - (NSString *) pickerView: (UIPickerView *) pickerView titleForRow: (NSInteger) rij voor Component: (NSGeheel getal) component {if (component == data1comp) {retourneren [self.data1 objectAtIndex: rij]} return [self.data2 objectAtIndex: row]} - (void) pickerView: (UIPickerView *) pickerView didSelectRow: (NSInteger) rij inComponent: (NSInteger) component {[self backgroundButton: 0] if (component == data1comp) {NSString * data11 = [_ data1 objectAtIndex: rij] NSArray * a = [woordenboek objectForKey: data11] secondrow = [self.data2 indexOfObject: a] [_picker2 selectRow: secondrow inComponent: data2comp geanimeerd: YES] [_picker2 reloadComponent: data2comp] selectedRow = data2comp] selectedRow = data11 geselecteerd = rij}}

Hier in onze methode didSelectRow () krijgen we de geselecteerde waarde van de eerste component, dan geven we deze als argument door aan de methode objectForKey () van het woordenboek, en krijgen we de overeenkomstige waarde voor de sleutel. Om de corresponderende positie voor de waarde in de tweede array, d.w.z. data2, te vinden, gebruiken we de methode indexOfObject () van de array en slaan we het resultaat op in een geheel getal.
Vervolgens geven we deze gehele waarde door aan de picker-methode selectRow: row inComponent: component () -methode. En herlaad de component van de picker met reloadComponent ().
Zodra we dit hebben gedaan, terwijl we een item uit de eerste component selecteren, wordt het overeenkomstige item in de tweede component van de picker geselecteerd.

De code voor de didSelectRow ()

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

Start nu de app en kijk of de picker werkt zoals verwacht.

Voila! het werkt!

Dus laten we doorgaan met het coderen van onze converteerknop. De eerdere kiezer had slechts twee overeenkomende waarden, namelijk Celsius en Fahrenheit, en vervolgens werd het resultaat berekend. Maar nu hebben we vier waarden Celsius, Fahrenheit, Meter en Centimeter. Dus ik heb een switch-instructie gebruikt, die de waarde berekent op basis van de geselecteerde rijvariabele.

- (IBAction) Converteren: (UIButton *) afzender {float val = [_ ValueTextField.text floatValue] NSLog (@ 'value% f', val) switch (selectedRow) {case 0: // Celsius naar Fahrenheit res = (val * 1.8) + 32 break case 1: // Fahrenheit naar Celsius res = (val-32) / 1.8 break case 2: // Meter naar centimeter res = val * 100 break case 3: // Centimeter naar meter res = val * 0.01 break standaard: res = 0.0} NSString * final = [NSString stringWithFormat: @ '%. 02f', res] _ResultLabel.text = final}

als u de app uitvoert, kunnen we zien dat alles goed werkt.

Nu kunnen we controleren op uitzonderingen die in onze app kunnen voorkomen. Er staat bijvoorbeeld geen waarde in het tekstvak. Of we proberen om te rekenen van Celsius naar Meter of Centimeter, wat eigenlijk niet mogelijk is. Dit soort situaties worden uitzonderingen genoemd en we moeten dit vermijden door code te schrijven om dergelijke fouten af ​​te handelen.

Laten we het eerste soort fout oplossen dat kan optreden wanneer we onze applicatie uitvoeren. Dat wil zeggen, we missen het schrijven van onze te converteren waarde in het tekstveld. Voor dit scenario moeten we onze gebruikers waarschuwen om de waarde in te voeren en vervolgens door te gaan.

Hiervoor kunnen we de UIAlertView gebruiken. We kunnen een methode schrijven met de naam showAlertWithMessage (NSString *) bericht. Bij deze methode kunnen we een alertView declareren en deze uiteindelijk weergeven met de methode show (). De code voor de methode is als volgt.

- (void) showAlertWithMessage: (NSString *) bericht {UIAlertView * alertView = [[UIAlertView alloc] initWithTitle: @ 'Error' bericht: bericht gedelegeerde: self cancelButtonTitle: nil otherButtonTitles: @ 'Okay', nil] alertView.tag = 100 _ResultLabel.text=@'Geen resultaat '[alertView show]}

Nu moet deze methode, wanneer de gebruiker op de knop Converteren klikt, worden genoemd als conversie. Conversie mag niet worden uitgevoerd zonder de waarde in te voeren. Dus in de methodedefinitie voor convert moeten we controleren of de lengte van het tekstveld groter of gelijk is aan nul of niet. Als dit het geval is, voert u de conversie uit, anders geeft u de waarschuwing weer. Daarom zou de conversieknopcode er als volgt uitzien:

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

Start nu de app en probeer op de converteerknop te klikken zonder waarden in het tekstveld in te voeren.

Het tweede type uitzondering dat kan optreden, is als de waarde in de eerste component niet overeenkomt met de waarde in de tweede component van de UIPickerView. Hiervoor controleren we of de huidige geselecteerde rijwaarde van de component van de tweede component gelijk is aan de waarde van de rijwaarde die wordt geretourneerd door de didSelectRow () gedelegeerde van de methode. Als de voorwaarde niet overeenkomt, is de conversie niet mogelijk en als de waarden overeenkomen, kan er worden geconverteerd.

We kunnen deze logica als volgt implementeren,

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

Start nu de app en kijk door de waarde in de tweede component te wijzigen nadat u de selectie in de eerste component hebt gemaakt.

U kunt de foutmelding zien dat het resultaat niet kan worden berekend. U zult merken dat het foutbericht in hetzelfde resultaatlabel is afgedrukt en dat het bericht lang is. Dit is de reden waarom het label vanuit de eerdere oriëntatie naar beneden is verplaatst.

Dus onze conversie-app is voltooid. U kunt naar keuze meer functionaliteit aan de app toevoegen en deze mooier maken volgens uw creativiteit.

Heeft u een vraag voor ons? Noem ze in het opmerkingengedeelte en we nemen contact met u op.

Gerelateerde berichten: