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?
Related
I'm trying to connect the text fields in a sign up form so that, upon done being pressed for each, the next field in the form automatically becomes active. To achieve this, I've extended the UITextField class, as follows, in the view controller for the sign up view.
#interface UITextField (Extended)
#property (nonatomic, weak) IBOutlet UITextField* nextField;
#end
I've then set the nextField outlets via interface builder for each field in the form, and have the following code implemented in the view controller, which is also acting as the delegate for the text fields in the form.
- (BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
UITextField* field = textField.nextField;
if (field)
[field becomeFirstResponder];
return NO;
}
However when building and running the app, it immediately crashes giving the following error :
*** Terminating app due to uncaught exception 'NSUnknownKeyException',
reason:'[<UITextField 0x78729580> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key nextField.'
A bit lost as to how to address this, any help would be appreciated! Thanks in advance.
Just remove all the outlets and recreate them again. You just missed or duplicated one of them, since you have several textfields it is highly possible something has gone awry. And make sure that each nextField really points to next field :)
UPDATE: It's late night so I missed one big problem.
You can't add new properties via category to an existing class like that. The reason is category is not capable of creating a backing variable behind the scenes. (There is a way with associated objects..but it's best not to delve into that black magic.)
Instead of UItextField+extended category, subclass the UITextfield class.
#interface CustomTextField : UITextField
#property (nonatomic, strong) IBOutlet UITextField *nextField;
#end
Then in interface builder, you will have to set that CustomTextfield class in the class inspector for each text field.
The problem is that while you can declare a property in a category, the compiler will not define the property getter and setter for you. You have to define the getter and setter yourself.
You can use an “associated object” to store the property value. See this answer for example code. Since you don't want your nextField property to retain the next field, use OBJC_ASSOCIATION_ASSIGN instead of OBJC_ASSOCIATION_RETAIN_NONATOMIC when setting the associated object.
Quite a simple one I assume but searching has failed me.
I have a UITextView I set up in a Storyboard with some dummy text. Dynamically I would like to change the content of this, but I don't know how. Searching for this seems to only returns results in which the UITextView has been created programmatically as opposed to via a drag and drop on the Storyboard, hence they have direct access to a variable representing it.
Add an outlet to UITextView then changed it dynamically!
Like this:
#property (weak, nonatomic) IBOutlet UITextView *yourText;
self.yourText.text = // ANY TEXT HERE
When using IB in combination with assistant view you control-drag an element in the IB to the .h file and create an outlet. You can drag it to one of 2 place, either inside the variable declaration block or outside the block.
If you drag it inside the variable block you get something like this:
#interface MyViewController : UIViewController {
IBOutlet UIButton *foo;
}
dragging it outside the block gives you something like....
#interface ViewController : UIViewController {
}
#property (retain, nonatomic) IBOutlet UIButton *foo;
I've thought about how they are different and I'm a little confused. Ok, I understand synthesized properties do some magic and create instance variables at runtime (only on 64bit/ARM). So I believe I understand how the 2 options work.
What's the best option though? First option generates less code and seems simpler.
Second version offers public accessors/mutators, but I rarely access outlets from outside my class (and if I do, it's almost always with encapsulation). From the time I've started iOS work I've exclusively used this option.
Am I missing anything or should I make the switch to variable based outlets in most cases?
The ability to declare IBOutlet in the property declaration is relatively new #property (retain, nonatomic) IBOutlet UIButton *foo;
Previously, you had to declare IBOutlet UIButton *foo inside the curly braces and then synthesize the property. Now, declaring the IBOutlet in the curly braces is redundant.
You have two options to declaring the properties now. Option 1 is to declare it in your .h file, which will make it public. Alternatively, you can create a private interface in your .m file using:
#interface MYCLASS()
#end
and declare your properties there. This is my preferred way of doing it unless I need public access to that property (which should be the exception, not the norm if you are obeying MVC conventions).
Short answer: It doesn't make a much of a difference either way.
Long answer: If you want set/mutator methods, then drag outside of the block. If you don't care about methods and are just going to access the variables directly then putting them in as straight variables inside the block is probably the way to go.
Public visibility:
If you just specify the IBOutlet as a variable then you can use #private or #protected to prevent outside access. If you really want a #property for some reason you can still control public visibility by moving the property out of the .h and into a class extension in the .m file.
Conclusion: Myself, I'm sticking with the straight variable declaration and save the other options for when I need something extra.
IBOutlets are best inside of the block, unless you really plan on working with it in the .m file.
Remember, you can have both. The one inside of the variable block is essentially, in all basics, just for when you use it in IBActions.
The property can be used in the .m file for further customization.
Again, you can use both, it just depends on the extent you're using it.
In my nib, I have a UITextView component.
In my code I have a UITextView field and I have used Interface Builder to make sure that the two are connected (at least I think I did that by dragging from "Files Owner" and dropping it on the UITextView in Interface Builder and selecting my member variable).
Now, when I update the text via setText, the UITextView still remains blank.
Thanks
DeShawn
Have you used
#property(nonatomic,retain) UITextView *yourTextViewName;
then
#synthesize yourTextViewName;
in .m file?
If yes, use the following code in viewDidLoad after updating the value to check:
NSLog(#"Text View Value = %#",yourTextViewName.text);
If it isn't figured it out yet;
check out iOS Text View Not Updating
The referencing yourTextViewName must be an IBOutlet UITextView *yourTextViewname
Then add the #property (nonatomic, retain) UITextView *yourTextViewName.
Add the #synthesize yourTextViewName in the corresponding .m file.
To set the text, use
yourTextViewName.text = #"some text";
This may sound crazy, but I had to explicitly set the hidden property of UITextView to NO in code and then it started showing up. See if this works for you.
Objective-C for iPad, Where do you put IBOutlet? In instance variable declaration or #property declaration? Is there a difference at all?
IBOutlet can be a marker on ivars or a property declaration.
There is a slight difference. IBOutlet properties go through access methods whereas IBOutlet ivars are direct ivar access.
The major difference is that if the IBOutlet property is retained, you'll have to release it in -dealloc whereas you typically need not do anything with an IBOutlet ivar. The upside of IBOutlet property is that you get all the useful features of properties.
Both are valid, even if it's usually recommended to put it on a property.
The difference with a property is that it's available from the outside, and that getter/setter methods are used.
That also allows property qualifiers, like non-atomic and retain, usually set for the IBOutlets.
mmalc (who is definitely a reputable source) says that the current best-practice is putting it on the #property declaration. He gives details (along with some cavets) in his answer to this quiestion
Both are valid I suggest you to use #property
I do both, and synthesise it in the .m file. I'm not 100% that they're both essential, but it doesn't hurt.