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

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).

Related

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

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).

My UIImage doesn't drop to the bottom of the screen when it's placed in the Delegate function

My code drops an UIImage to the bottom of the screen. But it's not working when I place the same code in isMyUIViewControllerDelegateTriggered. This is the same thread isn't it??
MyUIViewController.m
#interface MyUIViewController () <UIDynamicAnimatorDelegate>
#property (strong, nonatomic) UIDynamicAnimator *animator;
#property (strong, nonatomic) DropitBehavior *dropitBehavior;
#property (strong, nonatomic) IBOutlet UIView *jobLoadView;
#end
#synthesize someUIImage;
id refToSelf; /* Tried this to have a ref to the UIView, but doesn't work. */
static DropitBehavior * dropit;
- (void)viewDidLoad
{
refToSelf = self;
dropit = [[DropitBehavior alloc] init];
/* Placed inhere, this code works!
DropitBehavior * dropit = [refToSelf dropitBehavior];
[dropit addItem:someUIImage]; */
startupManager = [[StartupManager alloc] init];
[startupManager setDelegate:refToSelf];
[startupManager start];
}
- (DropitBehavior *)dropitBehavior
{
if (!_dropitBehavior) {
_dropitBehavior = [[DropitBehavior alloc] init];
[self.animator addBehavior:_dropitBehavior];
}
return _dropitBehavior;
}
- (UIDynamicAnimator *)animator
{
if (!_animator) {
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.jobLoadView];
_animator.delegate = self;
}
return _animator;
}
-(void)isStartupManagerDelegateTriggered:(NSString *) errorcode {
/* The startup manager code triggers 5 time, so I can make a loading effect. */
/* Doesn't work when I place the code inhere. */
dropit = [refToSelf dropitBehavior];
if ([dropit isKindOfClass:[DropitBehavior class]]) {
NSLog(#"is kind of class drop it ");
[dropit addItem:someUIImage];
}
}
DropitBehavior.m
#interface DropitBehavior()
#property (strong, nonatomic) UIGravityBehavior *gravity;
#property (strong, nonatomic) UICollisionBehavior *collider;
#end
#implementation DropitBehavior
/* Singleton */
static DropitBehavior *sharedSingleton;
+ (void)initialize {
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
sharedSingleton = [[DropitBehavior alloc] init];
}
}
- (UIGravityBehavior *)gravity
{
if (!_gravity) {
_gravity = [[UIGravityBehavior alloc] init];
_gravity.magnitude = 0.9;
}
return _gravity;
}
- (UICollisionBehavior *)collider
{
if (!_collider) {
_collider = [[UICollisionBehavior alloc] init];
_collider.translatesReferenceBoundsIntoBoundary = YES;
}
return _collider;
}
- (void)addItem:(id <UIDynamicItem>)item
{
[self.gravity addItem:item];
[self.collider addItem:item];
}
- (instancetype)init
{
self = [super init];
[self addChildBehavior:self.gravity];
[self addChildBehavior:self.collider];
return self;
}
#end
StartupManager.m
#implementation StartupManager
JSONParser * jsonParser;
HTTPConnection * httpConnection;
static StartupManager *sharedSingleton;
#synthesize delegate;
+ (void)initialize {
static BOOL initialized = NO;
if(!initialized) {
initialized = YES;
sharedSingleton = [[StartupManager alloc] init];
jsonParser = [[JSONParser alloc] init];
httpConnection = [[HTTPConnection alloc] init];
}
}
- (void) doingSomeStuff {
[httpConnection setDelegate:self];
[httpConnection postRequestToSomeServer:#"some.instance.inthe.cloud";
}
-(void)isHTTPConnectionDelegateTriggered:(NSData *)jsonPost {
[jsonParser setDelegate:self];
[jsonParser parseJSON:jsonPost];
}
-(void)isJSONParserDelegateTriggered:(NSString *) message {
*/ this gets called periodically and that has to do a loading screen animation. /*
[delegate isStartupManagerDelegateTriggered:message];
}
StartupManager.h
#class StartupManager;
#protocol StartupManagerDelegate
#required
-(void)isStartupManagerDelegateTriggered:(NSString *) errorcode;
#end
#interface StartupManager : NSObject <JSONParserDelegate, HTTPConnectionDelegate>
#property (nonatomic, assign) id<StartupManagerDelegate> delegate;
- (void) doingSomeStuff;
Is there anyone who can point me in the right direction? Otherwise I'll have to ask the Grandfather.
I think you may be misunderstanding the UIDynamicAnimatorDelegate protocol. It doesn't start an animation for you, it just lets you know that the animation state has changed.
So you normally wouldn't start your animation from a delegate method. In any case, the code you posted doesn't implement any of the delegate methods. The only way to start the animation with the code as posted is to explicitly invoke isMyUIViewControllerDelegateTriggered
When do you want it to start? viewDidLoad is too early. viewDidAppear would normally be the earliest reasonable time for something you expect the user to see.

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

cannot follow that tutorial

i tried to follow this tutorial:
http://www.youtube.com/watch?v=L-FK1TrpUng&feature=related
around 00:39:00.
Theres a counter which recognizes every switch to the second view controller and counts it.
The number of view switches should be shown on the second view controller.
But it doesn't work, thats the code:
Test2ViewController.h
#interface Test2ViewController : UIViewController <UITextFieldDelegate> {
UINavigationController *navController;
Test21ViewController *test21View;
NSString *text;
IBOutlet UITextField *textField1;
}
#property(nonatomic, retain) UITextField *textField1;
#property (nonatomic, retain) UINavigationController *navController;
#property (copy) NSString *text;
-(IBAction)pushViewController:(id)sender;
#end
Test2ViewController.m:
#import "Test2ViewController.h"
#import "Test21ViewController.h"
#implementation Test2ViewController
#synthesize textField1, navController, text;
-(IBAction)pushViewController:(id)sender {
static int count = 1;
Test21ViewController *test21ViewController = [[Test21ViewController alloc] init];
[self.navigationController pushViewController:test21ViewController animated:YES];
test21ViewController.label = [NSString stringWithFormat:#"Pushed %d", count];
count++;
}
Test21ViewController.h:
#interface Test21ViewController : UIViewController {
UINavigationController *navController;
NSString *label;
IBOutlet UILabel *textLabel;
UITextField *tF1;
}
#property (copy) NSString *label;
#property (nonatomic, retain) UINavigationController *navController;
#property(nonatomic,retain)UITextField *tF1;
-(IBAction)feldeingabe:(id)Sender;
#end
Test21ViewController.m:
#implementation Test21ViewController
#synthesize label;
- (void)viewDidLoad {
textLabel.text = label;
}
Any ideas why it doesn't work?
Thanks in advance
Code for the second question:
static int count = 1;
Test2ViewController *test2ViewController;
test2ViewController.label = [NSString stringWithFormat:#"Pushed %d !!!!!", count];
[[self navigationController] popViewControllerAnimated:NO];
count++;
CURRENT CODE:
#import "Test21ViewController.h"
#implementation Test21ViewController
#synthesize navController, text, parentView;
-(IBAction)pushViewController2:(id)sender {
Test2ViewController *test2ViewController;
static int count = 1;
test2ViewController.parentView = self;
test2ViewController.label = [NSString stringWithFormat:#"Pushed %d !!!!!", count];
[self.navigationController pushViewController:test2ViewController animated:YES]; count++;
}
For the second problem (passing a string from child to parent);
Test2ViewController.h
#interface Test2ViewController : UIViewController <UITextFieldDelegate> {
NSString *receiverPropertyFromChild;
}
#property(nonatomic, retain) NSString *receiverPropertyFromChild;
Test2ViewController.m:
-(IBAction)pushViewController:(id)sender {
static int count = 1;
Test21ViewController *test21ViewController = [[Test21ViewController alloc] init];
test21ViewController.label = [NSString stringWithFormat:#"Pushed %d", count];
test21ViewController.parentView = self;
[self.navigationController pushViewController:test21ViewController animated:YES];
count++;
}
Test21ViewController.h:
#class Test2ViewController;
#interface Test21ViewController : UIViewController {
Test2ViewController *parentView;
}
#property (nonatomic, assign) Test2ViewController *parentView;
Test21ViewController.m
-(IBAction)goToTest2ViewController:(id)sender {
parentView.receiverPropertyFromChild = #"the text you want to pass";
[self.navigationController popViewControllerAnimated:YES];
count++;
}
can you try:
Test21ViewController *test21ViewController = [[Test21ViewController alloc] init];
test21ViewController.label = [NSString stringWithFormat:#"Pushed %d", count];
[self.navigationController pushViewController:test21ViewController animated:YES];
I swapped the last two lines. It could be that you are setting the label after viewDidLoad has already been called, thus not setting the value in the label.
That said, it is better to pass the string as an init parameter, not as a property and then set in viewDidLoad.
edit:
To set it as init parameter, you need to create a new init method to accept that parameter.
- (id) initWithString:(NSString *)labelParam {
self = [super init];
if (self) {
this.label = labelParam;
}
return self;
}