I must be missing something basic here. When I use [NSString stringWithFormat] to set a property of an object that displays in a UITableViewCell, it displays as empty. If I just set the property normally, i.e. property = #"Item One", it displays fine. The code, and result below.
Using this:
Results in:
Yet the log shows:
Which would indicate the property is set. Will someone please take me to school here.
EDIT
Underretaining was the issue.
My prop looked as such: #property (weak, nonatomic) NSString *name
Changing that to: #property (strong, nonatomic) NSString *name
Fixed the issue. I understand that this means I retain a strong reference to this property, but in this particular, is there a "I just graduated college and taught himself Obj-C" explanation as to what was happening in memory to cause this issue?
My first thought, since a constant string works, is that you're under-retaining the name property, although if that's true I'm surprised you aren't crashing.
Edit:
After seeing your code, here's the problem. A weak property only holds a value as long as the value is kept alive elsewhere. A constant string lives forever, so assigning a constant string here worked. But if you assign a calculated value, then nothing owns it, and therefore nothing keeps it alive, and therefore your weak property will end up with nil.
I'm assuming you're assigning name to the text property of a UILabel.
Either the label is:
nil
Hidden (check it's hidden property)
not in the view hierarchy (check it's superview property)
Not big enough to show the text (calling sizeToFit will fix this)
The same color as your background (not likely)
The hardest problem to solve will be if it is nil. You haven't told us where the cell is coming from but here are a few possibilities.
The IBOutlet isn't set in the xib/storyboard
You aren't instantiating it in the correct init method. If you are instantiating it, make sure that specific init variation is being called.
Related
After updating to iOS8.3 I started getting a bunch of new warnings that werent there on iOS8.2. One in particular that caught my eye;
#property (strong, nonatomic) IBOutlet UITableView *tableView;
which was declared in a '.m' file.
What has changed in iOS8.3 to make this a warning?
Auto property synthesis will not synthesize property 'tableView'; it will be implemented by its superclass, use #dynamic to acknowledge intention
If you're using a UITableViewController then tableView is already synthesized. (ie. self.tableView is the tableView of the UITableViewController).
I faced similar issue too. I solved this by the following method. Inside your .m file write #dynamic tableView under the #implementation
I hope your issue will be solved.
What has changed? The compiler has become more clever.
You are probably subclassing UITableViewController.
UITableViewController already has a property named tableView. It is already synthesized or implemented otherwise in UITableViewController. So the warning tells you that you are not getting your own tableView property, but that you are getting the one supplied by UITableViewController.
Obviously if you were not aware of the tableView in UITableViewController, and if you wrongly assumed that this is your property, under your control, there would be trouble. That's why you get a warning. So if that is what you were doing, then your code was always badly broken, and needs fixing.
But if you just have the #property declaration in your code, but you know that it is actually the UITableViewController property, no harm is done, but remove the #property because it is wrong.
Had a similar problem with a custom UITableViewCell creating a new property called imageView. Since a property named imageView already existed, I kept getting the error message. I simply changed the name to projectImageView and it worked.
Now I understand that this question has been asked before, but the answers were unsatisfactory. My issue is that I have a view controller with a view and stuff in it including a label. I added a bunch of code for it and now I'm expanding on it. I now have an issue where I've decided to add another UIView to my interface and it has a label and that label is going to function EXACTLY like a label I have in my first UIView. My problem is that I don't want to have to go in my view controller method and add another line of code each time I manipulate that first label. Is there anyway I can link another label to my initial IBOutlet I have set for my first label? Or do I have to go in my code and add an extra line of code everytime I manipulate that first label?
It depends on what you want to do to that label. If you're looking to change some of the attributes of the label in the same way (e.g., font, text colour, alignment) then you can put both labels in an IBOutletCollection and iterate over the collection in your view controller.
If you want to have different data in the label, but other attributes the same, then you'll need a separate IBOutlet for that label.
You can combine the two techniques as well. e.g.
(interface)
#property (weak, nonatomic) IBOutlet UILabel *firstName;
#property (weak, nonatomic) IBOutlet UILabel *lastName;
#property (strong, nonatomic) IBOutletCollection(UILabel) NSArray *labels;
(implementation)
- (void)viewDidLoad {
[super viewDidLoad];
for (UILabel *aLabel in self.labels) {
// Set all label in the outlet collection to have center aligned text.
[aLabel setTextAlignment = NSTextAlignmentCenter;
}
[self.firstName setText:#"First Name"];
[self.lastName setText:#"Last Name"];
}
Basically the simple answer is no. Whether you use outlets or an outlet collection or tags or whatever, you ultimately have one reference in your code to one label in your interface, and another reference in your code to another reference in your interface. You can compress your mode of expression so as to cycle readily through those references (as suggested in a different answer), but the basic fact is inescapable that, ultimately, the only way to "talk to" a label is through the one reference that points to that label and to that label alone.
The only way of getting around that is not to use direct references at all. For example, a single message can be sent to multiple recipients by using an NSNotification. So you could have two instances of some UILabel subclass of your own, and "shout" to both instances simultaneously by posting a notification from your view controller - the notification is then automatically passed on to both labels, because you have arranged beforehand for them to register for it.
Similarly, another alternative is that you could use key-value observing so that a change in your view controller is automatically propagated to both labels automatically because they "observe" the change, meaning they are sent notifications - really just an inverted form of NSNotification. (If this were Mac OS X, you could make a simpler, safer version of this arrangement by using "bindings".)
However, I really cannot actually recommend that approach. The truth is that we still live in an excruciatingly primitive world of text-based programming, one line at a time, one command at a time, one reference at a time, and we must just bite the bullet and get on with it.
Swift 3, Xcode 8
Create a prototype cell with objects
then add another prototype
It will copy the objects from the first prototype cell.
The new objects will be connected to the same IBOutlet
Also, copy and pasting objects maintains IBActions, but does not maintain IBOutlets.
I hope this answers your question, as none of the other answers had this work around.
I'm trying to change the color of some placeholder text, of a UITextField, but i having problems reaching the text field. I've created a property with Referencing Outlets, like this:
#property (retain, nonatomic) IBOutlet UITextField *usernameField;
But can't reach it with either usernameField or _usernameField. What am i missing?
If you have a property, do NOT synthesize it. That just complicates things, and is no longer needed in Objective C 2.0.
Don't use _usernameField. That bypasses the property getter/setter and accesses the iVar directly.
Use self.usernameField instead. Until you understand the difference, use the property except in the code of a custom getter/setter or dealloc method.
first you should use self.usernameField and second just make sure you assigned the outlet to the UITextField you need to access it in the Interface Builder.
You can check it. Have you connected the outlet of the textfield in the xib file?
I'm having a problem with setText method for UITextView.
As I said on the title, I tried to change a UITextView text by using setText method or change the text property directly. It only works from the second time since the method is called.
My UITextView was an outlet. I even tried to change it's text directly from the owner class or create a method to call from another class, but it behaves the same.
I dont know if I'm doing sth wrong when create it as an outlet, I also tried to set it as nonatomic, strong, weak, retain but I still can't get it.
Any advice for my case? Thanks in advance! :)
EDIT:
I figured it out from David H's answer.
As my app is using tab, first tab is used for searching words, the second one for displaying the meaning, I tried to set the text before the outlet is created (as I haven't clicked the second tab yet). If I click the tab meaning first in order to let the outlet to be created, then it works perfectly.
Thanks for all the answer!
Almost for sure, the first time you try to set it the outlet is nil - not yet set. So add an assert (assert(myTextView) before you set it, or at least a NSLog message. You will surely find that the textView is nil the first time you try.
I've been working on a project for several weeks, and recently implemented a singleton object to assist with saving data. After this was implemented, I've been having issues updating labels inside my main view controller.
For example, I'm trying to update the following labels:
#property (nonatomic, retain) IBOutlet UILabel *numDrinksLabel;
#property (nonatomic, retain) IBOutlet UILabel *BACLabel;
with the following code, which is inside a function that gets called on a button press:
BACLabel.text = [NSString stringWithFormat:#"%.2f", user.BAC];
numDrinksLabel.text = [NSString stringWithFormat:#"(%i)", user.numDrinks];
this code block gives me the runtime error:
-[__NSCFString setText:]: unrecognized selector sent to instance 0x1197ef40
However, the same code block called inside viewDidLoad or viewDidAppear is executed with no problems. Initially this suggested to me that there was a problem with my #property declaration, but I get the same error when I change retain to strong, and when I change to weak, the uilabel object is simply null, which is to be expected but nonetheless very frustrating.
So the question is, why would the label objects become dealloced after the viewDidAppear function?
Any suggestions on how to fix this or further test for the root cause would be greatly appreciated!
It seems that your object which contains the iVars numDrinksLabel and BACLabel does no longer exist when you assign something to the text property of the UILabel objects.
Since this happens after you press a button, you have been in the main event loop before. In this loop, any autorelease object will be released if it is not retained by some object.
Thus it seems to me that the object that has your UILabels as iVars is an autorelease object, and it is not retained because you don't use setter methods like self.BACLabel.text = but simply assign methods as BACLabel.text =.
So try replacing your assignments like BACLabel.text = by setters like self.BACLabel.text =, as sixthcent said.
Please check if the superview of these labels is also declared strong