Count - variable as part of object name [duplicate] - objective-c

This question already has answers here:
Objective C Equivalent of PHP's "Variable Variables" [duplicate]
(2 answers)
Closed 8 years ago.
How I can integrate a count var (i = 1,2,3,4,...) into a object-name?
My code doesn't work.
for (int i=1; (i<=4); i++) {
self.cmdFertigOutlet(i).layer.cornerRadius = self.cmdAbbrechenOutlet(i).layer.cornerRadius = self.lblYear(i).layer.cornerRadius = self.lblMonth(i).layer.cornerRadius = self.lblDay(i).layer.cornerRadius = self.lblHour(i).layer.cornerRadius = self.lblMinute(i).layer.cornerRadius = self.lblSecond(i).layer.cornerRadius = self.txtBeschreibung(i).layer.cornerRadius = 5;
}
.h file
#property (weak, nonatomic) IBOutlet UIButton *cmdAbbrechenOutlet1;
#property (weak, nonatomic) IBOutlet UIButton *cmdFertigOutlet1;
#property (weak, nonatomic) IBOutlet UITextField *txtBeschreibung1;
#property (weak, nonatomic) IBOutlet UILabel *lblYear1;
#property (weak, nonatomic) IBOutlet UILabel *lblMonth1;
#property (weak, nonatomic) IBOutlet UILabel *lblDay1;
#property (weak, nonatomic) IBOutlet UILabel *lblHour1;
#property (weak, nonatomic) IBOutlet UILabel *lblMinute1;
#property (weak, nonatomic) IBOutlet UILabel *lblSecond1;
#property (weak, nonatomic) IBOutlet UIButton *cmdAbbrechenOutlet2;
#property (weak, nonatomic) IBOutlet UIButton *cmdFertigOutlet2;
#property (weak, nonatomic) IBOutlet UITextField *txtBeschreibung2;
#property (weak, nonatomic) IBOutlet UILabel *lblYear2;
#property (weak, nonatomic) IBOutlet UILabel *lblMonth2;
#property (weak, nonatomic) IBOutlet UILabel *lblDay2;
#property (weak, nonatomic) IBOutlet UILabel *lblHour2;
#property (weak, nonatomic) IBOutlet UILabel *lblMinute2;
#property (weak, nonatomic) IBOutlet UILabel *lblSecond2;
and so on... 3,4
.m file instead of use this (works), i will use the for-statement. i don't understand, how to put my object-names into an array and then use it with the for-statement.
self.cmdFertigOutlet1.layer.cornerRadius =
self.cmdAbbrechenOutlet1.layer.cornerRadius =
self.lblYear1.layer.cornerRadius =
self.lblMonth1.layer.cornerRadius =
self.lblDay1.layer.cornerRadius =
self.lblHour1.layer.cornerRadius =
self.lblMinute1.layer.cornerRadius =
self.lblSecond1.layer.cornerRadius =
self.txtBeschreibung1.layer.cornerRadius = 5;
self.cmdFertigOutlet1.layer.masksToBounds =
self.cmdAbbrechenOutlet1.layer.masksToBounds =
self.lblYear1.layer.masksToBounds =
self.lblMonth1.layer.masksToBounds =
self.lblDay1.layer.masksToBounds =
self.lblHour1.layer.masksToBounds =
self.lblMinute1.layer.masksToBounds =
self.lblSecond1.layer.masksToBounds =
self.txtBeschreibung1.layer.masksToBounds = YES;
self.cmdFertigOutlet2.layer.cornerRadius =
self.cmdAbbrechenOutlet2.layer.cornerRadius =
self.lblYear2.layer.cornerRadius =
self.lblMonth2.layer.cornerRadius =
self.lblDay2.layer.cornerRadius =
self.lblHour2.layer.cornerRadius =
self.lblMinute2.layer.cornerRadius =
self.lblSecond2.layer.cornerRadius =
self.txtBeschreibung2.layer.cornerRadius = 5;
self.cmdFertigOutlet2.layer.masksToBounds =
self.cmdAbbrechenOutlet2.layer.masksToBounds =
self.lblYear2.layer.masksToBounds =
self.lblMonth2.layer.masksToBounds =
self.lblDay2.layer.masksToBounds =
self.lblHour2.layer.masksToBounds =
self.lblMinute2.layer.masksToBounds =
self.lblSecond2.layer.masksToBounds =
self.txtBeschreibung2.layer.masksToBounds = YES;
The object names are like:
cmdFertigOutlet1, cmdFertigOutlet2, cmdFertigOutlet3, and so on.
cmdAbbrechenOutlet1, cmdAbbrechenOutlet2, cmdAbbrechenOutlet3, and so
on

You can't - the variables' names are compile-time properties and don't exist at runtime.
Instead, use arrays with four elements:
for (int i = 0; i < 4; i++) {
self.cmdFertigOutlet[i].layer.cornerRadius = ...
}

I'm going to give you a simple example using NSTextField objects (to keep it simple). I think you'll understand how to carry this forward in your application.
From your syntax, I also assume you're programming in Swift. To demonstrate a technique:
In my AppDelegate class I declare IBOutlets to 4 text boxes and connect them in IB:
#IBOutlet var testTextBox0:NSTextField!
#IBOutlet var testTextBox1:NSTextField!
#IBOutlet var testTextBox2:NSTextField!
#IBOutlet var testTextBox3:NSTextField!
I also declare a mutable array:
var testTextBoxes:NSMutableArray = NSMutableArray()
Then in the applicationDidFinishLaunching function I say:
testTextBoxes.addObject(testTextBox0)
testTextBoxes.addObject(testTextBox1)
testTextBoxes.addObject(testTextBox2)
testTextBoxes.addObject(testTextBox3)
var localTextField:NSTextField = testTextBox0
for var i:Int = 0; i < 4; i++
{
localTextField = testTextBoxes.objectAtIndex(i) as NSTextField
localTextField.stringValue = "text field \(i)"
}
and all the text box string values get set properly.
This illustrates a technique of loading your objects into an array (or arrays for several different object types) and accessing them sequentially in a for loop.
Here's another example in Objective C using button objects this time:
transformButtons = [[NSMutableArray alloc] initWithCapacity:10]; // transformButtons is an instance variable
[transformButtons addObject:button0];
[transformButtons addObject:button1];
[transformButtons addObject:button2];
[transformButtons addObject:button3];
[transformButtons addObject:button4];
[transformButtons addObject:button5];
[transformButtons addObject:button6];
[transformButtons addObject:button7];
[transformButtons addObject:button8];
[transformButtons addObject:button9];
Then later in the code:
NSButton *localButton;
for(int i = 0; i < 10; i++)
{
localButton = [transformButtons objectAtIndex:i];
[localButton setEnabled:YES];
[localButton setHidden:NO];
[localButton setTitle:buttonNames[i]];
}
Of course in the .h file this stuff was declared as:
NSMutableArray *transformButtons;
IBOutlet NSButton *button0;
IBOutlet NSButton *button1;
IBOutlet NSButton *button2;
IBOutlet NSButton *button3;
IBOutlet NSButton *button4;
IBOutlet NSButton *button5;
IBOutlet NSButton *button6;
IBOutlet NSButton *button7;
IBOutlet NSButton *button8;
IBOutlet NSButton *button9;
Hope this helps.
EDIT2:
In the .h file, if you want to access these variables from another class, why not:
#public
IBOutlet UIButton *cmdAbbrechenOutlet1;
IBOutlet UIButton *cmdFertigOutlet1;
IBOutlet UITextField *txtBeschreibung1;
IBOutlet UILabel *lblYear1;
IBOutlet UILabel *lblMonth1;
IBOutlet UILabel *lblDay1;
IBOutlet UILabel *lblHour1;
IBOutlet UILabel *lblMinute1;
IBOutlet UILabel *lblSecond1;
IBOutlet UIButton *cmdAbbrechenOutlet2;
IBOutlet UIButton *cmdFertigOutlet2;
IBOutlet UITextField *txtBeschreibung2;
IBOutlet UILabel *lblYear2;
IBOutlet UILabel *lblMonth2;
IBOutlet UILabel *lblDay2;
IBOutlet UILabel *lblHour2;
IBOutlet UILabel *lblMinute2;
IBOutlet UILabel *lblSecond2;
// And so on.....
#private
// Your private instance variables
In your .m file cmdAbbrechenOutlet1 could simply be accessed as cmdAbbrechenOutlet1. In another class where yourClass is visible, it could be accessed as yourClass->cmdAbbrechenOutlet1.

Related

Add up different slider values - Objective C

My sliders are located on 10 different views. So, I want the user to be able to select a value with ratingSliderOne, and then move on to "Page 2" and select another value etc. Those values should then be added up to a total
.h
#interface CBViewController : UIViewController
//Scorelabel
#property (nonatomic, readwrite) NSInteger theTotalScore;
#property (strong, nonatomic) IBOutlet UILabel *totalScoreLabel;
// Page 1
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderOne;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelOne;
// Page 2
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderTwo;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelTwo;
// Page 3
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderThree;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelThree;
// Page 4
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderFour;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelFour;
// Page 5
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderFive;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelFive;
// Page 6
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderSix;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelSix;
// Page 7
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderSeven;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelSeven;
// Page 8
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderEight;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelEight;
// Page 9
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderNine;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelNine;
// Page 10
#property (strong, nonatomic) IBOutlet UISlider *ratingSliderTen;
#property (strong, nonatomic) IBOutlet UILabel *repeaterLabelTen;
-(void)updateTotalScores;
- (IBAction)ratingSliderDidChange:(id)slider;
#end
.m
- (IBAction)ratingSliderDidChange:(id)slider
{
int sliderValue1 = self.ratingSliderOne.value;
int sliderValue2 = self.ratingSliderTwo.value;
int total = sliderValue1 + sliderValue2;
self.theTotalScore = total;
NSLog(#"%i, %i, %i", sliderValue1, sliderValue2, total);
[self updateTotalScores];
}
-(void)updateTotalScores{
if (_theTotalScore > 0) {
self.totalScoreLabel.text = [NSString stringWithFormat:#"%i", _theTotalScore];
NSLog(#"%i", _theTotalScore);
}
}
Currently, the NSLog(#"%i, %i, %i", sliderValue1, sliderValue2, total); returns the correc values for each slider. But when you change from page 1 (i.e. ratingSliderOne) to page 2, it "forgets" the value of ratingSliderOne.
EDIT: Added all the code and clarified the question
- (IBAction)ratingSliderDidChange:(id)slider is a delegate callback. It will be fired every time it moves or any other slider connected on the screen moves.
it sounds like what you need is inside this callback to get the value of each slider on the page and create the total each time. Like so:
- (IBAction)ratingSliderDidChange:(id)slider
{
int total = 0;
total += self.ratingSliderOne.value;
total += self.ratingSliderTwo.value;
// etc ....
self.theTotalScore = total;
NSLog(#"%i", _theTotalScore);
[self updateTotalScores];
}

How can I improve my attempt to create protected properties

#import "BGReviewController.h"
#interface BGReviewController (protected)
#property (weak, nonatomic) IBOutlet UIImageView *backgroundImage;
#property (weak, nonatomic) IBOutlet UIButton *dislikeButton;
#property (weak, nonatomic) IBOutlet UIButton *likeButton;
#property (weak, nonatomic) IBOutlet UIButton *post;
#property (weak, nonatomic) IBOutlet UIButton *cancel;
#property (weak, nonatomic) IBOutlet UITextView *textView;
#end
Then I add:
#synthesize backgroundImage = _backgroundImage;
#synthesize dislikeButton = _dislikeButton;
#synthesize likeButton = _likeButton;
#synthesize post = _post;
#synthesize cancel = _cancel;
#synthesize textView = _textView;
And I got error:
/business/Dropbox/badgers/BadgerNew/BGReviewController.m:32:13: Property declared in category 'protected' cannot be implemented in class implementation
Should I declare the synthesize in the implementation file of the category and then put the ivars explicitly?
you cant #synthesize in a category, you have to do the getters and setter manually
check out this answer
Replace
#interface BGReviewController (protected)
With
#interface BGReviewController ()

UITextField bind

I can't figure out why that code is not working for me.
ViewController.h
...
#property (nonatomic, copy) UITextField *textField;
...
ViewController.m
-(void)viewDidLoad
{
[self.textField addTarget:self
action:#selector(textIsChanged:)
forControlEvents:UIControlEventEditingChanged];
}
-(void)textIsChanged:(id)sender;
{
NSLog(#"Changed");
}
When I type something in the textField textIsChanged method is never invoked.
You should declare textField as an IBOutlet like this:
#property (nonatomic, retain) IBOutlet UITextField *textField;
or, if you are using ARC (Automatic Reference Counting):
#property (nonatomic, strong) IBOutlet UITextField *textField;
and bind it from the xib file in interface builder.

UIButton removeFromSuperview

I went through guide from Apple "Your first iOS app"
and now I have a button, which is not declared in ViewController:
#interface HelloWorldViewController : UIViewController <UITextFieldDelegate>
- (IBAction)changeGreeting:(id)sender;
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (copy, nonatomic) NSString *userName;
#end
Now i can remove label (and textField), using [label removeFromSuperview]; but i dont understand how to do it with button. Can someone help?
You should add an IBOutlet to the button as you did for the textfield and the label:
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UIButton *button; // Don't forget to link to this from Interface Builder
// ...
Then you can remove the button using:
[button removeFromSuperview];
Also note that the tutorial you linked to says:
The sender parameter in the action method refers to the object that is sending the action message (in this tutorial, the sender is the button).
So if you want to remove the button when it is tapped (inside changeGreeting:), then you don't need the IBOutlet because you already have a reference to the button in the sender parameter:
- (IBAction)changeGreeting:(id)sender
{
UIButton *button = (UIButton *)sender;
// ...
[button removeFromSuperview];
// ...
}
You need to declare the button in the controller like you did as an IBAction and this time declare this as an Outlet(IBoutlet).. this way you will get its reference in code..
Alternatively .. you can set a tag to the button in Interface Builder
..
and then retrieve in code using viewWithTag: method

IOS 5 error when attempting to set label to hidden [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a label that serves as a warning when certain conditions are not met. But when I attempt to set the label to hidden with the following code:
infoWarning.hidden = YES;
for context, here is the full code:
if (weightC < 50 || (waistM1 < 20 && waistM2 < 20 && waistM3 < 20) || (ageC < 18 ))
{
infoWarning.hidden = NO;
NSString *warning = #"";
if(ageC < 18)
{
warning = #" an age over 17";
}
if (averageWaistM < 20) {
if (warning != #"") {
warning = [NSString stringWithFormat:#"%#, and", warning];
}
warning = [NSString stringWithFormat:#"%# a waist measurement", warning];
}
if (weightC < 50) {
if (warning != #"") {
warning = [NSString stringWithFormat:#"%#, and", warning];
}
warning = [NSString stringWithFormat:#"%# a weight", warning];
}
if (warning!=#"") {
[infoWarning setText:[NSString stringWithFormat:#"Please add%#.", warning]] ;
}
} else {
if(gender.selectedSegmentIndex == 0)
{
}
else if(gender.selectedSegmentIndex == 1)
{
}
}
That I thought would work, but (obviously) does not. It gives me an EXC_BAD_ACCESS error on the line:
infoWarning.hidden = YES;
infoWarning does exist, is synthesized, and is connected to the UILabel in Interface Builder. Could you help me identify the problem and make it work?
This is the .h file:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#class Preferences;
#class Utilities;
#interface BodyFatCalculatorViewController : UIViewController {
IBOutlet UITextField *age;
IBOutlet UITextField *waist1;
IBOutlet UITextField *waist2;
IBOutlet UITextField *waist3;
IBOutlet UITextField *weight;
IBOutlet UILabel *waist;
IBOutlet UILabel *currentWeight;
IBOutlet UILabel *bodyFat;
IBOutlet UILabel *averageWaist;
IBOutlet UILabel *veryLean;
IBOutlet UILabel *veryLeanBorder;
IBOutlet UIImageView *veryLeanCheckmark;
IBOutlet UILabel *fit;
IBOutlet UILabel *fitBorder;
IBOutlet UIImageView *fitheckmark;
IBOutlet UILabel *average;
IBOutlet UILabel *averageBorder;
IBOutlet UIImageView *averageCheckmark;
IBOutlet UILabel *atRisk;
IBOutlet UILabel *atRiskBorder;
IBOutlet UILabel *atModRisk;
IBOutlet UILabel *atModRiskBorder;
IBOutlet UILabel *atHighRisk;
IBOutlet UILabel *atHighRiskBorder;
IBOutlet UILabel *infoWarning;
IBOutlet UISegmentedControl *gender;
NSMutableArray *arrayAge;
}
#property (nonatomic, retain) IBOutlet UITextField *age;
#property (nonatomic, retain) IBOutlet UITextField *waist1;
#property (nonatomic, retain) IBOutlet UITextField *waist2;
#property (nonatomic, retain) IBOutlet UITextField *waist3;
#property (nonatomic, retain) IBOutlet UITextField *weight;
#property (nonatomic, retain) IBOutlet UILabel *waist;
#property (nonatomic, retain) IBOutlet UILabel *currentWeight;
#property (nonatomic, retain) IBOutlet UILabel *bodyFat;
#property (nonatomic, retain) IBOutlet UILabel *averageWaist;
#property (nonatomic, retain) IBOutlet UILabel *veryLean;
#property (nonatomic, retain) IBOutlet UILabel *veryLeanBorder;
#property (nonatomic, retain) IBOutlet UIImageView *veryLeanCheckmark;
#property (nonatomic, retain) IBOutlet UILabel *fit;
#property (nonatomic, retain) IBOutlet UILabel *fitBorder;
#property (nonatomic, retain) IBOutlet UIImageView *fitCheckmark;
#property (nonatomic, retain) IBOutlet UILabel *average;
#property (nonatomic, retain) IBOutlet UILabel *averageBorder;
#property (nonatomic, retain) IBOutlet UIImageView *averageCheckmark;
#property (nonatomic, retain) IBOutlet UILabel *atRisk;
#property (nonatomic, retain) IBOutlet UILabel *atRiskBorder;
#property (nonatomic, retain) IBOutlet UILabel *atModRisk;
#property (nonatomic, retain) IBOutlet UILabel *atModRiskBorder;
#property (nonatomic, retain) IBOutlet UILabel *atHighRisk;
#property (nonatomic, retain) IBOutlet UILabel *atHighRiskBorder;
#property (nonatomic, retain) IBOutlet UILabel *infoWarning;
#property (nonatomic, retain) IBOutlet UISegmentedControl *gender;
-(IBAction)valueChanged:(id)sender;
-(IBAction)textFieldDoneEditing:(id)sender;
-(void)calculate;
#end
Problem has been fixed, thank you to those who responded and looked into it. The problem was actually an array with the limits that were too small (I don't know why that caused this to break, they weren't at all related...) and so I increased the limits and now the infoWarning works great.
The complete error from the console might help but given "EXC_BAD_ACCESS error" in the line
infoWarning.hidden = NO;
suggests that there is a problem with infoWarning.hidden, what are the #property and #synthesize statements?
To compare the contents of strings use:
[warning is equalToString:#""]
not:
warning != #""
which compares the pointers to the strings.
But in your case why not just use:
warning.length != 0