I am stuck at a simple task, I have uilabel on my uiviewcontroller's interface file. I want to update that label via some methods. It doesn't update the label.
.h
UIViewController
{
UILabel *pictureNameLabel;
}
#property (nonatomic, strong) IBOutlet UILabel *pictureNameLabel;
.m
#synthesize pictureNameLabel=_pictureNameLabel;
- (void)viewDidLoad
{
_pictureNameLabel = [[UILabel alloc] init];
_pictureNameLabel.textColor=[UIColor blackColor];
_pictureNameLabel.text=#"Try";
}
How can I fix that issue?
You don't need to alloc the label. It's already alive and get's awaken from the nib.
.h
UIViewController
{
//UILabel *pictureNameLabel;
}
#property (nonatomic, strong) IBOutlet UILabel *pictureNameLabel;
.m
#synthesize pictureNameLabel=_pictureNameLabel;
- (void)viewDidLoad
{
//_pictureNameLabel = [[UILabel alloc] init];
_pictureNameLabel.textColor=[UIColor blackColor];
_pictureNameLabel.text=#"Try";
}
Your direct problem is the line:
_pictureNameLabel = [[UILabel alloc] init];
In -ViewDidLoad. It's creating a new variable, and having the pictureNameLabel property point to it, causing you to lose your reference to the one created in Interface Builder. Remove that line, and everything should work fine.
If you've created an element via Interface Builder, you do not need to alloc & init it yourself, along with adding it to the view in the appropriate spot, as it's automatically done for you, and the property is already set to point to it. If you're manually creating a new view, you do need to do that... but you'd also need to add it somewhere in the view hierarchy as a subview.
Not related to your problem, but you have also created a variable named UILabel *pictureNameLabel;. I'd assume you created this variable to be the backing variable for the synthesized property pictureNameLabel... but, you synthesized that to _pictureNameLabel, which means you now have two variables, _pictureNameLabel and pictureNameLabel. This is almost certainly a mistake. You should either remove the manual definition of pictureNameLabel, or rename it to something distinct if you actually intend to use it separately from the property with the same name. Having it is likely to just lead to confusion & bugs down the road.
your label has already exists on your xib file, and you can set the textcolor, text on interface bulider.
Related
I need to connect an IBOutlet from this UIImageView to my ViewController in order to perform animations on it (just swiping a stone-like block around a grid).
However, I already have a category file that has an (+instancetype) method to create the UIImage programmatically, so I can use it to set an instance variable (usable throughout other files). Problem is (and bear with me because I am new to performing animation methods on movable objects) I can't use that instance variable (which is a UIView*) to do any animations. Actually, let me know if there is a way (to be used with the +(void)animateWithDuration.... method) because it would be beneficial.
+ (instancetype)stoneOneCreator {
UIImage* stoneOneImage = [UIImage imageNamed:#"Stone.png"];
UIImageView* stoneOneView = [[UIImageView alloc] initWithImage:
stoneOneImage];
return stoneOneView;
}
I call this method in my ViewController, set it to an IV, then use that IV throughout the other files where needed.
#implementation
{
UIView* _one;
}
_one = [UIView stoneOneCreator];
Then use _one by passing into other methods that are implemented in other files etc. etc.
My outlet property though when I'm working with the storyboard is
#property (weak, nonatomic) IBOutlet UIImageView* stoneOne;
Is there a way to use the 'stoneOne' property for IV purposes similar to '_one'? Or, is there a way to tie together the '_one' IV with the 'stoneOne' property?
Thanks,
Anthony
I am trying to create a new control for Xcode to implement into a new iOS app. The end idea is to display the formation of a football squad graphically. I realise that this could all be coded programmatically but I want to create a new control to represent a player and then load the formation accordingly as I may add other player information to the control in the future.
I have created a xib view file, in which is a label for displaying their name. I have tried the following but the label's text doesn't show up. Am I missing something obvious?
[I have included the correct headers and have connected the label up and set the xib to the new class]
header file for xib:
#interface playerObject : UIControl
#property (nonatomic, strong) NSString *playerNameLabel;
#end
implementation file for xib:
#import "playerObject.h"
#interface playerObject ()
#property (strong, nonatomic) IBOutlet UILabel *nameLabel;
#end
#implementation playerObject
- (void) setPlayerNameLabel:(NSString *)playerNameLabel
{
self.nameLabel.text = playerNameLabel;
}
View Controller Implementation File:
- (void)viewDidLoad
{
...
playerObject *newPlayer = [[playerObject alloc] initWithFrame:CGRectMake(10, 10, 100, 150)];
[newPlayer setPlayerNameLabel:#"TEST"];
[newPlayer setBackgroundColor:[UIColor redColor]];
[self.view addSubview:newPlayer];
}
Thanks in advance!
You may have created a xib file containing a label however you do not appear to be using it. You are creating a new instance of the playerObject class instead of loading one from a xib file. Take a look at the UINib class documentation instead.
You are instantiating your custom view without loading it from the .xib file.
In order to make it work, follow these steps:
Make your playerObject inherit from UIView instead of UIControl.
Open your .xib file.
Select the root view on the left pane.
On the right pane, switch to the Identity Inspector tab.
Type playerObject into the first text field "Class".
Make sure that you connected all your IBOutlets within Interface Builder.
Do the following to load your custom UIView from the .xib file:
playerObject *newPlayer = (playerObject *)[[[NSBundle mainBundle] loadNibNamed:#"MyXibFilename" owner:nil options:nil] firstObject];
newPlayer.playerNameLabel = #"Lionel Messi";
Note aside: I strongly recommend you to start using "namespaces" for your classes (it's just a two-letter prefix), such as XXPlayerObject, with XX being something else you consider describes your app / module. All other related custom classes should "share" this namespace. Look at what Apple does with its classes.
I hope this helps you!
I am very new to iPhone programming and I have a very basic problem which just confuses me. I declare a public UIScrollView in my header file like this.
#property UIScrollView *scroller;
Then in my implementation file I synthesize it;
#synthesize scroller;
And in the
- (id)initWithFrame:(CGRect)frame
method I allocate my object.
if (self) {
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(23, 99, 280, 300)];
}
( The class is extended from UIView )
But when I try to access this property in a method I always get nil value which just does not make sense.
- (void)DeselectAll{
scroller.hidden = YES;
}
( The scroller is always returning nil here. )
I also try accessing it with self.scroller but the value is still nil. I am sure that I am missing a very simple point but just couldn't figure it out.
( By the way this problem is happening for all my public properties )
Any help is very much appreciated.
Thank you.
First of all, declare the property like below
#property(strong,nonatomic) UIScrollView *scroller;
Now you initialize as
if (self) {
self.scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(23, 99, 280, 300)];
}
Create the UIScrollView in your header file like so :
#interface MyViewController : UIViewController {
UIScrollView * scrollView;
}
#property (nonatomic, retain) IBOutlet UIScrollView * scrollView;
#end
Then initialize it in viewDidLoad:
#synthesize scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc]init(WithFrame:)];
[self.scrollView addSubview:...];
self.scrollView.contentSize = ...;
}
If you are using ARC, I think the properties are getting released.
Just use strong property at the time of declaration.
#property(strong, nonatomic)UIScrollView *scroller;
Ya you have correct. But you had missed memory management to property. Take a look at this.
For example, if you need to hold your created object. you should do this.
For ARC,
#property(strong,nonatomic) UIScrollView *scroller;
withour ARc
#property(retain,nonatomic) UIScrollView *scroller;
Update:
You must assign it using self. Otherwise it will not set via setter method. like as below
if (self) {
self.scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(23, 99, 280, 300)];
}
Ok, here is how i solved this problem. I created these controls in my nib file and assigned the variables as outlets to these objects. In that case the objects are retained and I can access them from my methods. (I tried defining the variables as IBOutlets without assigning to the controls in the nib file and in that case values were returned as nil again. Only after I link them to controls, the objects are retained. ) Although I solved this problem I have difficulty understanding this behaviour. I tried everything recommended in the answers but weirdly I kept getting nil for the object in my method.
Thanks to everyone that has taken time to write a reply to my question. Maybe someone can explain and help me understand this weird behaviour?
Cheers.
Have you checked that initWithFrame: is being called?
If you are creating your UIView subclass in a NIB file then that method won't be called, but initWithCoder: is called instead.
Got away from XCode programming for a while, now I'm starting back and feel like I'm starting ALL over. I have a simple example that's driving me crazy.
I have created a sub class of UIView called Word1View and added it to my storyboard.
I declared it as a property in the main view controller and attached it as an IBOutlet to the main view. I can draw on this view using Core Graphics with no problems (rectangles, lines, etc). Here's the code in the ".h" file. The property is synthesized correctly in the ".m"
#import <UIKit/UIKit.h>
#import "Word1View.h"
#interface Board3ViewController : UIViewController
{
Word1View *word1View;
}
#property (nonatomic, strong) IBOutlet Word1View *word1View;
#end
Now, here's the problem. I have added a UILabel (I will be adding UIImageFiles later)
in Word1View.h it appears as so:
#import <UIKit/UIKit.h>
#interface Word1View : UIView
{
UILabel *testLabel;
}
#property (nonatomic, retain) UILabel *testLabel;
#end
This property is also synthesized correctly. The UILabel was added to the view in the main storyboard. I tried to make this an IBOutlet, but could not hook it up as long as it was part of the subview. I tried to access the UILabel in my main view controller as so:
[super viewDidLoad];
[self.view addSubview:word1View];
NSLog(#"Label text is: %#", word1View.testLabel.text);
I don't have any access to that label as evidenced by the output to NSLog which is:
Board3[14520:c07] Label text is: (null)
I would like to be able to access the label (change its text, properties etc) from my main View Controller.
Any help is greatly appreciated. Thank you.
You need to instantiate your UILabel and give it some text.
wordView1 = [[UILabel alloc] init];
wordView.text = #"Some Text";
I'm getting a bit confused with UIViews recently, I have been using them fine up until this point and they are just refusing to be compliant!
I have a UIViewController, and this contains 5 different views. I have created IBOutlets for these views as I am wanting to swap them at runtime:
IBOutlet UIView *view1;
IBOutlet UIView *view2;
IBOutlet UIView *view3;
IBOutlet UIView *view4;
IBOutlet UIView *view5;
To make them easier to maintain I decided to keep them all within an array, called viewArray. Now I am trying to add the views to the array as follows:
viewArray = [NSArray arrayWithObjects:view1, view2, view3, view4, nil];
This is being called in the init function of my UIViewController class. I have linked up all the IBOutlets to their relevant views in the xib / interface file, but they do not appear to be initialized. Upon further debugging it looks like the views aren't initialized until after the init function is called?
So how can I create an array of these objects? I will need to select the relevant view before the view itself is shown, therefore viewDidLoad is not an option.
I know that you can grab the tags of things and implicitly set them using:
imageExample = (UIImageView *)[self.view viewWithTag:100];
But can this be used to find views, as surely it will be searching for the tags within the originally initialized view (view1)?
Thanks for any help in advanced,
Kind Regards,
Elliott
You can initialize the viewArray lazily, for the price of having to use self.viewArray instead of unqualified viewArray.
Here is how you can do it:
In the .h file:
NSArray* _viewArray;
#property (nonatomic, readonly) NSArray *viewArray;
In the .m file:
-(NSArray*) viewArray {
if (!_viewArray) {
_viewArray = [NSArray arrayWithObjects:view1, view2, view3, view4, nil];
}
return _viewArray;
}