Get label.text from UILabel in an instance method iOS 7 - objective-c

I have a pickerview that displays an array of locations (2 components); below that are 2 UILabels (2 under each component).
When a user opens the app, the picker defaults to the first object in each array in the picker components and changes the label below to reflect that selection.
So it would look something like this:
|PickerComponent1|PickerComponent2|
| Label 1 | Label 2 |
It displays the labels correctly when [viewDidLoad] is called. The labels changed to the appropriate names.
I created an instance method - but I can't pass the text value of the labels to that method.
The log displays (null) and it's coming back as empty.
Any ideas on how I can pass that label text to the method appropriately?
*edit: if I put that code that assigned label1 and the NSLog line into the viewDidLoad method it prints out the label text appropriately. When I put it into the method it does not.
My viewDidLoad in my .m file:
- (void)viewDidLoad
{
//set self as delegate for tripPicker
_tripPicker.delegate = self;
//Set size of tripPicker & datePicker
_tripPicker.transform = CGAffineTransformMakeScale(0.60, 0.60);
_datePicker.transform = CGAffineTransformMakeScale(0.60, 0.60);
//Call method to get array of school names (reusable)
MetaMiles *model = [MetaMiles schoolNameList];
_schoolArray1 = (NSArray *)model;
_schoolArray2 = (NSArray *)model;
//Set date to current date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
_dateLabel.text = [NSString stringWithFormat:#"Date of trip: %#",[dateFormatter stringFromDate:self.datePicker.date ]];
//Set selector method for datePicker so on the value change it updates the date
[self.datePicker addTarget:self action:#selector(updateLabelForDate:) forControlEvents:UIControlEventValueChanged];
[super viewDidLoad];
//Set labels to be appropriate schools
begSchoolLabel.text = [_schoolArray1 objectAtIndex:[_tripPicker selectedRowInComponent:0]];
endSchoolLabel.text = [_schoolArray2 objectAtIndex:[_tripPicker selectedRowInComponent:1]];
//Update the Mileage indicator to display miles between currently selected values
ML54AddMilesViewController *milesObject = [[ML54AddMilesViewController alloc]init];
NSArray *currentMiles = [milesObject getMileage];
NSLog(#"Current Miles first run: %#",currentMiles);
}
My getMileage method:
- (NSArray *)getMileage {
//Update the Mileage indicator to display miles between currently selected values
NSString *begSchool = begSchoolLabel.text;
NSLog(#"FIRE THIS OFF : %#",begSchool);
NSString *endSchool = endSchoolLabel.text;
NSPredicate *milesFilter = [NSPredicate predicateWithFormat:#"beg_school=%# AND end_school=%#", begSchool, endSchool];
NSArray *resultMiles = [MetaMiles MR_findAllWithPredicate:milesFilter];
if (!resultMiles || ![resultMiles count]) {
NSLog(#"Empty Array");
} else {
NSLog(#"Our array is: %#", [resultMiles objectAtIndex:0]);}
return resultMiles;
}

What I ended up doing was instead of using the label to get the text - I just had it nab whatever the picker had chosen. The label updates appropriately but for some reason I couldn't pass it between methods - this other way I was able to do that.

Related

Calculator label string displaying

I'm new to Objective-C and trying to make a calculator. My problem is I can't add the new number when button is pressed to the string no matter what I use (I tried methods appendString/Format and stringByAppendingString/Format).
Inputting numbers. I do the same for every other numbers:
- (IBAction)btn9:(id)sender {
[self tabbedNumber:9];
}
Declare the variable:
#property NSString *labelString;
Getting the number function:
-(void)tabbedNumber:(int)num{
NSString *lblStr = [[NSString alloc]init];
lblStr = [lblStr stringByAppendingString:[#(num) stringValue]];
self.labelString = lblStr;
[self updateText];
}
Displaying on calculator with a label calLabel:
- (void)updateText{
self.calLabel.text = self.labelString;
Best Anwser by #pavelTerziyski:
You keep lblStr = [lblStr stringByAppendingString:[#(num) stringValue]] in the function but the creation of the variable must be in the view didLoad - (void)viewDidLoad { [super viewDidLoad]; self.lblStr = [NSString new]; }
How you get the (int)num - because i tried your code with this and it worked perfectly fine
- (IBAction)buttonAction:(UIButton *)sender {
NSString *lblStr = [[NSString alloc]init];
lblStr = [lblStr stringByAppendingString:sender.titleLabel.text];
self.labelString = lblStr;
[self updateText];
}
- (void)updateText{
self.numberLabel.text = self.labelString;
}
Try this method 👇
- (IBAction)tabbedNumber:(UIButton *)sender{
self.labelString.text = [self.labelString.text stringByAppendingString:sender.titleLabel.text];
}
With this you can add any button's title label text to your label string.
But you should connect number buttons to this method.
if you want to update label with another method try this 👇
- (IBAction)tabbedNumber:(UIButton *)sender{
[self updateText:sender.titleLabel.text];
}
- (void)updateText:(NSString *)tappedNumberString{
self.labelString.text = [self.labelString.text stringByAppendingString:tappedNumberString];
}
Don't forget to connect tabbedNumber method to number Buttons.
Appending something to a new created string is not very useful.
You need to append the integer (as text) to the property labelString which seems to hold the actual value of the label.
-(void)tabbedNumber:(int)num{
self.labelString = [self.labelString stringByAppendingFormat:#"%i", num];
[self updateText];
}

string not populating with array data, even though arrays are not really empty

I am trying to create a non-Document-based application for Mac OS X that randomizes cards for the game of Dominion.
From many of the ones I have tried, the only thing I cannot seem to do is limit the number of sets picked from a selection made by the user, and things worked pretty well in my program, but I am having issues.
I am trying to get the results to print in a custom view, but every time I look at the print preview, nothing shows, except header text, as specified in an NSMutableString.
This piece of code is what is being used to print and is found in MasterViewController:
- (IBAction)print:(id)sender
{
NSMutableString *content = [[NSMutableString alloc] initWithString:#"Cards\r\n\r\n"];
for (int i = 0; i < [supply.game count]; i++)
{
[content appendFormat:#"Card: %# Set: %# Cost: %d\r\n", [supply.game[i] name], [supply.game[i] collection], [supply.game[i] cost]];
}
[content appendFormat:#"\r\n\r\nRequired\r\n\r\n"];
for (int i = 0; i < [[setup supply] count]; i++)
{
NSDictionary* current = [setup supply][i];
NSString* key = [current allKeys][0]; // get the key of the current dictionary must be 0, as there is only one key
int value = [[current valueForKey:key] integerValue]; // variable to hold key value
if (value > 0) {
[content appendFormat:#"%#: %#", key, #"Yes"];
}
else
{
[content appendFormat:#"%#: %#", key, #"No"];
}
}
printView.content = [NSMutableString stringWithString:content];
[printView print:sender];
}
the data initially gets filled into some tableviews, which displays the correct content, and the supply.game array is the exact array that contains cards used for games.
setup is a property that refers to a view controller that populates a table with kinds of cards that may be required for games (e.g. shelters, colonies, ruins, spoils, and potions) and the supply method is supposed to return the array that view controller creates, which is itself not empty, as that table populates properly.
printView is a property that is assigned to a custom view found in MainMenu.xib and is the real view being used to print from.
the printView class looks like this:
header:
#import <Cocoa/Cocoa.h>
#interface PrintView : NSView
{
NSMutableString* content;
}
#property NSMutableString* content;
- (void)drawStringInRect:(NSRect)rect; // method to draw string to page
- (void)print:(id)sender; // method to print
#end
implementation:
#import "PrintView.h"
#implementation PrintView
#synthesize content;
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (void)print:(id)sender
{
[[NSPrintOperation printOperationWithView:self] runOperation];
}
- (void)drawRect:(NSRect)dirtyRect {
NSGraphicsContext *context = [NSGraphicsContext currentContext];
if ([context isDrawingToScreen])
{
}
else
{
[[NSColor whiteColor] set];
NSRect bounds = [self bounds];
if (content == nil || [content length] == 0)
{
NSRectFill(bounds);
}
else
{
[self drawStringInRect:bounds];
}
}
}
- (void)drawStringInRect:(NSRect)rect
{
NSSize strSize; // variable to hold string size
NSPoint strOrigin; // variable used to position text
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:[NSFont fontWithName:#"Helvetica" size:12] forKey:NSFontAttributeName];
[attributes setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName];
strSize = [content sizeWithAttributes:attributes];
strOrigin.x = rect.origin.x + (rect.size.width - strSize.width)/2;
strOrigin.y = rect.origin.y + (rect.size.height - strSize.height)/2;
[content drawAtPoint:strOrigin withAttributes:attributes];
}
#end
When I check the array sizes for printing operation, the size of the arrays is reported as zero, thus resulting in my current problem
If you need more code, here is code from Github, but I do not have the experimental branch up there, which is where the above code came from, though it should not be too different.
The MasterViewController will show how the supply.game array is made and SetupViewController houses the code that is used to determine what is needed in the game, as well as show how the supply array from [setup supply] is being produced.
MasterViewController has also been added as an object to MainMenu.xib, so I do not know if that affects anything.
Any idea of what I need to do?
Edit: Added in info that might be relevant

Select UIPickerview based on matching a string from coredata

I have a form that once a user submits, it should reload the view (but change a few things).
On this form there is a UIPickerview (_tripPicker) that has 2 locations a starting location and an end location (2 components to the pickerview).
I have it saving to the appropriate database and all that - but when it reloads (when the user clicks save) I want the pickerview to 'reset', and the first location (begSchool), to match the users second location (endSchool) that they just saved to coredata.
For example: Lets say user went from PointB to pointC (component 0 & 1 respectively in the pickerview); when they click save, I would like component 0 to display "PointC" and for the second component to just display the list of points to go to (resetting it to how it originally loads).
I've attempted to try and do some of this matching strings, but I'm running into issues with it.
Here is the logic where I do this:
//Save the data & reload View
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
//Reset the pickerview **********THIS LOGIC NEEDS WORK**********
//Check to see if there is previous UserMiles entered - if so, set beg_school to appropriate name
// Get the local context
NSArray *tripsSorted = [UserMiles MR_findAllSortedBy:#"driven_date" ascending:NO];
if (!tripsSorted || !tripsSorted.count){
//if no previous trips have been entered - set the school list to default
begSchoolLabel.text = [_schoolArray1 objectAtIndex:[_tripPicker selectedRowInComponent:0]];
} else {
UserMiles *lastTrip = [tripsSorted objectAtIndex:0];
NSString *preValue = lastTrip.end_school;
begSchoolLabel.text = preValue;
NSUInteger *currentIndex = [_schoolArray1 indexOfObject:preValue]; //Error/warning that incompatible integer to point conversion
[_tripPicker selectRow:currentIndex inComponent:0 animated:YES]; //Error/warning here that incompatible point to integer conversion
NSLog(#"LastTrip.endSchool = %#", lastTrip.end_school);
}
//Set end school labels for the second component in the picker
endSchoolLabel.text = [_schoolArray2 objectAtIndex:[_tripPicker selectedRowInComponent:1]];
NSLog (#"saveInBackground: finished!");
}];
[self.view setNeedsDisplay];
lastTrip.end_school gets me the appropriate name of the school from component 1 of the pickerview, I just need to figure out how to match that with the appropriate value from the array that is loading the pickerview and make it selected in the pickerview. The text currently displays the appropriate name, but the pickerview does not show any change.
Please let me know if I need to clarify or what other code you need to see - thanks in advance.
I was able to solve this by first finding the indexValue in the array by matching the string against the Objects in the array.
I ended up with this:
//Save the data & reload View
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:^(BOOL success, NSError *error) {
//Reset the pickerview **********THIS LOGIC NEEDS WORK**********
//Check to see if there is previous UserMiles entered - if so, set beg_school to appropriate name
// Get the local context
NSArray *tripsSorted = [UserMiles MR_findAllSortedBy:#"driven_date" ascending:NO];
if (!tripsSorted || !tripsSorted.count){
//if no previous trips have been entered - set the school list to default
begSchoolLabel.text = [_schoolArray1 objectAtIndex:[_tripPicker selectedRowInComponent:0]];
} else {
UserMiles *lastTrip = [tripsSorted lastObject];
NSString *preValue = lastTrip.end_school;
begSchoolLabel.text = preValue;
int indexValue = [_schoolArray1 indexOfObject:preValue]; //Compares the preValue string to the strings in the array and finds the indexValue of the right match
[_tripPicker selectRow:indexValue inComponent:0 animated:YES]; //Sets the picker to the appropriate value
NSLog(#"LastTrip.endSchool = %#", lastTrip.end_school);
}
//Set end school labels for the second component in the picker
endSchoolLabel.text = [_schoolArray2 objectAtIndex:[_tripPicker selectedRowInComponent:1]];
NSLog (#"saveInBackground: finished!");
}];
[self.view setNeedsDisplay];

Programmatically change the state of a UIButton

I've got a pop-up view that loads when a user clicks on a TableView with Core Data elements. On the pop-up view I have a label that represents an int value.
The pop-up view has two butons, one for decreasing the value of the label by 1 and one for increasing it by one. So + and -
What I want to do is to disable the minus button if the label's value is 0. What I've tried is:
-(void)viewDidLayoutSubviews{
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
minus.enabled = NO;
else
minus.enabled = YES
}
The problem with my code is that the button stays disabled after I increase the label's value, and it's no longer equal to 0.
Any suggestions?
You should keep a reference to minus button e.g.
#property (strong, nonatomic) IBOutlet UIButton *minusButton;
Set it with a value of your minus button, or connect outlet in Interface Builder
in your action handler for plusButton, do something like that
-(IBAction)plusAction:(id)sender {
//Do your business logic
...
self.minusButton.enabled = YES;
}
//In your minusButton action handler
-(IBAction)minusAction:(id)sender {
//Do your business logic
...
NSString *daString = currentVal.text;
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * myNumber = [f numberFromString:daString];
int number = [myNumber intValue];
if (number==0)
self.minusButton.enabled = NO;
else
self.minusButton.enabled = YES
}
It seems like you have things the other way around. I would take a totally different approach:
Keep an instance variable (which we'll call 'count') in this viewController which holds the number. it can be an NSInteger. now add a target (self) to both buttons with a #selector(buttonPressed:). now this is how this selector should look like:
- (void)buttonPressed:(id)sender{
if (sender==plusButton)
self.count++;
if (sender==minusButton)
self.count--;
label.text = [NSString stringWithFormat:#"%d",self.count];
minusButton.enabled = (self.count>0);
}
I would just do this with a UIStepper, instead of the 2 buttons. You can set properties right in your storyboard/IB file that specify the max and min, increments, and a bunch of other useful things too. There are a couple video tutorials posted on YouTube that probably cover everything you'll need to know to use it.
Also, I have noticed one thing that...
If the button in disabled state and you are trying to change the title of normal state, it wont work.
I had to change the state to enabled and then I could manipulate title and set back to disabled.

Method calls and returns

Can anyone explain this to me please (I'm getting so confused)
i have a button i click the button to call a method (flowCalculaton)
i set a local float var assign a NSTextField to the var to get its contents then retune the value ,
ALl builds and runs fine but i get a value of 0 to the answerText (label)
but if i change float setVolume = 233 ; for example i get 233 shown in the label
- (IBAction)calculate:(id)sender {
AppControls *cal =[[AppControls alloc]init];
float callMethod = [cal flowCalculation] ;
[answerText setFloatValue: callMethod ];
[cal release];
}
- (float) flowCalculation {
float setVolume = [volumeText floatValue];
return setVolume ;
}
if i do this the same call in (flowCalculation) to volumeText gives me the NSTextField value.
- (IBAction)calculate:(id)sender {
//AppControls *cal =[[AppControls alloc]init];
//float callMethod = [cal flowCalculation] ;
[answerText setFloatValue: [volumeText floatValue] ];
// [cal release];
}
Why is it not assigning [volumeText floatValue] to the var within a method please ?
Help appreciated.
What is AppControls and why are you allocating a new instance to do the calculation?
What is volumeText in AppControls, and what would be its value in a newly allocated instance of AppControls?
I'm just guessing, but maybe you meant to do this:
- (IBAction)calculate:(id)sender
{
float callMethod = [self flowCalculation] ;
[answerText setFloatValue: callMethod ];
}
EDIT in reply to comments:
I'm guessing that AppControls is your view controller. So you have an instance of it being displayed to the user, and the user is editing the contents of the text fields in that particular instance of AppControls. When you call AppControls *cal =[[AppControls alloc]init];, you're creating a brand new, empty, instance of AppControls that the user can't even see. So when you try to get the values of the text fields in that new instance, they are empty, because that is not the instance that the user was editing.