Objective C: Modify Label with name containing string - ios

I want to modify a label in objective C like this:
When pushing a button named "Car" I want the label "pushedCar" to unhide.
Right now it looks like this but its static...
if ([buttonName isEqualToString:#"Car"]) {
self.pushedCar.hidden = NO;}
How can I write something like:
if ([buttonName isEqualToString:#"Car"]) {
self.pushed%#.hidden , buttonName = false;}
It's kind of a stupid example but I need it for something too complex to write down here.
Thanks in advance.
Michael

Change all your button titles like, Car, Van , Bus etc.
then make this as touch up inside method of all them,
-(IBAction) buttonPressed:(UIButton *) pressedButton{
NSString *buttonName = pressedButton.titleLabel.text;
UILabel *label = [self valueForKey:[NSString stringWithFormat:#"pushed%#", buttonName]];
label.hidden = NO;
}

like this?
if ([ButtonName isEqualToString:#"Car"]) {
self.pushedCar.hidden = !self.pushedCar.hidden;
}

use KVC
id name = nil
if(myButtonCurrentTitle isEqualTo:#"Car"]) name = #"Car";
assert(name);
UILabel *label = [self valueForKey:[NSString stringWithFormat:#"pushed%#", name]];
assert([label isKindOfClass:[UILabel class]]);

If you mean "How could I get an object that is related to a string" it would probably be simplest to put the buttons into an NSDictionary so you could do something like
MyButton *button = [buttonDict objectForKey:#"Car"];
but to be honest, your example code doesn't make much sense so I'm finding it hard to know how to write a decent example for you

If I understand it correctly, you want different buttons and labels (e.g. car, horse, cat).
In that case make an NSDictionary with the key being the buttonName (#"Car") and the the object for it the label.
You can write then something like:
UILabel *label = [myDictionary objectForKey:buttonName];
label.hidden = NO; // or label.hidden = !label.hidden;
Hope this helps!

I think you are trying to use Key Value Coding to get the button instance based on some arbitrary string.
You firstly need to expose the button instances using properties:
#interface MyClass : UIView
{
// These are connected using Interface Builder
IBOutlet UIButton *carButton;
IBOutlet UIButton *busButton;
IBOutlet UIButton *bikeButton;
}
#property (string, nonatomic, readonly) UIButton *carButton;
#property (string, nonatomic, readonly) UIButton *busButton;
#property (string, nonatomic, readonly) UIButton *bikeButton;
#end
And you can get the instance of the button using:
NSString *thing = "#car";
UIButton *button = [self valueForKey:[NSString stringWithFormat:#"%#Button", thing]];
[button setHidden:YES];

Related

SetHidden not working

I am trying to show a label for some seconds when i press a button. But the hide function is not working properly.
-(void) hide_label:(NSString *)value{
[value setHidden:YES];
}
Get the error: No Visible #interface for 'NSString' declares the selector 'setHidden:'.
In your example, value is an NSString, not the UILabel. NSString's have no setHidden: method, as the error message suggests.
Instead, you will want to pass in the label itself and then call setHidden:.
So, change the method to:
- (void) hide_label:(UILabel *)label {
[label setHidden:YES];
}
And change all parts of the code that call this method to pass in the UILabel.
NSString is not a subclass of UILabel and does not respond to setHidden: you must call that on the UILabel property itself.
How do you declare your UILabel? It should be something similar to the following if you connect via a nib:
#property (nonatomic, weak) IBOutlet UILabel *label;
or if its created programatically:
#property (nonatomic, strong) UILabel *label;
You can then call setHidden on the label, as it is a property you can use dot syntax:
label.hidden = YES;
You can check its state by using its accessor:
if ([label isHidden]) {
//... do something
}
It might be worth you reading some tutorials on iOS development, Look Here on raywenderlich.com

Retrieving tag from IBOutletCollection of UIButtons

I have an IBOutletCollection of UIButtons. What is the most efficient way of retrieving the tags of any index in my mutableArray of buttons.
#property(retain) IBOutletCollection(UIButton) NSMutableArray *emptySpaces;
This is how my buttons are declared
#property (strong, nonatomic) IBOutlet UIButton *position1;
Ive tried the following. What is it I'm doing wrong? Thank you
if(emptySpaces[0].tag == 1){
}
Or
if([emptySpaces objectAtIndex:0].tag == 1){
}
To answer your initial question, an id which is what NSMutableArray -objectAtIndex: returns, doesn't have a receiver named tag. You should first cast your result to a UIButton before sending the tag message. Like this: ((UIButton *)self.emptySpaces[0]).tag
You could try something like this:
for (UIButton *button in self.emptySpaces) {
if (button.tag == 1) {
}
}

XCode - Referring to a UIImageView variable through another string variable?

Is it possible to use a string variable to refer to a UIImageView variable and change the image? The string variable is created by adding an "s" to the start of the tag of the button pressed. This is also the name of a specific UIImageView.
So one of the UIImageView declared in the .h file looks like this:
#property (retain, nonatomic) IBOutlet UIImageView *s11;
And in the .m file so far:
NSString *lastpressnum = [#(sender.tag) stringValue];
NSString *lastpressed = [NSString stringWithFormat:#"%s%#", "s", lastpressnum];
[lastpressed setImage:image];
KVC is the tool you need.
UIImageView * theImageView = [self valueForKey:lastpressed];
[theImageView setImage:image];

IBOutletCollection of UIButtons is empty after viewDidLoad

As said in the title, my IBOutletCollection of UIButtons is empty after viewDidLoad.
I created a IBOutletCollection of UILabels the same way, and this one is working perfectly.
Any idea how this can be fixed, or where i made a mistake?
Here is the Code:
#property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *lbl_save;
#property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *lbl_cancel;
#property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *lbl_edit;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *btn_changeData;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *btn_save;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *btn_cancel;
The buttons are placed in a xib and linked correctly to the corresponding outlets. Just like the labels.
The time i press the one of the Buttons is the first time, i want to access the Buttons in Code.
for (UIButton *btn in _btn_changeData) {
btn.hidden = NO;
btn.userInteractionEnabled = YES;
}
for (UIButton *btn in _btn_save) {
btn.hidden = YES;
btn.userInteractionEnabled = NO;
}
for (UIButton *btn in _btn_cancel) {
btn.hidden = YES;
btn.userInteractionEnabled = NO;
}
for (UILabel *lbl in _lbl_save) {
lbl.hidden = YES;
}
for (UILabel *lbl in _lbl_cancel) {
lbl.hidden = YES;
}
for (UILabel *lbl in _lbl_edit) {
lbl.hidden = NO;
}
That is also where i got the following Exception and realized, that my Button OUtletcollection is empty.
-[UIButton countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0xa8a8850
I neither overwrite the outletcollection, nor do i change attributes of the buttons.
Its just that the labels are there in the collection and the buttons not. And i have no idea why.
Thx in advance for any help.
Mav
First idea that comes to my mind is that the properties are not correctly synthesized. Is _btn_changeData really the ivar behind btn_changeData property?
Second idea is something I saw while debugging someone else's code. When outlets are incorrectly connected, for example, if the controller references itself, two controller instances can be create. Obviously only of of them will have the outlets connected. Make sure only of instance is created.
For debugging, implementing the setter by yourself might be a good idea.
Edit:
After rereading, the problem is actually different they you say in your question. The error message -[UIButton countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0xa8a8850
doesn't mean that _btn_changeData is an empty array. It means there is a UIButton instead of an array.
Having said this, you should check if you are not overwriting the data in _btn_changeData somewhere.

Possible to use a getter to configure UIButtons an d UIViews in iOS?

I regularly use lazy loading to instantiate custom classes, arrays, etc. The pattern is typically:
#property (strong, nonatomic) Class *class;
...
- (Class *)class
{
if(!_class) _class = [[Class alloc]init];
return _class;
}
Is it possible to use the same pattern to configure UI elements? For example, instead of formatting all my buttons and views in ViewWillAppear, I would like to put the formatting in the getter. For example:
- (UIButton *)button
{
if(!_button) {
_button = [[UIButton alloc]init];
self.button.backgroundColor = [UIColor redColor];
}
return _button;
}
The problem is I am using a storyboard and XCode instantiates the button so asking if it is nill should always return false. So the background will never be changed. If I remove the if-then, then the background will be set every time the getter is accessed which is probably OK but not optimal.
So, how do I use a UI element's getter to configure the element?
If this is really the way you want to do it, just use a BOOL flag. For example:
#interface MyClass() {
BOOL _hasCustomisedButton;
}
#property (strong, nonatomic) UIButton *button;
#end
#implementation MyClass
- (UIButton *)button {
if (_hasCustomisedButton || _button == nil) {
// check for nil button as well in case the nib isn't loaded yet
return _button;
}
[_button setBackgroundColor:[UIColor redColor]];
_hasCustomisedButton = YES;
return _button;
}
#end

Resources