SetHidden not working - ios

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

Related

Need to connect a UISlider created with Interface Builder to non-event code

I have a ViewController that populates a couple of sliders as so:
// ViewController.h
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UISlider *aSlider;
#property (weak, nonatomic) IBOutlet UISlider *anotherSlider;
#end
// ViewController.m
#interface ViewController ()
#end
#implementation ViewController
-(void)resetSliders
{
NSLog(#"Resetting sliders sl1: %# sl2: %#", self.aSlider, self.anotherSlider);
[self.aSlider setValue:0.5f animated:NO];
[self.anotherSlider setValue:0.5f animated:NO];
}
- (IBAction)setOneSlider:(UISlider *)sender {
NSLog(#"Setting aSlider to %f", sender.value);
self.sl1Val = sender.value;
[self doAThing];
}
- (IBAction)setTwoSlider:(UISlider *)sender {
NSLog(#"Setting anotherSlider to %f", sender.value);
self.sl2Val = sender.value;
[self doBThing];
}
#end
The calls to setOneSlider and setTwoSlider are wired to the value changed events of the two sliders. That works perfectly well. Unfortunately, I have not connected the sliders to their programmatic handles, because the call to resetSliders yields no change in the UI, even with a call added to setNeedsDisplay on the two slider elements.
When resetSliders is called, the log shows:
2015-04-28 12:22:19.608 myApp[4489:681127] Resetting sliders sl1: (null) sl2: (null)
Can anyone indicate to me how to set the self.aSlider and self.anotherSlider with the correct object handles?
To add some color: I have dragged the UI representation of the sliders to their respective #property declarations, and I can see that they have filled-in grey circles in the margin, indicating that they've been wired. The Connections Inspector shows both a "Value Changed" event trigger and a Referencing Outlet connecting myApp to the slider(s).
I'm extremely new to IOS programming and am reaching the limits of learning-by-failing.
The properties should be defined inside the #interface blocks. Yours are currently outside. Additionally, they should probably be weak instead of retain, and no need for the #synthesize statements or the ivars.
Lastly, when you reference them in code, you should do so as self.aSlider, not just aSlider.
It sounds like you still need to connect these outlets in Interface Builder:
#property (retain, nonatomic) IBOutlet UISlider *aSlider;
#property (retain, nonatomic) IBOutlet UISlider *anotherSlider;
Also you don't need to declare properties and ivars for the same sliders. Just declare and use the properties you already have.
#interface ViewController : UIViewController
and
-(void)resetSliders
{
// note the addition of 'self.' below
NSLog(#"Resetting sliders sl1: %# sl2: %#", self.aSlider, self.anotherSlider);
[self.aSlider setTo:0.5f animated:NO];
[self.anotherSlider setTo:0.5f animated:NO];
}

Copy UITextField string to UITextView

How Can I copy UITextField string to UITextView?
I want to do it when UIButton;
[myUIButton addTarget:self action:#selector(touchButton) forControlEvents:UIControlEventTouchUpInside];
UITextField* textField (initialized, omit code here)
[self.view addSubview:textField];
//save string to the property
self.textFieldString = textField.text;
//textFieldString is #property NSString* textFieldString; at the header.
UITextView* textView (initialized, omit code here)
[self.textView setEditable:false];
[self.view addSubview:self.textView];
//here i want to implement UITextField string -> UITextView display
-(void)submitButtonClicked {
//....
//Problem i am having here is that, I can not see instance variable other than #property variable. How should I pass UITextField .text to UITextView?
}
Prepare the identifier to each UI
[textField setTag:100];
[self.view addSubview:textField];
[textView setTag:200];
[self.view addSubview:textView];
Identify the each UI element and Manage
-(void)submitButtonClicked {
//Problem i am having here is that,
// I can not see instance variable other than #property variable.
// How should I pass UITextField .text to UITextView?
UITextField *myTextField=(UITextField*)[self.view viewWithTag:100];
UITextView *myTextView=(UITextView*)[self.view viewWithTag:200];
myTextView.text=myTextField.text;
}
If you are creating UITextView programatically then create a property variable and synthesize the same. You can access the same using the synthesized name and in UIButton action method get the text and set it to UITextView.
In .m file you can declare UITextView as
#interface classname () {
UITextView *textView
}
or in .h file
#property (nonatomic, strong) UITextView *textView;
As you have described the problem 'Problem i am having here is that, I can not see instance variable other than #property variable. How should I pass UITextField .text to UITextView?'
In your button's action use:
textView.text=textField.text;
Declare your variables between #interface and #end and initialize them in the viewDidLoad. This way you'll be able to use them in your button's action.
#interface ViewController ()
{
UITextView *textView;
UITextField *textField;
}
#implementation ViewController
-(void) viewDidLoad
{
// Do the following
// Initialize both textView and textField
// Set their frames
// Add both of them as a subview to your view
}
#end
Now you'll be able to access both of them in your button's action.
Hope this helps.

Custom drawRect: parameter

Is there any way to add a second parameter in a custom UIView class in the drawRect method?
I am currently using a UIView to draw a text string but the text itself is set in the drawRect method. Is there any way to pass in the text variable in something like
- (void) drawRect:(CGRect)rect(NSString *)text
and if not are there any alternative work arounds?
Thanks
You would generally have a custom #property for your UIView subclass:
#property (nonatomic, copy) NSString *text;
You might even have a custom setter that calls setNeedsDisplay, such that when you set the text property, the view's drawRect will get called, e.g.:
- (void)setText:(NSString *)text
{
_text = [text copy];
[self setNeedsDisplay];
}
Your drawRect could then reference self.text when it needs to reference that NSString.

IBOutlet returning nil after IBAction Implementation (IOS)

I have 3 UIButton created through the Interface Builder of Xcode.
Have the IBOutlet and IBAction defined in the Controller.h like this:
#property (strong, nonatomic) IBOutlet UIButton *btnToday;
#property (strong, nonatomic) IBOutlet UIButton *btnToday_less_1;
#property (strong, nonatomic) IBOutlet UIButton *btnToday_less_2;
- (IBAction) setBtnToday: (UIButton *) sender;
- (IBAction) setBtnToday_less_1: (UIButton *) sender;
- (IBAction) setBtnToday_less_2: (UIButton *) sender;
In my Controller.m have this:
#synthesize btnToday;
#synthesize btnToday_less_1;
#synthesize btnToday_less_2;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[btnToday setTitle:#"Today" forState: UIControlStateNormal];
[btnToday_less_1 setTitle:#"Yesterday" forState: UIControlStateNormal];
[btnToday_less_2 setTitle:#"Day before yesterday" forState: UIControlStateNormal];
}
The above code works OK, but if I implement the IBAction it does not.
The implementation looks like this:
-(IBAction)setBtnToday:(UIButton *)sender{ /* a method call */ }
-(IBAction)setBtnToday_less_1:(UIButton *)sender{ /* a method call */ }
-(IBAction)setBtnToday_less_2:(UIButton *)sender{ /* a method call */ }
If I do a NSLog of any of the IBOutlet they return nil. If remove the code of the IBAction from the Controller.m file it starts working again.
What am i doing wrong?
note: does not work means it compile without Errors and run but the text I am trying set on the UIButton are not updated.
You can't override setBtnToday:, setBtnToday_less_1:, and setBtnToday_less_2: like that because those are exactly the setter methods that the runtime is relying on to set up the buttons you configured in your xib file.
When you create a (non readonly) property the compiler synthesizes both a "getter" and "setter" method for your property. By default the getter method is - (<property type>)<property name> and the setter is - (void)set<CamelCase property name>. And those IBAction methods you posted are exactly the setters for your three button properties. By writing them explicitly (and making them do nothing) you're preventing the compiler from synthesizing the default setter implementations and that in turn prevents the xib loading code from working in the expected way.
If you're trying to implement methods to respond to the buttons being tapped you should just name them something else, like - (IBAction)btnTodayTapped:(id)sender, - (IBAction)btnToday_less_1_tapped:(id)sender, etc. Alternatively you could make one method, - (IBAction)buttonTapped:(id)sender and have that method inspect the sender to determine which button was tapped.

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.

Resources