How to execute a if loop when i press the convert button objective c, xcode - objective-c

This is my .h file in xcode
//
// PickerViewController.h
// Picker
//
// Created by jitin on 9/14/14.
// Copyright (c) 2014 jitin. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface PickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
IBOutlet UIPickerView *picker;
}
#property (nonatomic, retain) UIPickerView *picker;
#property (weak, nonatomic) IBOutlet UITextField *txtbox1;
#property (weak, nonatomic) IBOutlet UITextField *txtbox2;
#property (weak, nonatomic) IBOutlet UITextField *txtbox3;
#property (weak, nonatomic) IBOutlet UITextField *txtbox4;
-(IBAction)convert:(id)sender;
#end
this is my .m file using xcode
//
// PickerViewController.m
// Picker
//
// Created by jitin on 9/14/14.
// Copyright (c) 2014 jitin. All rights reserved.
//
#import "PickerViewController.h"
#interface PickerViewController ()
#end
#implementation PickerViewController
#synthesize picker;
#synthesize txtbox1, txtbox2, txtbox3, txtbox4;
static NSString *pd[3] = {#"Farenheit", #"Feet", #"Grams"};
static NSString *pd2[3] = {#"Celcius", #"Inches", #"Kilograms"};
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark UIPickerViewDelegate & UIPickerViewDataSource methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 3;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return pd[row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"didSelectRow: %li, inComponent: %li", row, (long)component);
self.txtbox1.text = pd[row];
self.txtbox2.text = pd2[row];
}
#pragma mark Rotation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
NSLog(#"Current Row Select Value %li", [picker selectedRowInComponent:0]);
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(BOOL)shouldAutorotate {
NSLog(#"Current Row Select Value %li", [picker selectedRowInComponent:0]);
return YES;
}
-(IBAction)convert:(id)sender
{
float inValue = [[txtbox3 text] floatValue];
float outValue = ((inValue * (9.0f/5.0f)) + 32);
[txtbox4 setText:[NSString stringWithFormat:#"%3.2f", outValue]];
}
#end
my question is about the convert method/function in my .m file.
I want to do a if loop based on what row is selected in the pickerview. for example. if row 0 is selected, the conversion would be Fahrenheit to Celsius.
if row 1 is selected the conversion would be feet to inches when i hit the convert button. I know I have to use a if loop. But i'm having trouble on what to call in that if loop in order for my statements to execute correctly. Another note. I have not implemented my feets to inches and the grams to kilograms conversion yet. I just wanna get my if loop working first.

Hi #user7897479 and welcome.
My recommendation would be to use a "UnitConversion" class to hold all the relevant information about the units and perform the conversions for you. This separates the responsibilities so that your ViewController only really has the responsibility of passing data between the UI Elements <-> conversion class.
One other thing that i'd like to mention before I get into my full answer:
Naming is very important! Please give meaningful names to your properties/methods/objects/classes -- This will help not only others looking at your code, but yourself going forward maintaining it
Looking at this without much idea about your interface, I have no clue what txtbox1,2,3,4 are for, or for that matter what type of strings pd, pd2 (if I was just looking at them without the literals defined).
Ok, onto some code:
UnitConversion.h:
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
UnitConversionTypeFarenheightToCelsius,
UnitConversionTypeFeetToInches,
UnitConversionTypeGramsToKilograms,
} UnitConversionType;
NS_ASSUME_NONNULL_BEGIN
#interface UnitConversion : NSObject
- (instancetype _Nullable)initWithUnitConversionType:(UnitConversionType)type;
- (NSString *)nameForConvertFromUnit;
- (NSString *)nameForConvertToUnit;
- (NSString *)runConversionOnValue:(float)value;
#end
NS_ASSUME_NONNULL_END
UnitConversion.m:
#import "UnitConversion.h"
typedef enum : NSUInteger {
ConversionUnitFarenheit,
ConversionUnitFeet,
ConversionUnitGrams,
ConversionUnitCelsius,
ConversionUnitInches,
ConversionUnitKilograms,
} ConversionUnit;
#interface UnitConversion()
#property ConversionUnit convertFromUnit;
#property ConversionUnit convertToUnit;
#property UnitConversionType conversionType;
#property float valueToConvert;
#end
#implementation UnitConversion
- (instancetype _Nullable)initWithUnitConversionType:(UnitConversionType)type {
self = [super init];
if (self) {
_conversionType = type;
switch (type) {
case UnitConversionTypeFarenheightToCelsius: {
_convertFromUnit = ConversionUnitFarenheit;
_convertToUnit = ConversionUnitCelsius;
break;
}
case UnitConversionTypeFeetToInches: {
_convertFromUnit = ConversionUnitFeet;
_convertToUnit = ConversionUnitInches;
break;
}
case UnitConversionTypeGramsToKilograms: {
_convertFromUnit = ConversionUnitGrams;
_convertToUnit = ConversionUnitKilograms;
break;
}
default:
break;
}
}
return self;
}
- (NSString *)runConversionOnValue:(float)value {
self.valueToConvert = value;
NSString *convertedValue = #"Undefined";
switch (self.conversionType) {
case UnitConversionTypeFarenheightToCelsius:
convertedValue = [self _convertFarenheightToCelsius];
break;
case UnitConversionTypeFeetToInches:
convertedValue = [self _convertFeetToInches];
break;
case UnitConversionTypeGramsToKilograms:
convertedValue = [self _convertGramsToKilograms];
break;
default:
break;
}
return convertedValue;
}
- (NSString *)_convertFarenheightToCelsius {
return [NSString stringWithFormat:#"%.2f", (self.valueToConvert - 32.0f) * (5.0f/9.0f)];
}
- (NSString *)_convertFeetToInches {
return [NSString stringWithFormat:#"%.2f", self.valueToConvert / 12.0f];
}
- (NSString *)_convertGramsToKilograms {
return [NSString stringWithFormat:#"%.2f", self.valueToConvert / 1000.0f];
}
- (NSString *)nameForConvertFromUnit {
return [self _nameForConversionUnit:self.convertFromUnit];
}
- (NSString *)nameForConvertToUnit {
return [self _nameForConversionUnit:self.convertToUnit];
}
- (NSString *)_nameForConversionUnit:(ConversionUnit)unit {
NSString *unitName = #"Default Unit";
switch (unit) {
case ConversionUnitFarenheit: {
unitName = #"Farenheit";
break;
}
case ConversionUnitFeet: {
unitName = #"Feet";
break;
}
case ConversionUnitGrams: {
unitName = #"Grams";
break;
}
case ConversionUnitCelsius: {
unitName = #"Celsius";
break;
}
case ConversionUnitInches: {
unitName = #"Inches";
break;
}
case ConversionUnitKilograms: {
unitName = #"Kilograms";
break;
}
default:
break;
}
return unitName;
}
#end
ConversionViewController.m:
#import "ConversionViewController.h"
#import "UnitConversion.h"
#interface ConversionViewController () <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
#property (strong, nullable) IBOutlet UIPickerView *conversionPicker;
#property (strong, nullable) NSArray <UnitConversion *> *unitConversionArray;
#property (strong, nullable) IBOutlet UILabel *convertFromLabel;
#property (strong, nullable) IBOutlet UILabel *convertToLabel;
#property (strong, nullable) IBOutlet UITextField *convertFromValue;
#property (strong, nullable) IBOutlet UITextField *convertToValue;
#end
#implementation ConversionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// setup the conversion we want to do and put them into our data structure
UnitConversion *degreesConversion = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeFarenheightToCelsius];
UnitConversion *inchesToFeet = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeFeetToInches];
UnitConversion *gramsToKilo = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeGramsToKilograms];
self.unitConversionArray = #[degreesConversion, inchesToFeet, gramsToKilo];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// by default select the first row
[self.conversionPicker selectRow:0 inComponent:0 animated:NO];
}
- (IBAction)convert:(id)sender {
NSInteger pickerRow = [self.conversionPicker selectedRowInComponent:0];
if (pickerRow >= 0) {
// grab our associated UnitConversion based on our backing unit conversion array
// the index matches up with the index selected for the picker row
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:pickerRow];
// run the conversion
NSString *convertedValue = [conversion runConversionOnValue:[self.convertFromValue.text floatValue]];
// set the converted value to our result field
self.convertToValue.text = convertedValue;
}
}
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 3;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// clear out our input and output fields
self.convertFromValue.text = #"";
self.convertToValue.text = #"";
// set the labels to alpha 0 because we going to fade in the change
self.convertFromLabel.alpha = 0.0f;
self.convertToLabel.alpha = 0.0f;
// determine which conversion is selected from the picker view
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:row];
// set our labels to reflect that
self.convertFromLabel.text = [conversion nameForConvertFromUnit];
self.convertToLabel.text = [conversion nameForConvertToUnit];
// now animate the fade in of our label names
[UIView animateWithDuration:0.2 animations:^{
self.convertFromLabel.alpha = 1.0f;
self.convertToLabel.alpha = 1.0f;
}];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
// our titles should be in the form of "Feet to Inches"
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:row];
return [NSString stringWithFormat:#"%# to %#", [conversion nameForConvertFromUnit], [conversion nameForConvertToUnit]];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// only allow numbers decimal and negative
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:#"0123456789.-"];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:textField.text];
// don't allow the text field to change if the user attempts to input something else
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
return stringIsValid;
}
#end
Here's an example of what that Code produces after generating a simple interface:
While this does seem like overkill for the example, it makes it a lot easier to expand upon it (for example if you wanted to add additional conversion types, or re-use the conversion class somewhere else).

Related

How can I display a certain message/alert after the user chooses certain values from a multicomponent picker in xcode?

I'm trying to display a message when the user chooses 2 values from a double component picker.
In case the user’s choice was "High Fever" and "Strong Cough", use an Alert View to display a message indicating: 'you should do the PCR Test'.
In case the user’s choice was a selection of "High Fever" and "Medium Cough" or "Medium Fever" and "Strong Cough", display a message indicating: 'it is just a normal flu'.
In case of all other possible selections, display a message: 'Relax... Nothing to worry about!'
Here is the code below:
#import "FirstViewController.h"
#define kFeverComponent 0
#define kCoughComponent 1
#interface FirstViewController ()
#property (strong, nonatomic) NSArray *feverTypes;
#property (strong, nonatomic) NSArray *coughTypes;
#property (weak, nonatomic) IBOutlet UIPickerView *dependentPicker;
#end
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.feverTypes = #[#"High Fever", #"Medium Fever", #"No Fever"];
self.coughTypes = #[#"Strong Cough", #"Medium Cough", #"No Cough"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)symptomsButtonPressed:(id)sender {
NSInteger feverRow = [self.dependentPicker selectedRowInComponent: kFeverComponent];
NSInteger coughRow = [self.dependentPicker selectedRowInComponent: kCoughComponent];
NSString *fever = self.feverTypes[feverRow];
NSString *cough = self.coughTypes[coughRow];
NSString *message = [[NSString alloc] initWithFormat:
#"You chose %# and %#.", fever, cough];
UIAlertController *alert =
[UIAlertController
alertControllerWithTitle:#"Thank you for choosing" message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:#"Okay"
style:UIAlertActionStyleDefault handler:nil];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:
(NSInteger)component {
if (component == kCoughComponent) {
return [self.coughTypes count];
} else {
return [self.coughTypes count];
}
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component {
if (component == kCoughComponent) {
return self.coughTypes[row];
} else {
return self.feverTypes[row];
}
}
#end
You need to implement pickerview:didSelectRow:inComponent delegate method. So make your class adhere to the UIPickerViewDelegate protocol by adding it to the interface definition e.g.
#interface FirstViewController () < UIPickerViewDelegate >
and then implement e.g.
- ( void ) pickerView:( UIPickerView * ) pickerView
didSelectRow:( NSInteger ) row
inComponent:( NSInteger ) component
{
// logic here e.g.
NSInteger fever = [pickerView selectedRowInComponent:kCoughComponent];
NSInteger cough = [pickerView selectedRowInComponent:kFeverComponent];
NSString * msg;
if ( fever >= threshold && cough >= threshold )
{
msg = #"Seek help";
}
else
{
msg = #"All fine";
}
// Show alert with msg
}

How to implement a multiple conversions in pickerView in objective-c

I am trying to create a conversion app. I have three units to convert: temperature (fahrenheit, pounds and miles to their metric counterparts).
I want to use a picker view, but I am having difficulties connecting the pickerView to the functionality and actually selecting each unit.
I have been able to implement this in a segmented control, but would like a pickerView to be able to add more conversions in the future.
Thanks!
ViewControlle.m
#import "ViewController.h"
#interface ViewController (){
NSArray *devices;
}
#end
//CONVERSIONS
// convert pounds to kilograms
double convertLbsToKgs(double poundsValue){
double kilogramsValue;
kilogramsValue = poundsValue / 2.205;
return kilogramsValue;
}
//convert fahrenheit to celcius
double convertFarenheitToCelcius(double farenheitValue){
double celciusValue;
celciusValue = (farenheitValue - 32) * 0.555;
return celciusValue;
}
//convert miles to kilometers
double convertMilesToKilometers(double milesValue){
double kilometersValue;
kilometersValue = milesValue * 1.609;
return kilometersValue;
}
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
devices = #[#"Pounds", #"Fahernheit", #"Miles"];
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
}
// pickerView datascource & delegate methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return devices.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return devices[row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.outputTextBox.text = devices[row];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIPickerViewDataSource, UIPickerViewDelegate>
#property (weak, nonatomic) IBOutlet UITextField *inputField;
#property (weak, nonatomic) IBOutlet UILabel *outputTextBox;
#property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
#end
Add this code in didselect method.
if ([devices[row] isEqualToString: #"Pounds"]) {
double kgs =[self convertLbsToKgs:[inputField.text doubleValue]];
outputTextBox.text=[NSString stringWithFormat:#"%f",kgs];
}else if ([devices[row] isEqualToString: #"Fahernheit"]){
double celcious =[self convertFarenheitToCelcius:[inputField.text doubleValue]];
outputTextBox.text=[NSString stringWithFormat:#"%f",celcious];
}else if ([devices[row] isEqualToString: #"Miles"]){
double kms=[self convertMilesToKilometers:[inputField.text doubleValue]];
outputTextBox.text=[NSString stringWithFormat:#"%f",kms];
}

Objective c - Getting text from a UITextfield after keyboard is dismissed

Another NEWBIE QUESTION:
I'm feeling pretty dumb right now. I haven't worked with UI text input for a very long time. So this is what I have so far. I have a view with a subview. I've wired up my IBOutlets for the UITextFields and I've wired the text fields back to the main view controller file owner for the delegate (not sure about that one). I happily build and run. I enter some text and when I click outside the text field my keyboard goes away. But when I exit my view I should be saving the values in each of the fields. But when I step through the code, my textfields (not the text but the fields themselves) are all nil.
So, obviously I've missed an important step here.
Calling saveUserSettings from the main view when user clicks to close the subview:
- (IBAction)closeButtonPressed:(UIButton *)sender {
[self.userSettingsView saveUserSettings];
[self dismissViewControllerAnimated:YES completion:nil];
}
The psychedelic colors are helping me see them during development. :-)
The selected view is a scrollview but it's not scrolling either. That's a different issue.
Here is the IDUtilityViewController code:
#interface IDUtilityViewController ()
#property (strong, nonatomic) IBOutlet IDAboutView *aboutView;
#property (strong, nonatomic) IBOutlet IDUserSettingsView *userSettingsView;
#property (strong, nonatomic) IBOutlet UIButton *aboutButton;
#property (strong, nonatomic) IBOutlet UIButton *userSettingsButton;
#end
#implementation IDUtilityViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.aboutView = [[IDAboutView alloc] init];
self.userSettingsView = [[IDUserSettingsView alloc] init];
[self userSettingsButtonPressed:self.userSettingsButton];
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(hideKeyboard)];
tapGesture.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapGesture];
}
- (void)hideKeyboard
{
[self.userSettingsView saveUserSettings];
[self.view endEditing:YES];
}
#pragma mark - IBActions
- (IBAction)closeButtonPressed:(UIButton *)sender {
//[self.userSettingsView saveUserSettings];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)aboutButtonPressed:(UIButton *)sender {
self.userSettingsView.hidden = YES;
self.aboutView.hidden = NO;
}
- (IBAction)userSettingsButtonPressed:(UIButton *)sender {
self.aboutView.hidden = YES;
self.userSettingsView.hidden = NO;
}
Here is the IDUserSettingsView.h:
#interface IDUserSettingsView : UIView
#property (nonatomic, strong) IBOutlet UITextField *userIDField;
#property (nonatomic, strong) IBOutlet UITextField *passwordField;
#property (nonatomic, strong) IBOutlet UITextField *ipAddressField;
#property (nonatomic, strong) IBOutlet UITextField *portNumberField;
#property (nonatomic, strong) IBOutlet UITextField *doorNameField;
#property (nonatomic, strong) IBOutlet UITextField *badgeNumberField;
- (void)saveUserSettings;
#end
Here is the IDUserSettingsView.m:
#import "IDUserSettingsView.h"
#interface IDUserSettingsView()
#property (nonatomic, strong) NSUserDefaults *standardUserDefaults;
#end
#implementation IDUserSettingsView
#synthesize userIDField = _userIDField;
#synthesize passwordField = _passwordField;
#synthesize ipAddressField = _ipAddressField;
#synthesize portNumberField = _portNumberField;
#synthesize doorNameField = _doorNameField;
#synthesize badgeNumberField = _badgeNumberField;
NSMutableString *emptyString = #"";
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.standardUserDefaults = [NSUserDefaults standardUserDefaults];
}
return self;
}
- (void)saveUserSettings
{
[self.standardUserDefaults setObject:self.userIDField.text forKey:#"isonos_userID"];
[self.standardUserDefaults setObject:self.passwordField.text forKey:#"isonos_password"];
[self.standardUserDefaults setObject:self.ipAddressField.text forKey:#"isonos_ipAddress"];
[self.standardUserDefaults setObject:self.portNumberField.text forKey:#"isonos_portNumber"];
[self.standardUserDefaults setObject:self.doorNameField.text forKey:#"isonos_doorName"];
[self.standardUserDefaults setObject:self.badgeNumberField.text forKey:#"isonos_badgeNumber"];
}
- (UITextField *)userIDField {
return _userIDField;
}
- (void)setUserIDField:(UITextField *)userIDField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_userID"];
if (!result) result = emptyString;
_userIDField.text = [emptyString stringByAppendingString:result];
}
- (UITextField *)passwordField {
return _passwordField;
}
- (void)setPasswordField:(UITextField *)passwordField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_password"];
if (!result) result = emptyString;
_passwordField.text = [emptyString stringByAppendingString:result];
}
- (UITextField *)ipAddressField {
return _ipAddressField;
}
- (void)setIpAddressField:(UITextField *)ipAddressField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_ipAddress"];
if (!result) result = emptyString;
_ipAddressField.text = [emptyString stringByAppendingString:result];
}
- (UITextField *)portNumberField {
return _portNumberField;
}
- (void)setPortNumberField:(UITextField *)portNumberField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_portNumber"];
if (!result) result = emptyString;
_portNumberField.text = [emptyString stringByAppendingString:result];
}
- (UITextField *)doorNameField {
return _doorNameField;
}
- (void)setDoorNameField:(UITextField *)doorNameField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_doorName"];
if (!result) result = emptyString;
_doorNameField.text = [emptyString stringByAppendingString:result];
}
- (UITextField *)badgeNumberField {
return _badgeNumberField;
}
- (void)setBadgeNumberField:(UITextField *)badgeNumberField {
NSString *result = [self.standardUserDefaults stringForKey:#"isonos_badgeNumber"];
if (!result) result = emptyString;
_badgeNumberField.text = [emptyString stringByAppendingString:result];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
I've even tried just setting the controls straight with no values:
#import "IDUserSettingsView.h"
#interface IDUserSettingsView()
#property (nonatomic, strong) NSUserDefaults *standardUserDefaults;
#end
#implementation IDUserSettingsView
#synthesize userIDField = _userIDField;
#synthesize passwordField = _passwordField;
#synthesize ipAddressField = _ipAddressField;
#synthesize portNumberField = _portNumberField;
#synthesize doorNameField = _doorNameField;
#synthesize badgeNumberField = _badgeNumberField;
NSMutableString *emptyString = #"";
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.standardUserDefaults = [NSUserDefaults standardUserDefaults];
}
return self;
}
- (void)saveUserSettings
{
[self.standardUserDefaults setObject:self.userIDField.text forKey:#"isonos_userID"];
[self.standardUserDefaults setObject:self.passwordField.text forKey:#"isonos_password"];
[self.standardUserDefaults setObject:self.ipAddressField.text forKey:#"isonos_ipAddress"];
[self.standardUserDefaults setObject:self.portNumberField.text forKey:#"isonos_portNumber"];
[self.standardUserDefaults setObject:self.doorNameField.text forKey:#"isonos_doorName"];
[self.standardUserDefaults setObject:self.badgeNumberField.text forKey:#"isonos_badgeNumber"];
}
- (UITextField *)userIDField {
return _userIDField;
}
- (void)setUserIDField:(UITextField *)userIDField {
_userIDField = userIDField; // breakpoint here
}
- (UITextField *)passwordField {
return _passwordField;
}
- (void)setPasswordField:(UITextField *)passwordField {
_passwordField = passwordField;
}
- (UITextField *)ipAddressField {
return _ipAddressField;
}
- (void)setIpAddressField:(UITextField *)ipAddressField {
_ipAddressField = ipAddressField;
}
- (UITextField *)portNumberField {
return _portNumberField;
}
- (void)setPortNumberField:(UITextField *)portNumberField {
_portNumberField = portNumberField;
}
- (UITextField *)doorNameField {
return _doorNameField;
}
- (void)setDoorNameField:(UITextField *)doorNameField {
_doorNameField = doorNameField;
}
- (UITextField *)badgeNumberField {
return _badgeNumberField;
}
- (void)setBadgeNumberField:(UITextField *)badgeNumberField {
_badgeNumberField = badgeNumberField;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
#end
Here is the View Hierarchy:
If you're calling "saveUserSettings" from your main view (and not your IDUserSettingsView), then it's likely the IDUserSettingsView has dismissed and all the outlet connections are long gone.
Why not copy the changed settings into some structure that gets sent/copied into your main view which you can then call "saveUserSettings" on when the user chooses to update his/her settings?
Or, make certain "saveUserSettings" gets called before your IDUserSettingsView dismisses (and everything in that view gets torn down and/or dealloc'd).
You probably messed up the IBOutlet connections, I bet they're not connected or connected to the wrong objects.
Try defining a setter method and putting a breakpoint on it to try and find where it's being set or perhaps cleared to nil:
- (void)setUserIDField:(UITextField *)field
{
_userIDField = field; // breakpoint here
}
(note: if you have ARC disabled you will need to retain the new value and release the old value).

Why Isn't My UITextField Wrapper Being Displayed In UITableViewCell?

The issue is that my UITextField wrapper class isn't getting the UITextField to appear within a UITableViewCell (however, a regular UITextField view works just fine):
Here is my custom UITextField:
Header:
#import <UIKit/UIKit.h>
#protocol TUTextFieldDelegate <NSObject>
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string;
- (BOOL)textFieldShouldClear:(UITextField *)textField;
- (void)textFieldDidBeginEditing:(UITextField *)textField;
- (void)textFieldDidEndEditing:(UITextField *)textField;
#end
#interface TUTextField : UIControl <UITextFieldDelegate>
#property (nonatomic, assign) BOOL fixedDecimalPoint;
#property (nonatomic, assign) id <TUTextFieldDelegate>delegate;
#property (nonatomic, assign) UIKeyboardType keyboardType;
#property (nonatomic, strong) NSString *placeholder;
#property (nonatomic, assign) UITextBorderStyle borderStyle;
#property (nonatomic, assign) BOOL adjustsFontSizeToFitWidth;
#property (nonatomic, assign) UITextFieldViewMode clearButtonMode;
#property (nonatomic, strong) NSString *text;
- (id)initWithTextField:(UITextField *)textField;
- (id)initWithFrame:(CGRect)frame;
#end
Implementation:
#import "TUTextField.h"
#interface TUTextField ()
#property (nonatomic, strong) UITextField *textField;
#end
#implementation TUTextField
- (id)initWithTextField:(UITextField *)textField
{
self = [super initWithFrame:textField.frame];
if (self) {
self.textField = textField;
_textField.delegate = self;
_fixedDecimalPoint = NO;
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.textField = [[UITextField alloc] initWithFrame:frame];
_textField.delegate = self;
[self addSubview:_textField];
_fixedDecimalPoint = NO;
}
return self;
}
- (void)setKeyboardType:(UIKeyboardType)keyboardType {
_textField.keyboardType = keyboardType;
}
- (void)setPlaceholder:(NSString *)placeholder {
_textField.placeholder = placeholder;
}
- (void)setBorderStyle:(UITextBorderStyle)borderStyle {
_textField.borderStyle = borderStyle;
}
-(void)setAdjustsFontSizeToFitWidth:(BOOL)adjustsFontSizeToFitWidth {
_textField.adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth;
}
-(void)setClearButtonMode:(UITextFieldViewMode)clearButtonMode {
_textField.clearButtonMode = clearButtonMode;
}
-(void)setText:(NSString *)text {
_textField.text = text;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
[self addSubview:self.textField];
}
*/
- (void)viewDidLoad {
[self addSubview:_textField];
}
- (void)viewWillAppear {
[self addSubview:_textField];
}
- (BOOL)textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
{
if ([_delegate respondsToSelector:#selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
return [_delegate textField:textField shouldChangeCharactersInRange:range
replacementString:string];
}
return YES;
}
- (BOOL)textFieldShouldClear:(UITextField *)textField {
if ([_delegate respondsToSelector:#selector(textFieldShouldClear:)]) {
return [_delegate textFieldShouldClear:textField];
}
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if ([_delegate respondsToSelector:#selector(textFieldDidBeginEditing:)]) {
[_delegate textFieldDidBeginEditing:textField];
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([_delegate respondsToSelector:#selector(textFieldDidEndEditing:)]) {
[_delegate textFieldDidEndEditing:textField];
}
}
#end
And here is the code to add my custom wrapper to the table view:
} else if (indexPath.row == 1) {
cell.textLabel.text = #"Tax Rate";
if (!_textField) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(220.0, 8.0, 60.0, 26.0)];
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
textField.adjustsFontSizeToFitWidth = YES;
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.keyboardType = UIKeyboardTypeDecimalPad;
textField.placeholder = kTaxRateDefault;
_textField = [[TUTextField alloc] initWithTextField:textField];
_textField.delegate = self;
// retrieve saved settings
_taxRate = [[SettingsSingleton sharedManager] taxRate];
if (![_taxRate isEqualToString:#""])
_textField.text = _taxRate;
}
UILabel *percentSign = [[UILabel alloc] initWithFrame:CGRectMake(285.0, 6.0, 20.0, 26.0)];
percentSign.text = #"%";
percentSign.backgroundColor = [UIColor clearColor];
[cell addSubview:_textField];
[cell addSubview:percentSign];
}
}
Any help appreciated!
I don't think this is the best way to extend a UITextField.
Instead of making an NSObject with a UITextField under it you should be saying something like:
Interface:
#interface UITextField (extendedUITextField) {
// Variables
}
//Methods
#end
Implementation:
#implementation UITextField (extendedUITextField)
// Method implement
#end
Hope this helps.

UISlider in xcode

I was wondering if anyone has any idea how to connect a text field with a slider. I want the slider to list numbers from 1-100 or 1-1000. I've looked places but there is no true answer to what I'm looking for. Your help would be greatly appreciated
ViewController.h
#interface ViewController : UIViewController {
IBOutlet UISlider *mySlider;
IBOutlet UITextField *myTextField;
}
#property (nonatomic, retain) IBOutlet UISlider *mySlider;
#property (nonatomic, retain) IBOutlet UITextField *myTextField;
- (IBAction) sliderValueChanged:(id)sender;
- (IBAction) changeButtonPressed:(id)sender;
ViewController.m
#import "ViewController.h"
#implementation TutorialProjectViewController
#synthesize mySlider, myTextField;
- (void)viewDidLoad {
[super viewDidLoad];
self.myTextField.delegate = self;
}
- (IBAction) sliderValueChanged:(UISlider *)sender {
myTextField.text = [NSString stringWithFormat:#" %.1f", [sender value]];
}
- (IBAction) changeButtonPressed:(id)sender {
NSString *textValue = [myTextField text];
float value = [textValue floatValue];
if (value < 0) value = 0;
if (value > 100) value = 100;
mySlider.value = value;
myTextField.text = [NSString stringWithFormat:#"%.1f", value];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[myTextField resignFirstResponder];
//[put your textfield name here resignFirstResponder];
return NO;
}
#end
Change Slider Value:
I'm assuming you want to update the text field's text as the slider is changed.
You don't connect the two. You need to listen for changes to the slider's value. In the method that you setup for this, you need to convert the slider's value to the text you want. You then update the text field's text with this new text based on the slider's value.
The hook for the slider:
[someSlider addTarget:self action:#selector(sliderUpdate:) forControlEvents:UIControlEventValueChanged];
The method that listens to the slider:
- (void)sliderUpdate:(UISlider *)slider {
float newVal = slider.value;
NSString *newText = [NSString stringWithFormat:#"%d", (int)newVal];
someTextField.text = newText;
}
This code assumes the slider is referenced in the someSlider ivar and the text field is referenced by the someTextField ivar. It also assumes the slider's minimumValue is 0 and the maximumValue is 100 or 1000 as needed.
#import "FirstViewController.h"
#interface FirstViewController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextBox;
#property (weak, nonatomic) IBOutlet UISlider *mySlider;
#property (weak, nonatomic) IBOutlet UINavigationBar *titleOnTop;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *backButton;
- (IBAction)changeGreeting:(id)sender;
- (IBAction)sliderValueChanged:(id)sender;
- (IBAction)changeButtonPressed:(id)sender;
#end
#implementation FirstViewController
#synthesize mySlider, myTextBox;
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTextBox.delegate = self;
}
- (IBAction) sliderValueChanged:(UISlider *)sender
{
myTextBox.text = [NSString stringWithFormat:#"%.1f", [sender value]];
}
- (void)sliderUpdate:(UISlider *)slider {
float newVal = slider.value;
NSString *newText = [NSString stringWithFormat:#"%d", (int)newVal];
myTextBox.text = newText;
}
- (IBAction) changeButtonPressed:(id)sender
{
NSString *textValue = [myTextBox text];
float value = [textValue floatValue];
if (value < 0) value = 0;
if (value > 1000) value = 1000;
mySlider.value = value;
myTextBox.text = [NSString stringWithFormat:#"%.1f", value];
if ([myTextBox canResignFirstResponder]) [myTextBox resignFirstResponder];
}
- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
if (myTextBox)
{
if ([myTextBox canResignFirstResponder]) [myTextBox resignFirstResponder];
}
[super touchesBegan: touches withEvent: event];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (IBAction)changeGreeting:(id)sender {
self.username = self.myTextBox.text;
NSString *nameString = self.username;
if ([nameString length] == 0) {
nameString = #"World";
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[myTextBox resignFirstResponder];
return YES;
}
#end
#import "FirstViewController.h"
#interface FirstViewController ()
#property (weak, nonatomic) IBOutlet UITextField *myTextBox;
#property (weak, nonatomic) IBOutlet UISlider *mySlider;
#property (weak, nonatomic) IBOutlet UINavigationBar *titleOnTop;
#property (weak, nonatomic) IBOutlet UIBarButtonItem *backButton;
- (IBAction)changeGreeting:(id)sender;
- (IBAction)sliderValueChanged:(id)sender;
- (IBAction)changeButtonPressed:(id)sender;
- (IBAction)backgroundTouched:(id)sender;
- (IBAction)textFieldReturn:(id)sender;
#end
#implementation FirstViewController
#synthesize mySlider, myTextBox;
- (IBAction)backgroundTouched:(id)sender;
{
[myTextBox resignFirstResponder];
}
- (IBAction)textFieldReturn:(id)sender;
{
[sender resignFirstResponder];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTextBox.delegate = self;
}
- (IBAction) sliderValueChanged:(UISlider *)sender
{
myTextBox.text = [NSString stringWithFormat:#"%.1f", [sender value]];
}
- (void)sliderUpdate:(UISlider *)slider {
float newVal = slider.value;
NSString *newText = [NSString stringWithFormat:#"%d", (int)newVal];
myTextBox.text = newText;
}
- (void)textFieldDidChange:(UITextField*)sender { slider.value = [sender.text floatValue]; }
- (IBAction) changeButtonPressed:(id)sender
{
NSString *textValue = [myTextBox text];
float value = [textValue floatValue];
if (value < 0) value = 0;
if (value > 1000) value = 1000;
mySlider.value = value;
myTextBox.text = [NSString stringWithFormat:#"%.1f", value];
if ([myTextBox canResignFirstResponder]) [myTextBox resignFirstResponder];
}
- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event
{
if (myTextBox)
{
if ([myTextBox canResignFirstResponder]) [myTextBox resignFirstResponder];
}
[super touchesBegan: touches withEvent: event];
}
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[self.textField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (IBAction)changeGreeting:(id)sender {
self.username = self.myTextBox.text;
NSString *nameString = self.username;
if ([nameString length] == 0) {
nameString = #"World";
}
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[myTextBox resignFirstResponder];
return NO;
}
#end