Set the tltleColor of a button - ios

My app is crashing when I try to change the color of the text which is inside a button myButton.titleLabel.textColor.
If I do that the app does not crash but the color of the text keeps in blackColor:
[myButton setTitleColor:[UIColor colorWithRed:0.41 green:0.107 blue:0.252 alpha:1.0] forState:UIControlStateNormal];
If I do this other way the app crashes:
.m:
-(IBAction)buttonTapped:(id)sender {
[myButton setTitleColor:myColor forState:UIControlStateNormal];
}
[...]
-(void) viewDidLoad {
myColor = [UIColor colorWithRed:0.41 green:0.107 blue:0.252 alpha:1.0];
}
.h:
UIColor *myColor;
debugger output:
2013-04-20 18:23:45.625 myApp[6291:c07] -[NSShadow set]: unrecognized selector sent to instance 0x753bfd0
2013-04-20 18:23:45.627 myApp[6291:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSShadow set]: unrecognized selector sent to instance 0x753bfd0'
*** First throw call stack:
(0x15bb012 0x12c8e7e 0x16464bd 0x15aabbc 0x15aa94e 0x369c87 0x369f76 0x368cd9 0x36b098 0x25ce6e 0x126a3f 0x12652c 0x1269ba 0x1262b6 0x126994 0x11b0e2 0x11b15c 0x990bc 0x9a227 0x9a8e2 0x1583afe 0x1583a3d 0x15617c2 0x1560f44 0x1560e1b 0x261c7e3 0x261c668 0x20cffc 0x21c2 0x20f5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
How can I solve that? I want to use the second way (if possible).

The color object that you create with colorWithRed:green:blue:alpha: is autoreleased, so by the time buttonTapped: is called, the object has already been deallocated, so you have a pointer that points to garbage data (a dangling pointer).
You could either switch to using ARC (automatic reference counting), and/or create a retained property for myColor. That would look like this in your header:
#property (nonatomic, retain) UIColor *myColor;
Then, instead of setting the instance variable directly, use:
self.myColor = [UIColor colorWithRed:0.41 green:0.107 blue:0.252 alpha:1.0];
in viewDidLoad. If you don't use ARC, don't forget to release the color in dealloc:
- (void)dealloc
{
[_myColor release];
[super dealloc];
}

Related

UILabel in a NSMutableArray unrecognized selector

In my app, I have created a 'NSMutalbeArray', in which I add some 'UILabel'.
I correctly initialize my array :
_pickerMonthLabel = [[NSMutableArray alloc] init];
I correctly add UILabels in my array, but when I want to make some changes to a label, the behavior is strange. For example, I want to change the text color of a label in my array. I do :
[(UILabel *)[_pickerMonthLabel objectAtIndex:i] setTextColor:[UIColor redColor]];
This doesn't look like to work because my app crashes :
-[__NSCFConstantString setTextColor:]: unrecognized selector sent to instance 0x17e8d4
*** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFConstantString setTextColor:]: unrecognized selector sent to instance 0x17e8d4'
But i have no warning when I wrote this line. When I write another kind of line :
(UILabel *)[_pickerMonthLabel objectAtIndex:i].textcolor = [UIColor redColor];
It gives me an error :
Property 'textcolor' not found on object of type 'id'
I don't understand the difference between these two lines, and how to fix my problem...
Thank you in advance for your help.
I guess this is more of a remark, but you could try to use the respondsToSelector: message to check if the instance can handle the message you are trying to send. (This will make sure you don't get an exception) In your case this would be:
if ([[_pickerMonthLabel objectAtIndex:i] respondsToSelector:#selector(setTextColor:)]){
[(UILabel *)[_pickerMonthLabel objectAtIndex:i] setTextColor:[UIColor redColor]];
}
// add this to see what your class is
//else{
// NSLog(#"The class is: %#", [[_pickerMonthLabel objectAtIndex:i] class]);
//}
Hope it helps your debugging.

How to update the selected property of a UIButton using the button's tag

I am trying to update the selected property for a UIButton by using the button’s tag. However, when I select the relevant view in the iOS simulator I get the following error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setSelected:]: unrecognized selector sent to instance 0x995b1e0'
After researching this issue and error, it appears that the UIView object doesn't know what to do with the setSelected method.
Here is my code where I am attempting to update the selected property:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"Documents folder: %#", [self documentsDirectory]);
NSLog(#"Data file path:%#", [self dataFilePath]);
UIButton *januarybtn = (UIButton *)[self.view viewWithTag:1];
[januarybtn setSelected:YES];
}
Also, here are several posts that I have tried to follow when making this update:
UIView viewWithTag 0 problem
Unrecognized selector sent to instance" problem
Thank you in advance for helping me.

NSInvalidArgumentException in Objective C

I'm making a simple calculator and when I use the addition button, the iOS Simulator crashes and I get an NSInvalidArgumentException. What do I do to prevent this from happening?
Error Report:
2013-06-23 17:18:54.574 Tutorial Test (Storyboard)[9744:c07] -[ViewController2 addition]:
unrecognized selector sent to instance 0x75858f0
2013-06-23 17:18:54.577 Tutorial Test (Storyboard)[9744:c07] *** Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController2 addition]:
unrecognized selector sent to instance 0x75858f0'
*** First throw call stack:
(0x1c91012 0x10cee7e 0x1d1c4bd 0x1c80bbc 0x1c8094e 0x10e2705 0x162c0 0x16258 0xd7021
0xd757f 0xd66e8 0x45cef 0x45f02 0x23d4a 0x15698 0x1becdf9 0x1becad0 0x1c06bf5 0x1c06962
0x1c37bb6 0x1c36f44 0x1c36e1b 0x1beb7e3 0x1beb668 0x12ffc 0x1e2d 0x1d55)
libc++abi.dylib: terminate called throwing an exception
(lldb)
Code in ViewController that has this error:
View Controller.h
#import <UIKit/UIKit.h>
//Calculator
#interface ViewController2 : UIViewController{
IBOutlet UITextField *textField1;
IBOutlet UITextField *textField2;
IBOutlet UILabel *label;
}
-(IBAction)addition;
-(IBAction)subtract;
-(IBAction)multiply;
-(IBAction)divide;
-(IBAction)clear;
#end
View Controller.m
//Addition
-(IBAction)plus
{
float a = ([textField1.text floatValue]);
float b = a+([textField2.text floatValue]);
label.text = [[NSString alloc] initWithFormat:#"%2.f", b];
}
You named the method in the .m file plus, rather than addition. That is why the method addition isn't found, and the fix would be to rename the method in the .m file from plus to addition:
//Addition
-(IBAction)addition
{
float a = [textField1.text floatValue];
float b = [textField2.text floatValue];
label.text = [[NSString alloc] initWithFormat:#"%2.f", a+b];
}
Have you allocated an instance of the ViewController2 class?
For example:
ViewController2 *vc2 = [[ViewController2 alloc] init];
[vc2 addition];
Also, if the .m code you posted is the full contents of that file, then you're also missing
-(IBAction)addition {
...
}
You didn't inplement the right method.
You call addition but you never actually implement it. Declaring the method signature in the .h is not enough, you have to code the method.
This means that the selector that you are calling is not available on the class you called it against. The best thing to do is place a breakpoint where the method is being called. Go to the debugger and po your object.
po 0x75858f0
in this instance. However that number could be an object and it could be different. Look at the number in the console.
Make sure the object is of the proper class. Then check that class to make sure it responds to the selector you are calling.
Edit: Your problem is that your plus method should be renamed to addition. The names in the .h must match the names in the .m

About #selector and MVC

What I have:
four TableViewController(A, B, C, D) - which would show four category
of content.
fake TabBarController based on UITabBarController, it
works fine.
What I want to do:
Add a button on ATableView, and it will use a method on my FakeTabBarController (because I want to share the method so I can use it on BTableViewController, CTableViewController rather than duplicate it two or three times)
So I just make the method public (on the .h file), and included the .h file in my ATableViewController. Then,
addTarget:action:forControlEvents: as always, but.. it doesn't work, please help!
Error:
[ATableViewController assisitantButtonPressed:]: unrecognized selector sent to instance 0x715a8d0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ATableViewController assisitantButtonPressed:]: unrecognized selector sent to instance 0x715a8d0'
*** First throw call stack:
(0x1ca1012 0x10dee7e 0x1d2c4bd 0x1c90bbc 0x1c9094e 0x10f2705 0x262c0 0x26258 0xe7021 0xe757f 0xe66e8 0x2ea1d3 0x1c69afe 0x1c69a3d 0x1c477c2 0x1c46f44 0x1c46e1b 0x1bfb7e3 0x1bfb668 0x22ffc 0x1c8d 0x1bb5)
libc++abi.dylib: terminate called throwing an exception
FakeTabBarController.h:
#import <UIKit/UIKit.h>
#interface CustomTabBarController : UITabBarController
- (IBAction)assisitantButtonPressed:(UIButton *)sender;
#end
FakeTabBarController.m:
...
- (IBAction)assisitantButtonPressed:(UIButton *)sender
{
switch ([sender tag]) {
case 0: // AA
NSLog(#"AA");
break;
case 1: // BB
NSLog(#"BB");
break;
default:
break;
}
}
...
ATableViewController.m:
#import "ATableViewController.h"
#import "ATableCell.h"
#import "FakeTabBarController.h"
...
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *AAImage = [UIImage imageNamed:#"search.png"];
UIButton *AAButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width * 0.73, 0, AAImage.size.width, AAImage.size.height)];
[AAButton setTag:0];
[AAButton setImage:searchImage forState:UIControlStateNormal];
[AAButton addTarget:self action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:AAButton];
}
This line
[AAButton addTarget:self action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
sets the target to method assisitantButtonPressed: of self, which is ATableViewController. It throws exception because ATableViewController doesn't have that method. The correct way is to add a weak property to ATableViewController to keep a reference to CustomTabBarController and addTarget to that TabBar, rather than self
#interface ATableViewController
#property (weak, nonatomic) CustomTabBarController* tabBar;
...
#end
#implementation ATableViewController
-(void)viewDidLoad {
[super viewDidLoad];
self.tabBar = <you must somehow obtain the tab bar reference, either here or in init>
...
[AAButton addTarget:self.tabBar action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
...
}
#end
It's good that you're trying to avoid code duplication. However since ATableViewController, BTableViewController, ... are very similar (judging from your question and their naming), you may want to use just one single TableViewController but with different actual data. Besides, if the method assisitantButtonPressed: really belongs to the table view controller and you moved it to the navBar just to avoid code duplication, it is a very bad practice.

How do I incorporate TSPopover into my app so it doesn't cause run-time crash?

I am trying to incorporate TSPopover into my iPad app (XCode 4.6, Storyboards with UITabBarController, iOS 6.2). I have copied the TSPopover code into my app, and picked one controller to start with. On one scene, I have the little 'i' in a circle for the user to tap when they need help (it's going to eventually be localized, thus the need for the help). So, I have this code in -viewDidLoad:
if(tfShopOpens.text.length == 0 || shopCloses.text.length == 0) {
/* (below code copied from the TSPopover demo code)
UIButton *topButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[topButton addTarget:self action:#selector(showPopover:forEvent:) forControlEvents:UIControlEventTouchUpInside];
topButton.frame = CGRectMake(10,10, 300, 30);
[topButton setTitle:#"button" forState:UIControlStateNormal];
topButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[self.view addSubview:topButton];
*/
[boHelpStoreHours addTarget:self action:#selector(showPopover:forEvent:) forControlEvents:UIControlEventTouchUpInside];
This is from the .h file:
- (IBAction)bHelpStoreHours:(UIButton *)sender;
#property (strong, nonatomic) IBOutlet UIButton *boHelpStoreHours;
This is from the Connections Inspector:
This is the error I'm getting when I tap this particular button:
2013-04-02 15:49:48.016 saori[5495:c07] -[PreferencesViewController bHelpStoreHours:]: unrecognized selector sent to instance 0x8a6c510
2013-04-02 15:49:48.019 saori[5495:c07] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PreferencesViewController bHelpStoreHours:]: unrecognized selector sent to instance 0x8a6c510'
* First throw call stack:
(0x26fc012 0x19eae7e 0x27874bd 0x26ebbbc 0x26eb94e 0x19fe705 0x9322c0 0x932258 0x9f3021 0x9f357f 0x9f26e8 0x961cef 0x961f02 0x93fd4a 0x931698 0x2b79df9 0x2b79ad0 0x2671bf5 0x2671962 0x26a2bb6 0x26a1f44 0x26a1e1b 0x2b787e3 0x2b78668 0x92effc 0x222d 0x2155 0x1)
libc++abi.dylib: terminate called throwing an exception
The problem I'm having is that I'm not sure everything is connected correctly to make this work. There are NO comments in the TSPopover code to guide me, so I'm guessing what is needed. I have looked in Google and SO... nothing! What is causing the run-time crash? and how do I fix it?
Your bHelpStoresHours: method may not exist in your #implementation. Make sure you have defined the method in your PreferencesViewController.m file.

Resources