#import "ActivityViewController.h"
#interface ActivityViewController ()
#property (weak, nonatomic) IBOutlet UIView *clockView;
#property (weak , nonatomic) NSTimer *timer;
#property (weak, nonatomic) IBOutlet UILabel *hoursLabel;
#property (weak, nonatomic) IBOutlet UILabel *minutesLabel;
#property (weak, nonatomic) IBOutlet UILabel *secondsLabel;
#property (weak, nonatomic) IBOutlet UILabel *miliLabel;
#end
#implementation ActivityViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
NSDate *start;
- (IBAction)pause:(UIButton *)sender {
[self.timer invalidate];
}
-(void)startTimer {
start = [[NSDate alloc] init];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:#selector(count) userInfo:nil repeats:true];
}
- (IBAction)startCounting:(UIButton *)sender {
[self startTimer];
}
-(void)count {
NSDate *now = [[NSDate alloc] init];
NSTimeInterval interval = [now timeIntervalSinceDate:start];
self.hoursLabel.text = [NSString stringWithFormat:#"%#", [self hourString:interval]];
self.minutesLabel.text = [NSString stringWithFormat:#"%#", [self minuteString:interval]];
self.secondsLabel.text = [NSString stringWithFormat:#"%#", [self secondString:interval]];
self.miliLabel.text = [NSString stringWithFormat:#"%#", [self miliString:interval]];
}
-(NSString *)hourString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long hours = (interval / 3600);
return [NSString stringWithFormat:#"%0.2ld", hours];
}
-(NSString *)minuteString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long minutes = (interval / 60) % 60;
return [NSString stringWithFormat:#"%0.2ld", minutes];
}
-(NSString *)secondString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long seconds = interval % 60;
return [NSString stringWithFormat:#"%0.2ld", seconds];
}
-(NSString *)miliString:(NSTimeInterval)timeInterval {
NSInteger ms = (fmod(timeInterval, 1) * 100);
return [NSString stringWithFormat:#"%0.2ld", ms];
}
#end
This my whole implementation of the view controller
I try to make a stopwatch, but when I try to make this in objective-C updating UI in miliseconds slows down after 3 seconds and frozes simulator and computer after 6 seconds. Is there any solution? In swift it works very smoothly but when it comes to obj-c I have problem.
I created a new default iOS project in the latest Xcode and copied and pasted and slightly fixed your code - see below. I just wired it up to the default view controller that Xcode creates as part of the project.
I am running this on the oldest mac mini known to man and working on another project while running this one and it gave no trouble at all. See the screenshot. Even after 5m it was still running along just fine. I continued work elsewhere no problem, nothing slowed down. I am sure it must be some other funny issue?
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIView * clockView;
#property (weak, nonatomic) IBOutlet UILabel * hoursLabel;
#property (weak, nonatomic) IBOutlet UILabel * minutesLabel;
#property (weak, nonatomic) IBOutlet UILabel * secondsLabel;
#property (weak, nonatomic) IBOutlet UILabel * miliLabel;
#property (strong, nonatomic) NSTimer * timer;
#property (strong, nonatomic) NSDate * start;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)pause:(UIButton *)sender
{
self.timer.invalidate;
}
-(void)startTimer
{
self.start = [[NSDate alloc] init];
self.timer.invalidate;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:#selector(count:)
userInfo:nil
repeats:true];
}
- (IBAction)startCounting:(UIButton *)sender
{
[self startTimer];
}
- ( void ) count:( NSTimer * ) timer
{
NSDate *now = [[NSDate alloc] init];
NSTimeInterval interval = [now timeIntervalSinceDate:self.start];
self.hoursLabel.text = [NSString stringWithFormat:#"%#", [self hourString:interval]];
self.minutesLabel.text = [NSString stringWithFormat:#"%#", [self minuteString:interval]];
self.secondsLabel.text = [NSString stringWithFormat:#"%#", [self secondString:interval]];
self.miliLabel.text = [NSString stringWithFormat:#"%#", [self miliString:interval]];
}
-(NSString *)hourString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long hours = (interval / 3600);
return [NSString stringWithFormat:#"%0.2ld", hours];
}
-(NSString *)minuteString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long minutes = (interval / 60) % 60;
return [NSString stringWithFormat:#"%0.2ld", minutes];
}
-(NSString *)secondString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long seconds = interval % 60;
return [NSString stringWithFormat:#"%0.2ld", seconds];
}
-(NSString *)miliString:(NSTimeInterval)timeInterval {
NSInteger ms = (fmod(timeInterval, 1) * 100);
return [NSString stringWithFormat:#"%0.2ld", ms];
}
#end
This is some other issue I am sure ... I assume your ActivityViewController just derives straight from a normal UIViewController and that your clockView is not doing anything funny.
Anyhow, see if this helps but I think the issue is elsewhere.
Several things ... you dispatch on the main queue but you are already on the main queue so you are swamping the main queue. Also, you dispatch async so the queue gets clogged pretty soon I think. Still I would think the hardware should be able to handle it actually so I am not entirely sure why it freezes, but I think you need to do it a bit better.
Also, importantly, if you build a stopwatch you should not count yourself. Sure, use a timer to regularly update the stopwatch, but in stead of counting yourself you should use the wall clock for the time. The way you do it now will be very inaccurate and the inaccuracies will accumulate over time.
At present you fire every 10 millis. Maybe fire every 100 and then update your stopwatch but read from the device's internal clock. This in itself is problematic, see How can I get the Correct Current Time in iOS? for some ideas on how to do that.
When the stopwatch starts note the time e.g.
NSDate * start = NSDate.now;
and when the timer fires calculate the difference from this start time using the current time, again with something like
NSDate * now = NSDate.now;
and update your stopwatch with the difference between the two. This will be both easier and more accurate BUT see that link as it is also needs some improvement and is just a starting point for now.
Related
This is a simple program that takes two numbers inputed by the user in two separate text fields and adds them together when the 'Add' button is clicked. The way I have done this is by subclassing NSTextField into a class called MyTextField. I believe my error has something to do with memory leaks, but being an inexperienced programmer, I'm not quite sure how to deal with allocating and deallocating memory.
The problem is: When I click the Add button, it works perfectly. However, when I click it again, it does not show the correct amount. It keeps taking my inputs as nil and outputting 0. I have attached my code.
Note: I know that this is much more complicate than it needs to be! I am simply showing a simpler version of a much more complicated program that displays the exact same error.
MyTextField.h
#import <Cocoa/Cocoa.h>
#interface MyTextField : NSTextField
#property (strong) NSString* number;
#property double dblNum;
-(id)initWithNumber:(NSString *)number;
-(NSString *)getNumber;
-(void)setNumber;
-(double)getDblNum;
-(void)setDblNum;
-(double)calcSum:(MyTextField *)other;
-(NSString *)description;
#end
MyTextField.m
#import "MyTextField.h"
#implementation MyTextField
-(id)initWithNumber:(NSString *)number{
self = [super init];
if (self) {
if ([number length] > 0){
_number = number;
}else{
_number = #"0";
}
[self setDblNum];
}
return self;
}
- (id)init {
return [self initWithNumber:[self getNumber]];
}
-(NSString *)getNumber{
return _number;
}
-(void)setNumber{
_number = [self stringValue];
}
-(double)getDblNum{
return _dblNum;
}
-(void)setDblNum{
_dblNum = [_number doubleValue];
}
-(double)calcSum:(MyTextField *)other{
return [self getDblNum] + [other getDblNum];
}
- (NSString *)description{
return [NSString stringWithFormat: #"Number: %f", _dblNum];
}
#end
ViewController.h
#import <Cocoa/Cocoa.h>
#import "MyTextField.h"
#interface ViewController : NSViewController
#property (strong) IBOutlet MyTextField *valueOne;
#property (strong) IBOutlet MyTextField *valueTwo;
#property (strong) IBOutlet NSTextField *answer;
- (IBAction)btnAdd:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "MyTextField.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
}
- (IBAction)btnAdd:(id)sender {
_valueOne = [[MyTextField alloc] initWithNumber:[_valueOne stringValue]];
_valueTwo = [[MyTextField alloc] initWithNumber:[_valueTwo stringValue]];
double ans = [_valueOne calcSum:_valueTwo];
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
#end
P.S. Sorry for the annoying amount of code. Thanks!
Your btnAdd: is where the problem is.
- (IBAction)btnAdd:(id)sender {
_valueOne = [[MyTextField alloc] initWithNumber:[_valueOne stringValue]];
_valueTwo = [[MyTextField alloc] initWithNumber:[_valueTwo stringValue]];
double ans = [_valueOne calcSum:_valueTwo];
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
Each time the button is tapped, you're recreating both MyTextField instances. Instead, you simply need to get & set the values from your existing valueOne and valueTwo outlets, like:
- (IBAction)btnAdd:(id)sender {
double value1 = [_valueOne.text doubleValue];
double value2 = [_valueTwo.text doubleValue];
double ans = value1 + value2;
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
Obviously, you need to check the validity of the valueOne and valueTwo text strings.
You really don't need a MyTextField subclass, because it's not doing anything except converting strings to doubles (and vice versa).
for a class project we've been asked to create an app. In part my app includes a coin counting app where a random amount is generated and the user is required to click on the coin buttons until the correct amount is reached.
here is the .m code...
//
// CountingChangeViewController.m
// Piggy Bank
//
#import "CountingChangeViewController.h"
#interface CountingChangeViewController ()
//define button connections
- (IBAction)PennyButton:(id)sender;
- (IBAction)NickelButton:(id)sender;
- (IBAction)DimeButton:(id)sender;
- (IBAction)QuarterButton:(id)sender;
- (IBAction)ResetButton:(id)sender;
//define UILable connections
#property (weak, nonatomic) IBOutlet UILabel *labelAmountRequired;
#property (weak, nonatomic) IBOutlet UILabel *labelAmountInBank;
#property (weak, nonatomic) IBOutlet UILabel *labelAmountRemaining;
#property (weak, nonatomic) IBOutlet UILabel *labelCoinCount;
#property (weak, nonatomic) IBOutlet UIImageView *imagePickNewCoin;
#property (weak, nonatomic) IBOutlet UILabel *labelPennyCount;
#property (weak, nonatomic) IBOutlet UILabel *labelNickelCount;
#property (weak, nonatomic) IBOutlet UILabel *labelDimeCount;
#property (weak, nonatomic) IBOutlet UILabel *labelQuarterCount;
#end
//declare class variables
double AmountTotal = 0;
double AmountBank = 0;
double AmountRemaining = 0;
double rNumberMod;
double coinValue;
int coinCount = 0;
int pennyCount = 0;
int nickelCount = 0;
int dimeCount = 0;
int quarterCount = 0;
//start implementation
#implementation CountingChangeViewController
- (void)resetPage{
_imagePickNewCoin.hidden=YES;
//simply generates a new random amount
AmountTotal = [self RandomNumber];
_labelAmountRequired.text = [NSString stringWithFormat:#"$%.2f", AmountTotal];
AmountBank = 0;
_labelAmountInBank.text = [NSString stringWithFormat:#"$%.2f", AmountBank];
AmountRemaining = 0;
_labelAmountRemaining.text = [NSString stringWithFormat:#"$%.2f", AmountRemaining];
coinCount = 0;
_labelCoinCount.text = [NSString stringWithFormat:#"%d", coinCount];
pennyCount = 0;
_labelPennyCount.text = [NSString stringWithFormat:#"%d", pennyCount];
nickelCount = 0;
_labelNickelCount.text = [NSString stringWithFormat:#"%d", nickelCount];
dimeCount = 0;
_labelDimeCount.text = [NSString stringWithFormat:#"%d", dimeCount];
quarterCount = 0;
_labelQuarterCount.text = [NSString stringWithFormat:#"%d", quarterCount];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self resetPage];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)PennyButton:(id)sender {
pennyCount++;
_labelPennyCount.text =[NSString stringWithFormat:#"%d",pennyCount];
coinValue = .01;
[self checkValue];
}
- (IBAction)NickelButton:(id)sender {
if ((AmountRemaining > 0) && (AmountRemaining <= .04))
{
//display the error message
_imagePickNewCoin.hidden=NO;
}
else
{
nickelCount++;
_labelNickelCount.text =[NSString stringWithFormat:#"%d",nickelCount];
coinValue = .05;
[self checkValue];
}
}
- (IBAction)DimeButton:(id)sender {
if ((AmountRemaining > 0) && (AmountRemaining <= .09))
{
//display the error message
_imagePickNewCoin.hidden=NO;
}
else
{
dimeCount++;
_labelDimeCount.text =[NSString stringWithFormat:#"%d",dimeCount];
coinValue = .10;
[self checkValue];
}
}
- (IBAction)QuarterButton:(id)sender {
if ((AmountRemaining > 0) && (AmountRemaining <= .24))
{
//display the error message
_imagePickNewCoin.hidden=NO;
}
else
{
quarterCount++;
_labelQuarterCount.text =[NSString stringWithFormat:#"%d",quarterCount];
coinValue = .25;
[self checkValue];
}
}
-(double)RandomNumber{
int rNumber = arc4random_uniform(99) +1;
double rNumberMod = rNumber * .01;
return rNumberMod;
}
-(void)checkValue {
//hide the error message
_imagePickNewCoin.hidden=YES;
//at button press play coin drop sound
SystemSoundID soundID;
NSString *soundFile = [[NSBundle mainBundle]
pathForResource :#"coin-drop-1" ofType :#"mp3"];
AudioServicesCreateSystemSoundID ((__bridge CFURLRef)
[NSURL fileURLWithPath :soundFile]
, &soundID);
AudioServicesPlaySystemSound (soundID);
//add coinvalue to amountTotal and put the resulting value in the AmountInBank UILabel .text attribute
//this is the math occuring behind the scenes
AmountBank = AmountBank + coinValue;
//this is how the math result shows on the screen
_labelAmountInBank.text = [NSString stringWithFormat:#"$%.2f", AmountBank];
//calculate the amountRemaining and put the resulting value in the AmountRemaining UILabel .text attribute
//this is the math occuring behind the scenes
AmountRemaining = AmountTotal - AmountBank;
//this is how the math result shows on the screen
_labelAmountRemaining.text = [NSString stringWithFormat:#"$%.2f", AmountRemaining];
// increment coin count by one and display it on the screen
coinCount++;
_labelCoinCount.text =[NSString stringWithFormat:#"%d",coinCount];
//test to see if the AmountRemaining = 0
if (AmountRemaining == 0)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"CONGRATULATIONS!" message:#"You saved the correct amount of money! Would you like to try again?" delegate:self cancelButtonTitle:nil otherButtonTitles:#"TRY AGAIN", nil];
[alertView show];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
[self resetPage];
}
- (IBAction)ResetButton:(id)sender {
[self resetPage];
}
#end
Sometimes it works and sometimes it doesn't. It is supposed to bring up an alert view when the amount of change needed reaches 0. Sometimes it does and other times it doesn't. Also when amountRemaining is less than the value of the coin button clicked it is supposed to show a hidden image "imagePickNewCoin" instead of adding the coin's value to the bank amount. Sometimes this works and other times it performes the calculation anyway resulting in a negative value for amountRemaining.
Why would this work sometimes and not other times?
Keep getting a error on the last line #implementation line saying implementation incomplete. Not sure what the problem is. What would cause this? I posted the header too.
Added the rest of the code from the .m file.
#import "mmViewController.h"
#interface mmViewController ()
-(void)timerFired:(NSTimer*)theTimer;
#end
#implementation mmViewController
#synthesize remainingTime, playerScore, scrambledWord;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)viewDidLoad
{
[super viewDidLoad];
//Do any additional setup after loading the view, typically from a nib.
//Initialize the game model
gameModel = [[mmScramblerModel alloc] init];
//Display the time, score and scrambled word
remainingTime.text = [NSString stringWithFormat:#"%i", gameModel.time];
playerScore.text = [NSString stringWithFormat:#"%i", gameModel.score];
scrambledWord.text = [gameModel getScrambledWord];
//Start the game timer
gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timerFired:)
userInfo:nil
repeats:YES];
}
-(void) endGameWithMessage:(NSString *)message {
//Call this method to end the game
//Invalidate the timer
[gameTimer invalidate];
//Show an alert with the results
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Game Over!"
message:message
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
-(void) timerFired:(NSTimer *)theTimer {
//The timer fires this method rougly every second
[gameModel timerTick];
if(gameModel.time <= 0){
remainingTime.text = 0;
[self endGameWithMessage:#"You are out of time. You lose!"];
}
else
remainingTime.text = [NSString stringWithFormat:#"%i", gameModel.time];
}
#end
#import <UIKit/UIKit.h>
#import "mmScramblerModel.h"
#interface mmViewController : UIViewController {
mmScramblerModel* gameModel;
NSTimer* gameTimer;
}
-(IBAction)guessTap:(id)sender;
-(void) endGameWithMessage:(NSString*) message;
#property (weak, nonatomic) IBOutlet UITextField * guessText;
#property (weak, nonatomic) IBOutlet UILabel * scrambledWord;
#property (weak, nonatomic) IBOutlet UILabel * remainingTime;
#property (weak, nonatomic) IBOutlet UILabel * playerScore;
#end
Look at the methods listed in the .h file. Now look at the methods that you actually implemented. SInce there are only two, it's pretty easy to notice that you didn't implement one of them.
Implement the guessTap: method.
From your code i can see the interface declaration of
-(IBAction)guessTap:(id)sender;
But you have not implemented this method in .m file
remove the guessTap: method from interface
Good Morning Guys,
I have a problem. I have an application that do a calculate. If i insert the Label in a same ViewController i watch all.
How do I insert the same Label in another View?
This is the view where there is the calculate.
H.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *textField1;
#property (strong, nonatomic) IBOutlet UITextField *textField2;
#property (strong, nonatomic) IBOutlet UIButton *result;
#property (strong, nonatomic) IBOutlet UIDatePicker *data;
#end
M.
//
// ViewController.m
// IEcigarette
//
// Created by Federico on 24/11/12.
// Copyright (c) 2012 Federico. All rights reserved.
//
#import "ViewController.h"
#import "ResultViewController.h"
#interface ViewController ()
#property (strong, nonatomic) NSString * myString;
#property (strong, nonatomic) UILabel * myLabel;
#end
#implementation ViewController
-(IBAction)calculate:(id)sender{
NSDate *past = _data.date ;
NSDate *now = [NSDate date];
NSCalendar *gregorianCalendar = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSDayCalendarUnit;
NSDateComponents *components = [gregorianCalendar components:unitFlags
fromDate:past
toDate:now
options:0];
int z = [components day];
int a = ([_textField1.text intValue]);
int b = a*([_textField2.text intValue]);
int r = b * z / 20;
_myLabel.text = [[NSString alloc] initWithFormat:#"%d", r];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (BOOL)textFieldShouldReturn:(UILabel *)myLabel {
[myLabel resignFirstResponder];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self performSegueWithIdentifier:#"detail" sender:self];
}
return YES;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
ResultViewController* destVC = (ResultViewController*)segue.destinationViewController;
destVC.myString = self.myLabel.text;
destVC.navigationItem.title = self.myLabel.text;
}
}
#end
Thank you
why you are trying to insert the same label to the another view also. just pass the label.text (string) to another view controller's string. then use that string and create a new label with this string in the viewdidload method . you can also pass the value using nsuserdefaults.
You could keep a reference to it in a shared and call:
[yourLabel removeFromSuperview];
[yourViewController.view addSubview:yourLabel];
for every view controller you want to display it on.
However if what you're sharing is pretty much functioning as a UILabel, I would recommend using separate UILabel instances for each view controller and just sharing the .text value across views. You could pass the value in prepareForSegue, save it to NSUserDefaults, set it as a property of some shared object/singleton.
This question already has answers here:
Xcode - How to fix 'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X" error?
(79 answers)
Closed 7 years ago.
I am writing an app from the Tabbed Application template in xCode.
Without any code, the app will switch tabs with no problems.
After adding code to the first view controller, I get an error when trying to switch tabs.
here is the error message:
2012-04-26 09:43:01.171 Triangle Solver[9516:f803] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TriSecondViewController 0x68827d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key solve.'
*** First throw call stack: (0x13ce022 0x155fcd6 0x13cdee1 0x9c6022 0x937f6b 0x937edb 0x952d50 0x23a71a 0x13cfdea 0x13397f1 0x23926e 0xdf1fc 0xdf779 0xdf99b 0xfb0a9 0xfaedd 0xf94aa 0xf934f 0xfae14 0x13cfe99 0x1b14e 0x1b0e6 0x2434bd 0x13cfe99 0x1b14e 0x1b0e6 0xc1ade 0xc1fa7 0xc1b13 0x245c48 0x13cfe99 0x1b14e 0x1b0e6 0xc1ade 0xc1fa7 0xc1266 0x403c0 0x405e6 0x26dc4 0x1a634 0x12b8ef5 0x13a2195 0x1306ff2 0x13058da 0x1304d84 0x1304c9b 0x12b77d8 0x12b788a 0x18626 0x2a0d 0x2975) terminate called throwing an exception(lldb)
firstViewResponder.h:
#import
#interface TriFirstViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *triText1;
#property (weak, nonatomic) IBOutlet UITextField *triText2;
- (IBAction)calc:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *legA;
#property (weak, nonatomic) IBOutlet UILabel *legB;
#property (weak, nonatomic) IBOutlet UILabel *hypotenuse;
#property (weak, nonatomic) IBOutlet UILabel *angleA;
#property (weak, nonatomic) IBOutlet UILabel *angleB;
#property (weak, nonatomic) IBOutlet UIButton *button1;
#property (copy, nonatomic) NSString *text1;
#property (copy, nonatomic) NSString *text2;
#end
secondViewController.h:
#interface TriSecondViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITextField *sines1;
#property (weak, nonatomic) IBOutlet UITextField *sines2;
#property (weak, nonatomic) IBOutlet UITextField *sines3;
- (IBAction)solve2:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *angleA;
#property (weak, nonatomic) IBOutlet UILabel *sideA;
#property (weak, nonatomic) IBOutlet UILabel *angleB;
#property (weak, nonatomic) IBOutlet UILabel *sideB;
#property (weak, nonatomic) IBOutlet UILabel *angleC;
#property (weak, nonatomic) IBOutlet UILabel *sideC;
#property (weak, nonatomic) IBOutlet UISegmentedControl *segControl;
- (IBAction)aassas:(id)sender;
#property (weak, nonatomic) IBOutlet UILabel *sine1;
#property (weak, nonatomic) IBOutlet UILabel *sine2;
#property (weak, nonatomic) IBOutlet UILabel *sine3;
#end
firstViewController.m:
#interface TriFirstViewController ()
#end
#implementation TriFirstViewController
#synthesize legA;
#synthesize legB;
#synthesize hypotenuse;
#synthesize angleA;
#synthesize angleB;
#synthesize button1;
#synthesize triText1;
#synthesize triText2;
#synthesize text1;
#synthesize text2;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setTriText1:nil];
[self setTriText2:nil];
[self setLegA:nil];
[self setLegB:nil];
[self setHypotenuse:nil];
[self setAngleA:nil];
[self setAngleB:nil];
[self setButton1:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (IBAction)calc:(id)sender
{
double aa = 0;
double ab = 0;
double la = 0;
double lb = 0;
double h = 0;
self.text1 = self.triText1.text;
self.text2 = self.triText2.text;
aa = [self.text1 doubleValue];
lb = [self.text2 doubleValue];
ab = 90 - aa;
la = (tan((aa * (M_PI/180))) * lb);
h = (pow(la, 2) + pow(lb, 2));
h = sqrt(h);
self.legA.text = [NSString stringWithFormat: #"%.2lf", la];
self.legB.text = [NSString stringWithFormat: #"%.2lf", lb];
self.angleA.text = [NSString stringWithFormat: #"%.2lf", aa];
self.angleB.text = [NSString stringWithFormat: #"%.2lf", ab];
self.hypotenuse.text = [NSString stringWithFormat: #"%.2lf", h];
}
#end
secondViewController.m:
#interface TriSecondViewController ()
#end
#implementation TriSecondViewController
#synthesize sine1;
#synthesize sine2;
#synthesize sine3;
#synthesize angleA;
#synthesize sideA;
#synthesize angleB;
#synthesize sideB;
#synthesize angleC;
#synthesize sideC;
#synthesize segControl;
#synthesize sines1;
#synthesize sines2;
#synthesize sines3;
BOOL mode = NO;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[self setSines1:nil];
[self setSine2:nil];
[self setSines3:nil];
[self setAngleA:nil];
[self setAngleB:nil];
[self setAngleC:nil];
[self setSideA:nil];
[self setSideB:nil];
[self setSideC:nil];
[self setSine1:nil];
[self setSine2:nil];
[self setSine3:nil];
[self setSegControl:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
- (IBAction)solve2:(id)sender
{
if (mode)
{
double aa = [self.sines1.text doubleValue];
double ab = [self.sines2.text doubleValue];
double ac = 180 - aa - ab;
double sa = [self.sines3.text doubleValue];
double sb;
double sc;
//convert degrees to radians
aa = (aa * (M_PI/180));
ab = (ab * (M_PI/180));
ac = (ac * (M_PI/180));
sb = (sa/sin(aa))*sin(ab);
sc = (sa/sin(aa))*sin(ac);
self.angleA.text = [NSString stringWithFormat: #"%.2lf", aa];
self.angleB.text = [NSString stringWithFormat: #"%.2lf", ab];
self.angleC.text = [NSString stringWithFormat: #"%.2lf", ac];
self.sideA.text = [NSString stringWithFormat: #"%.2lf", sa];
self.sideB.text = [NSString stringWithFormat: #"%.2lf", sb];
self.sideC.text = [NSString stringWithFormat: #"%.2lf", sc];
}
if (!mode)
{
double aa = [self.sines1.text doubleValue];
double ab;
double ac;
double sa = [self.sines2.text doubleValue];
double sb = [self.sines3.text doubleValue];
double sc;
aa = (aa * (M_PI/180));
ab = asin(sb*(sin(aa)/sa));
ac = 180 - aa - ab;
ac = (ac * (M_PI/180));
sc = (sa/sin(aa))*sin(ac);
self.angleA.text = [NSString stringWithFormat: #"%.2lf", aa];
self.angleB.text = [NSString stringWithFormat: #"%.2lf", ab];
self.angleC.text = [NSString stringWithFormat: #"%.2lf", ac];
self.sideA.text = [NSString stringWithFormat: #"%.2lf", sa];
self.sideB.text = [NSString stringWithFormat: #"%.2lf", sb];
self.sideC.text = [NSString stringWithFormat: #"%.2lf", sc];
}
}
- (IBAction)aassas:(id)sender
{
switch (self.segControl.selectedSegmentIndex) {
case 0:
self.sine1.text = #"Angle A/n";
self.sine2.text = #"Angle B/n";
self.sine3.text = #"Side A/n";
mode = NO;
break;
case 1:
self.sine1.text = #"Angle A/n";
self.sine2.text = #"Side A/n";
self.sine3.text = #"Side B/n";
mode = YES;
break;
default:
break;
}
}
#end
The usual reason for this error is that somewhere in a xib file or storyboard you have a link from some control or view to an IBOutlet called 'solve' but you no longer have that property or variable defined in the code of the class where the link points.
I think you could get the detailed info in Xcode debugger or gdb, the call stack is very important info.
I did it and found the result that a identifier of tableviewcell is wrong.
UIViewController compliant to NSKeyValueCoding protocol, so when set a value for undeined key and you do not override
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
it will arise a NSUndefinedKeyException exception..
[self setTriText1:nil];
[self setTriText2:nil];
[self setLegA:nil];
[self setLegB:nil];
[self setHypotenuse:nil];
[self setAngleA:nil];
[self setAngleB:nil];
[self setButton1:nil];
may be here can brings that exception. why not you write it like this:
self.triText1 = nil;
self.triText2 = nil;
self.legA = nil;
as well for sencondViewContrlloer, if you use "set method" explicitly and write wrong method, similar exception will be happened..