Uncertain about public or private variable declaration and self delegate? - ios

I'm very new to Objective-C and iOS development in general. This week I managed to get a small app running correctly in the simulator after large efforts.
I've pickup basics of the programming language by reading in "iOS 7 Programming Fundamentals" by Matt Neuburg, instructions from tutorials online and from suggestions on this website.
I've written code that works (apparently), but I do not fully understand why I needed to make several adjustments in my code to make it work.
The app is a basic one which solves a "wind triangle" for your information. All it needs to do, is putting some user defined variables in the correct formula, and display the outcome.
I've copied the .h and .m file. Simply said: the .h declares 7 variables; 5 user inputs in a textfield; 2 labels to display 2 calculated outcomes; one button which initiates the action to calculate.
With following code, I do not understand:
why I was forced to state my variables preceded by a underscore to use in the implementation
why I was forced to declare .delegate to 'self' for the variables after loading the view
Any suggestions to make this 'app' more logical and easier to understand (by myself) ?
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#define M_PI 3.14159265358979323846264338327950288 /* pi */
float windDegreesFloat;
float windSpeedFloat;
float courseDesiredFloat;
float trueAirSpeedFloat;
float magneticVariationFloat;
float headingCalculatedFloat;
float groundSpeedCalculatedFloat;
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
And
//
// ViewController.m
// WindTriangle
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.windDegrees.delegate = self;
self.windSpeed.delegate = self;
self.courseDesired.delegate = self;
self.trueAirSpeed.delegate = self;
self.magneticVariation.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)calculatePressed:(id)sender {
windDegreesFloat = [_windDegrees.text floatValue];
windSpeedFloat = [_windSpeed.text floatValue];
courseDesiredFloat = [_courseDesired.text floatValue];
trueAirSpeedFloat = [_trueAirSpeed.text floatValue];
magneticVariationFloat = [_magneticVariation.text floatValue];
headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));
NSString * headingCalculatedString = [NSString stringWithFormat:#"%.1f", headingCalculatedFloat];
_headingCalculated.text = headingCalculatedString;
groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));
NSString * groundSpeedCalculatedString = [NSString stringWithFormat:#"%.1f", groundSpeedCalculatedFloat];
_groundSpeedCalculated.text = groundSpeedCalculatedString;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
#end
I'm brandnew to StackOverflow as well. Your comments will be much appreciated.

Hey so for your first question, the underscore indicates instance variables. Sometime back, you couldn't do this in objective c. If you declared a property, you had to call it through self.property after synthesizing it. So the underscore is just calling an instance.
As for the second question when you set the delegate in this case you're actually setting the delegate of the IBOutlet for the UITextField as the viewcontroller you're typing the code in. A delegate is responsible for the interaction between the controller and the view. This allows the view controller to manage certain methods of the UITextFieldDelegate

When you declare #property, for example:
#property (weak, nonatomic) UITextField *property;
Compiler create public variable, which you can access by self.property and private variable, which you access with underscore _property.
In your implementation you read private variable by adding underscore.
The delegate is a way for object to inform another object about something. In your example:
self.windDegrees.delegate = self;
self.windDegrees is a text field and this instruction means that this text field (windDegrees) will inform current class (ViewController) that something happened, for example method:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
will be called every time your text fields should return.

You have several things wrong here. Your .h file should be:
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
You do not want to declare all of those unnecessary global variables. You do not need to redefine the standard M_PI macro. And you do not need to tell the world that your class conforms to the UITextField protocol.
In your .m file you should replace this:
#interface ViewController ()
#end
with:
#interface ViewController () <UITextViewDelegate, UITextFieldDelegate>
#end
Also, everywhere you reference one of the generated instance variables for one of your properties, you should change the reference to use the property instead. Example:
Change:
windDegreesFloat = [_windDegrees.text floatValue];
to:
windDegreesFloat = [self.windDegrees.text floatValue];
Do this everywhere you use the underscored variable instead of the property.
The use of self.windDegrees.delegate = self;, for example, is to tell the text field that your view controller (self) will be handling events from the text field.

Thanks for all the feedback. I changed the code with your feedback to following code.
As it worked before, it still does, but with correct(er) coding.
I'm starting to understand why I had to remove the global variables in .h, where to put correct protocol declarations, and also where the _ really stands for. Additional comments or thoughts are welcome. thx all !
//
// ViewController.h
// WindTriangle
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextView *instructionsText;
#property (weak, nonatomic) IBOutlet UITextField *windDegrees;
#property (weak, nonatomic) IBOutlet UITextField *windSpeed;
#property (weak, nonatomic) IBOutlet UITextField *courseDesired;
#property (weak, nonatomic) IBOutlet UITextField *trueAirSpeed;
#property (weak, nonatomic) IBOutlet UITextField *magneticVariation;
#property (weak, nonatomic) IBOutlet UILabel *headingCalculated;
#property (weak, nonatomic) IBOutlet UILabel *groundSpeedCalculated;
- (IBAction)calculatePressed:(id)sender;
#end
And
//
// ViewController.m
// WindTriangle
//
#import "ViewController.h"
#interface ViewController () <UITextViewDelegate, UITextFieldDelegate>
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.windDegrees.delegate = self;
self.windSpeed.delegate = self;
self.courseDesired.delegate = self;
self.trueAirSpeed.delegate = self;
self.magneticVariation.delegate = self;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)calculatePressed:(id)sender {
float windDegreesFloat = [self.windDegrees.text floatValue];
float windSpeedFloat = [self.windSpeed.text floatValue];
float courseDesiredFloat = [self.courseDesired.text floatValue];
float trueAirSpeedFloat = [self.trueAirSpeed.text floatValue];
float magneticVariationFloat = [self.magneticVariation.text floatValue];
float headingCalculatedFloat = ( courseDesiredFloat - magneticVariationFloat ) + ( 180 / M_PI ) * asin(( windSpeedFloat / trueAirSpeedFloat) * sin(( M_PI * ( windDegreesFloat - ( courseDesiredFloat - magneticVariationFloat))) / 180));
NSString * headingCalculatedString = [NSString stringWithFormat:#"%.1f", headingCalculatedFloat];
_headingCalculated.text = headingCalculatedString;
float groundSpeedCalculatedFloat = sqrt(pow( trueAirSpeedFloat , 2) + pow(windSpeedFloat , 2) - (2 * trueAirSpeedFloat *windSpeedFloat * cos((M_PI * ( courseDesiredFloat - windDegreesFloat + ((180 / M_PI) * asin(( windSpeedFloat / trueAirSpeedFloat ) * sin((M_PI * ( windDegreesFloat - courseDesiredFloat )) / 180))))) / 180)));
NSString * groundSpeedCalculatedString = [NSString stringWithFormat:#"%.1f", groundSpeedCalculatedFloat];
_groundSpeedCalculated.text = groundSpeedCalculatedString;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
return [textField resignFirstResponder];
}
#end

Related

Wrong behavior of drawRect of custom UIView inside UITableViewCell

I'm facing a bit complicated (at least it looks like it to me) problem with a custom UIView that I made (called EventBadge).
Here's the code of my custom class:
EventBadge.h
#interface EventBadge : UIView
- (void)setBadgeFillColor:(UIColor *) color;
- (void)setBadgeBorderColor:(UIColor *) color;
- (void)setBadgeIcon:(MyCustomIcons) icon;
#end
EventBadge.m
#implementation EventBadge
UIColor *badgeFillColor;
UIColor *badgeBorderColor;
MyCustomIcons badgeIcon;
- (void)drawRect:(CGRect)rect {
// Gets graphic context
CGContextRef context = UIGraphicsGetCurrentContext();
// Sets fill and border colors for cirlce
CGContextSetFillColor(context, CGColorGetComponents([badgeFillColor CGColor]));
CGContextSetStrokeColor(context, CGColorGetComponents([badgeBorderColor CGColor]));
// Set border line width
CGContextSetLineWidth(context, 2.0);
// Set rect containing circle as inset of rect
CGRect circle = CGRectInset(rect, 1, 1);
// Draw fill and stroke into rect
CGContextFillEllipseInRect(context, circle);
CGContextStrokeEllipseInRect(context, circle);
// Draws icon
[self drawBadgeIconInside:circle];
// Fill graphic context with path
CGContextFillPath(context);
}
/**
* Sets the background color for the badge and forces refresh
*/
- (void)setBadgeFillColor:(UIColor *) color{
badgeFillColor = color;
[self setNeedsDisplay];
}
/**
* Sets the background color for the badge and forces refresh
*/
- (void)setBadgeBorderColor:(UIColor *) color{
badgeBorderColor = color;
[self setNeedsDisplay];
}
/**
* Sets the icon for the badge and forces refresh
*/
- (void)setBadgeIcon:(MyCustomIcons) icon{
badgeIcon = icon;
[self setNeedsDisplay];
}
/**
* Draws the badge icon inside a rectangle
*/
- (void)drawBadgeIconInside:(CGRect) rect {
// Creates the inner rectangle from the original one (20x20)
CGRect iconContainer = CGRectInset(rect, 5, 5);
// Switch on badgeIcon: many different supported types
switch (badgeIcon) {
case EventLocation:
[StyleKit drawIconLocationWithFrame:iconContainer colorBase:[StyleKit blackMP]];
break;
case EventCar:
[StyleKit drawIconCarWithFrame:iconContainer colorBase:[StyleKit blackMP]];
break;
default:
MyLog(MyLogLevelError, #"INVALID MyCustomIcon");
break;
}
}
#end
I have a UITableView that can be filled with three different types of UITableViewCell, let's say TypeA, TypeB and TypeC.
TypeA and TypeB have different elements inside (UILabels, UIViews and so on) and they both have my EventBadge. TypeC is made of standard elements only.
Here's the code for all cell types:
TypeA.h
#interface TypeACell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIView *prevRouteView;
#property (strong, nonatomic) IBOutlet UIView *nextRouteView;
#property (strong, nonatomic) IBOutlet UILabel *addressLabel;
#property (strong, nonatomic) IBOutlet EventBadge *eventBadgeView;
#end
TypeB.h
#interface TypeBCell : UITableViewCell
#property (strong, nonatomic) IBOutlet EventBadge *eventBadgeView;
#property (strong, nonatomic) IBOutlet UIView *prevRouteView;
#property (strong, nonatomic) IBOutlet UIView *nextRouteView;
#property (strong, nonatomic) IBOutlet UILabel *titleLabel;
#property (strong, nonatomic) IBOutlet UILabel *addressLabel;
#property (strong, nonatomic) IBOutlet UILabel *startTime;
#property (strong, nonatomic) IBOutlet UILabel *endTime;
#property (strong, nonatomic) IBOutlet CalendarColorView *calendarColor;
#end
TypeC.h
#interface TypeCCell : UITableViewCell
#property (strong, nonatomic) IBOutlet UIView *routeView;
#property (strong, nonatomic) IBOutlet UILabel *duration;
#property (strong, nonatomic) IBOutlet UILabel *startTime;
#property (strong, nonatomic) IBOutlet UILabel *endTime;
#property (strong, nonatomic) IBOutlet CalendarColorView *calendarColor;
#property (strong, nonatomic) IBOutlet TransportTypeIconView *transportTypeView;
#end
I choose the type of cell inside cellForRowAtIndexPath method of my ViewController looking at the type of object stored in _tableviewData (the array used to fill the tableView). The code looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if([_tableviewData[indexPath.row] isKindOfClass:[EventTypeA class]]){
EventTypeA *event = (EventTypeA *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeACell:event atIndexPath:indexPath];
}
else if([_tableviewData[indexPath.row] isKindOfClass:[EventTypeB class]]) {
EventTypeB *event = (EventTypeB *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeBCell:event atIndexPath:indexPath];
}
else {
EventTypeC *event = (EventTypeC *)_tableviewData[indexPath.row];
return [self tableView:tableView createTypeCCell:event atIndexPath:indexPath];
}
}
Inside each method createTypeXCell I work directly on elements and set their properties. Everything is working as expected except properties set on my custom view. So TypeC works perfectly and everything in TypeA and TypeB works as expected except the settings for colors and icons on my eventBadgeView.
The behaviour that I get is that each eventBadgeView, no matter which UITableViewCell belongs to, gets painted with the properties of the last eventBadgeView being worked (the last item of the array).
If I scroll a little bit up or down the UITableView, enough to render one item, that item gets updated well, with the properties I set previously.
But if I scroll too much everything gets messed up once again.
I've noticed that drawRect gets always called a lot later with regards to setNeedsDisplay and I've learned that this is meant to be like this.
I've read on lots of SO posts (I'm not linking here all of them) and based on those what I've tried to do (with no luck) is:
call [cell.eventBadgeView setNeedsDisplay] inside the method that
creates the cell after setting properties
put all the part of setting cell properties and [cell.eventBadgeView setNeedsDisplay] inside dispatch_async
use a CALayer to "force" drawRect to be executed synchronously
Maybe as I'm new to ObjectiveC I'm missing some basic things, and I have big doubts on my custom EventBadge : UIView class since everything else works fine.
Thanks in advance for the help! :)
You should declare those variables out the implementation body otherwise, they'll be threated like gloabal variables in the .m file (more info about this here)
UIColor *badgeFillColor;
UIColor *badgeBorderColor;
MyCustomIcons badgeIcon;
put them in an interface (inside the .m file or directly in the .h) and declare them as #property
#interface MPEventBadge ()
#property (strong, nonatomic) UIColor *badgeFillColor;
#property (strong, nonatomic) UIColor *badgeBorderColor;
#property (nonatomic) MPInsertEventIcons badgeIcon;
#end
you can then access the variable like
_badgeFillColor = color;

Calculate an equation with input in textfield - Xcode

I'm working on a app in Xcode and have run into a problem.
My app needs to collect input from a TextField (where the user enters information) an put it into my equation & eventually give the user a result.
For example - a
user enters their Weight, Height and Age.
My app then needs to take these inputs and place them into the following equation:
Men: RMR = 66,473 + (13,751*WEIGHT) + (5,0033*HEIGHT) - (6,755*AGE)
But how do I code this? What I have made so far:
My .h file is as follows:
#import <UIKit/UIKit.h>
IBOutlet UITextField *Weight;
IBOutlet UITextField *Height;
IBOutlet UITextField *Age;
IBOutlet UILabel *rectResult;
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *Weight;
#property (weak, nonatomic) IBOutlet UITextField *Height;
#property (weak, nonatomic) IBOutlet UITextField *Age;
#property (weak, nonatomic) IBOutlet UILabel *rectResult;
-(IBAction)calculate:(id)sender;
#end
and my .m file:
#implementation ViewController
-(IBAction)calculate:(id)sender {
float floatRectResult=[Weight.text floatValue]*
[Age.text floatValue];
NSString *stringRectResult=[[NSString alloc]
initWithFormat:#"%1.2f",floatRectResult];
rectResult.text=stringRectResult;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
PS.: Sorry for my English - Can anybody help me? :)
Try something like this:
-(IBAction)calculate:(id)sender {
//66,473 + (13,751*WEIGHT) + (5,0033*HEIGHT) - (6,755*AGE)
float result = (66473 + (13751*[Weight.text floatValue]) + (50033*[Height.text floatValue]) - (6755*[Age.text floatValue]));
rectResult.text = [NSString stringWithFormat:#"%.2f", result];
}
Since you appear to be using some constants, it may be better to #define them so that you can easily change them later. Example:
//Above your implementation
#define kWeightConst 13751.0 //Can be used later as just kWeightConst

Simple math app: answer always equals 1

I'm new to programming so this is probably a result of my illiteracy, but I would appreciate a solution anyways.
I'm trying to make an app that takes the user input from 12 different textfields and feeds out an answer into a label by mathematically altering the user input using Cramer's rule.
So far, I've been trying to multiply the user input from one textfield by the user input from another and feed it out into a label, but whenever I type in my numbers, the product is always 1, and it doesn't print to the label.
Here is my code:
//
// ViewController.h
// Cramer
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
// Objects are given addresses:
#property (weak, nonatomic) IBOutlet UITextField *box_a;
#property (weak, nonatomic) IBOutlet UITextField *box_b;
#property (weak, nonatomic) IBOutlet UILabel *hiLabel;
#property (weak, nonatomic) IBOutlet UIButton *clickButton;
#end
AND
//
// ViewController.m
// Cramer
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (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.
}
// Math takes place:
- (IBAction)clickButton:(id)sender {
NSInteger number1 = [self.box_a.text integerValue];
NSInteger number2 = [self.box_b.text integerValue];
NSInteger prod = number1 * number2;
self.hiLabel.text = [NSString stringWithFormat:#"%#", #(prod)];
}
#end
Thanks
Use %ld as the format specifier in the last statement:
self.hiLabel.text = [NSString stringWithFormat:#"%ld", prod];

iAd error: setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key adView [duplicate]

I'm a beginner in everything programming and have been trying to implement some self learned stuff from the Big Nerd Ranch Books. But I'm really stumped by this problem, and yes, I have searched this and other forums for possible solutions with no success. Here is the code:
ANKYViewController.h:
#import <UIKit/UIKit.h>
#interface ANKYViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *weightFieldDeadlift;
#property (weak, nonatomic) IBOutlet UITextField *repFieldDeadlift;
#property (strong, nonatomic) IBOutlet UILabel *workingOneRMDeadlift;
#property (weak, nonatomic) IBOutlet UITextField *weightFieldBenchPress;
#property (weak, nonatomic) IBOutlet UITextField *repFieldBenchPress;
#property (strong, nonatomic) IBOutlet UILabel *workingOneRMBenchPress;
#property (weak, nonatomic) IBOutlet UITextField *weightFieldSquat;
#property (weak, nonatomic) IBOutlet UITextField *repFieldSquat;
#property (strong, nonatomic) IBOutlet UILabel *workingOneRMSquat;
#property (weak, nonatomic) IBOutlet UITextField *weightFieldMilitaryPress;
#property (weak, nonatomic) IBOutlet UITextField *repFieldMilitaryPress;
#property (strong, nonatomic) IBOutlet UILabel *workingOneRMMilitaryPress;
- (IBAction)calculateOneRM:(id)sender;
#end
ANKYViewController.m:
#import "ANKYViewController.h"
#interface ANKYViewController ()
#end
#implementation ANKYViewController
#synthesize weightFieldDeadlift;
#synthesize repFieldBenchPress;
#synthesize workingOneRMBenchPress;
#synthesize weightFieldSquat;
#synthesize repFieldSquat;
#synthesize workingOneRMSquat;
#synthesize weightFieldMilitaryPress;
#synthesize repFieldMilitaryPress;
#synthesize workingOneRMMilitaryPress;
#synthesize repFieldDeadlift;
#synthesize workingOneRMDeadlift;
#synthesize weightFieldBenchPress;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setWeightFieldDeadlift:nil];
[self setRepFieldDeadlift:nil];
[self setWorkingOneRMDeadlift:nil];
[self setWeightFieldDeadlift:nil];
[self setRepFieldBenchPress:nil];
[self setWeightFieldBenchPress:nil];
[self setWorkingOneRMBenchPress:nil];
[self setWeightFieldSquat:nil];
[self setRepFieldSquat:nil];
[self setWorkingOneRMSquat:nil];
[self setWeightFieldMilitaryPress:nil];
[self setRepFieldMilitaryPress:nil];
[self setWorkingOneRMMilitaryPress:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)calculateOneRM:(id)sender {
float dw = [[weightFieldDeadlift text]floatValue];
float dr = [[repFieldDeadlift text]floatValue];
float d = (dw * dr * 0.0333) + dw;
NSLog(#"Deadlift: %f", d);
NSString *deadlift = [[NSString alloc]initWithFormat:#"%f", d];
[workingOneRMDeadlift setText:deadlift];
float bpw = [[weightFieldBenchPress text]floatValue];
float bpr = [[repFieldBenchPress text]floatValue];
float bp = (bpw * bpr * 0.0333) + bpw;
NSLog(#"Bench Press: %f", bp);
NSString *benchPress = [[NSString alloc]initWithFormat:#"%f", bp];
[workingOneRMBenchPress setText:benchPress];
float sw = [[weightFieldSquat text]floatValue];
float sr = [[repFieldSquat text]floatValue];
float s = (sw * sr * 0.0333) + sw;
NSLog(#"Squat: %f", s);
NSString *squat = [[NSString alloc]initWithFormat:#"%f", s];
[workingOneRMSquat setText:squat];
float mpw = [[weightFieldMilitaryPress text]floatValue];
float mpr = [[repFieldMilitaryPress text]floatValue];
float mp = (mpw * mpr * 0.0333) + mpw;
NSLog(#"Military Press: %f", mp);
NSString *militaryPress = [[NSString alloc]initWithFormat:#"%f", mp];
[workingOneRMMilitaryPress setText:militaryPress];
}
#end
File's owner class is already stated as ANKYViewController. Linking the outlets etc was by control dragging instead of manually coding (I gave up after spending too many hours).
The error:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIApplication 0x6c22e70> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key repsField.'
There's no copy and pasting of code, and it's certainly distressing that there is no mentioning of "repsField"(instead of repFieldxxx) anywhere.
I hope that this is enough information to help lead to a solution, as I've spent days looking through other people's solutions with no success.
Thanks.
Looks like the problem is that someone is accessing the UIApplication instance with a key (repsField) that is not KVC compliant.
Update I don't think you even need to subclass to add a breakpoint. Go to the breakpoint navigator and add a symbolic breakpoint for symbol -[UIApplication setValue:forUndefinedKey:] and then run the application.
I think you can debug it by subclassing UIApplication and set a breakpoint in a dummy override of the setValue:forUndefinedKey: method.
In the file where you call UIApplicationMain add this class:
#interface TestApplication : UIApplication
#end
#implementation TestApplication
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
[super setValue:value forUndefinedKey:key]; // set breakpoint here
}
#end
And then change the third argument to UIApplicationMain to #"TestApplication", for example:
UIApplicationMain(argc, argv, #"TestApplication", NSStringFromClass([AppDelegate class]));
Now run the application and it should break into to debugger and you should be able to see the call stack causing it.
When this error message appears it is very often a bad connection in a xib file or storyboard. I'll guess that this is an old example that has a MainWindow.xib file in it, with the File's Owner set as the UIApplication class. There is most likely a connection in that xib to an outlet called repsField in the File's Owner which, of course, does not match anything in the actual class.

Unrecognized selector sent to instance (UIStepper)

Okay, I know there is a ton of these questions out there, because I've looked and tried some of the solutions. However, many of the ones I tried didn't work or the answer was too over my head for me to really grasp well - I'm a new developer and this is my first app. I learn by learning what not to do at this point.
I have the 'unrecognized selector sent to instance error' on a UIStepper stepperValueChanged setup. Here is the contents of the error message as it is given to me:
[DetailViewController stepperValueChanged]: unrecognized selector sent to instance 0x8637630
I will probably be ripped apart for this, but I can't really understand what's going on here - my only guess so far is to assume it has something to do with the only point in my code where stepperValueChanged exists - under the DetailViewController.h, as placed below:
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>
{
// Create GUI parameters for text fields, text labels, and the stepper:
IBOutlet UITextField *value1;
IBOutlet UITextField *value2;
IBOutlet UITextField *value3;
IBOutlet UISwitch *double_precision;
IBOutlet UILabel *value1_type;
IBOutlet UILabel *value2_type;
IBOutlet UILabel *value3_type;
IBOutlet UILabel *deriv_units;
IBOutlet UILabel *units;
IBOutlet UILabel *result;
IBOutlet UIStepper *stepper;
}
// Define properties of the above GUI parameters:
#property (nonatomic, retain) UITextField *value1;
#property (nonatomic, retain) UITextField *value2;
#property (nonatomic, retain) UITextField *value3;
#property (nonatomic, retain) UILabel *value1_type;
#property (nonatomic, retain) UILabel *value2_type;
#property (nonatomic, retain) UILabel *value3_type;
#property (nonatomic, retain) UILabel *deriv_units;
#property (nonatomic, retain) UILabel *units;
#property (nonatomic, retain) UILabel *result;
// Setup property as instance of UIStepper:
#property (nonatomic, strong) IBOutlet UIStepper *stepper;
// Setup NSString instance for segue linking:
#property (nonatomic, strong) NSString *equationName;
#property (strong, nonatomic) id detailItem;
#property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
// IBActions for the Calculate button and UIStepper instance:
- (IBAction)Calculate:(id)sender;
- (IBAction)stepperValueChanged:(id)sender;
- (IBAction)double_precision:(id)sender;
#end
Any ideas what is going on here? I don't have much of a clue, and if anyone can help explain to me what exactly is in play here while addressing it, I would be more than grateful.
If you need the contents of the implementation file, let me know; I'll edit it in.
Relevant areas of the .m file:
#interface DetailViewController ()
#property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
#end
#implementation DetailViewController
// Synthesize an instance of NSString for segue linking:
#synthesize equationName = _equationName;;
// Synthesize all other variables:
#synthesize value1 = _value1;
#synthesize value2 = _value2;
#synthesize value3 = _value3;
#synthesize value1_type = _value1_type;
#synthesize value2_type = _value2_type;
#synthesize value3_type = _value3_type;
#synthesize deriv_units = _deriv_units;
#synthesize result = _result;
#synthesize units = _units;
#synthesize stepper = _stepper;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
self.title = _equationName;
self.stepper.stepValue = 1;
self.stepper.autorepeat = NO;
self.stepper.continuous = YES;
self.stepper.wraps = YES;
int eqNum;
if ((_equationName = #"Energy-Frequency Relation"))
{
eqNum = 1;
self.stepper.minimumValue = 1;
self.stepper.maximumValue = 3;
}
else if ((_equationName = #"Energy-Frequency-Wavelength Relation"))
{
eqNum = 2;
self.stepper.minimumValue = 1;
self.stepper.maximumValue = 4;
}
// Take _equationName quantization and use it in a switch case to determine the formula that IBAction will use:
if (dflt)
{
switch (eqNum)
{
case 1:
if ((stepper.value = 1))
{
// Change deriv_units appropriately:
self.deriv_units.text = #"Energy (Joules)";
// This is a Planck's constant calculation, we hide the second variable as the constant
// is stored:
self.value2.hidden = YES;
self.value2_type.hidden = YES;
self.value3.hidden = YES;
self.value3_type.hidden = YES;
// Now we set up the parameters of the first entry variable:
self.value1_type.text = #"Frequency (in Hz)";
double frequency = [value1.text doubleValue];
double Planck = 6.626069e-34;
double energy = Planck * frequency;
// Now we set up the return field to return results:
NSString* resultIntermediate = [NSString stringWithFormat:#"%f", energy];
self.units.text = #"J";
}
// Identical function statements under ViewDidLoad truncated
}
bool dflt;
-(IBAction)KeyboardGoAway:(id)sender
{
[self.value1 resignFirstResponder];
[self.value1 resignFirstResponder];
[self.value1 resignFirstResponder];
}
-(IBAction)double_precision:(id)sender
{
// Sets double-float 'truth' value depending on state of UISwitch:
if (double_precision.on)
{
dflt = TRUE;
}
else
{
dflt = FALSE;
}
}
#pragma mark - Calculation runtime
-(IBAction)Calculate:(id)sender
{
// Assigns numerical information to _equationName data -
// switch case can only handle integer literals
// Also handles stepper incrementation and UILabel/UITextView hiding
NSString* resultIntermediate;
self.result.text = resultIntermediate;
}
The trailing colon makes the difference. Your action method is stepperValueChanged:,
but from the error message it seems that you connected the stepper to stepperValueChanged.
There are two reason for these kind of issues.
Probable case 1:
You first declared the function like - (IBAction)stepperValueChanged;
Connected the IBAction to stepper
Changed the method to - (IBAction)stepperValueChanged:(id)sender;
Solution:
Delete old connection in the interface builder and connect it again.
Probable case 2:
In your code you are calling the method using a selector where you written like: #selector(stepperValueChanged)
Solution:
Change the selector like: #selector(stepperValueChanged:)
Usually this means you are missing the method in your .m or you might of misspelled stepperValueChanged.
Edit: Actually, I believe it needs to be stepperValueChanged: with a semicolon.

Resources