Updating same label with new text in ios - ios

I am trying to update label. When I tap on label the text is move to textview then when i click on Done every time new label is created with updated text. What should I do to update same label? I am using `singleton' for doing so.

Try searching about IBOutlets and properties of particular UI Elements. Like, you want to change your .text property of the UILabel in this case. There is absolutely no use for singletons here.

Try to use viewWithTag to get the existing label if you don't have the instance of label.
For example:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(10, 60, 200, 100)];
[self.view addSubview:myView];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, CGRectGetWidth(myView.frame), 50)];
[myLabel setTag:1001]; // We can use this tag to find the label from different place.
[myView addSubview:myLabel];
To find the label
UILabel *mLabel = (UILabel *) [myView viewWithTag:1001];
if (mLabel) {
[mLabel setText:#"Hello"];
}

Related

IOS/Objective-C: Lazy load UILabel

I am creating a label programatically. Unfortunately, I've discovered that every time I update the label, I am creating a new instance. Is there a way to check if a UILabel already exists before you create it?
This is my current code to create label:
UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
If I condition it on following, I get error that it does not recognize label:
for (id percentLabel in self.view.subviews) {
if (![percentLabel isKindOfClass:[UILabel class]]) {
UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
}
percentLabel.textAlignment = NSTextAlignmentCenter;
Thanks for any suggestions.
There are many ways to check the object existence. In your example the if statement will create a label on every single iteration of the for cycle. A fixed version of that code will look like this:
UILabel *percentLabel = nil;
for (id subview in self.view.subviews) {
if ([subview isKindOfClass:[UILabel class]]) {
percentLabel = (UILabel *)subview;
break;
}
}
if (!percentLabel) {
// Label creation code here
}
However I would suggest you to store that label as a property in your view controller and initialize it lazily as it shown below:
...
#property (weak, nonatomic) UILabel *percentLabel;
...
- (UILabel *)percentLabel {
if (!_percentLabel) {
UILabel *percentLabel = /* initialization code here */;
// Add percent label as a subview to your view
_percentLabel = percentLabel;
}
return _percentLabel;
}
Note that I'm storing the property with a weak reference, because your view will actually own that label and keep a strong reference via it's subviews property.
It looks to me like you are looping over your subviews (some of which might not actually be labels) and you are trying to change the text alignment.
There are better ways to keep track of a label instance then looping over the subviews every time, such as setting a class property like:
UILabel *labelToChange;
in your interface decleration in your .h file.
Then in your implementation simply access the label using
labelToChange.textAlignment = NSTextAlignmentCenter;
Just make sure you only [UILabel alloc] init once to initialise an instance of UILabel
It would be easier to set a unique tag to your UILabel that way you do not need to check the class. Remember that there are even UILabel in UITableView, UINavigationBar, and so, and you don't want to mess with those.
So, what you should do is create 2 separate methods: one to create label and be called in viewDidLoad ONCE, and another is to update the label.
Create method:
-(void)createLabels {
UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
percentLabel.tag = 1111; // a unique tag
[self.view addSubview:percentLabel];
}
Update method:
-(void)updateLabelWithText:(NSString*)newText {
UILabel *yourLabel = (UILabel*)[self.view viewWithTag:1111];
yourLabel.text = newText;
}
you can give percentLabel a unique tag value.
then you can use viewWithTag to get percentLabel, like
UILabel *percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
percentLabel.tag = 100;
[self.view addSubview:percentLabel];
//In another method
UILabel *percenLabel = [self.view viewWithTag:100];
if (percentLabel == nil) {
percentLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, height, 280, 20)];
percentLabel.tag = 100;
percentLabel.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:percentLabel];
}
else {
percentLabel.textAlignment = NSTextAlignmentCenter;
}

SetLeftView In Label Objective-C

it has been asked before (using textfield, and I'm asking how to include a character not a small icon), and yes I have already tried using this SetLeftView to put a dollar sign '$' or whatever character I want beside the TEXTFIELD.
However, I do not want a textfield, but a label, and when I apply the same code to do what I want, it returns me an error, I mean Xcode fails to build the code.
Here is my code:
// We add a label to the top that will display the results
self.resultLabel = [[UILabel alloc] initWithFrame:CGRectMake(25, 80, TEXTAREA_WIDTH, TEXTAREA_HEIGHT)];
[resultLabel setBackgroundColor:[UIColor clearColor]];
[resultLabel setText:#"01234"];
[resultLabel setFont:[UIFont fontWithName:#"AppleGothic" size:30.0f]];
resultLabel.textColor = RGB(255,255,255);
resultLabel.textAlignment = NSTextAlignmentCenter;
// Add it to the view
[self.view addSubview:resultLabel];
UILabel *dollarSignLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 80, 25, 40)];
dollarSignLabel.text = #"$";
dollarSignLabel.textColor = RGB(255,255,255);
[dollarSignLabel setFont:[UIFont fontWithName:#"AppleGothic" size:30.0f]];
[resultLabel setLeftView:dollarSignLabel];
[resultLabel setLeftViewMode:UITextFieldViewModeAlways];
Error: No visible #interface for 'UILabel' declares the selector
'setLeftView'. Same error in the line of setLeftViewMode.
Again, this works if I use a textfield.
My working code (using textfield)
// adding a textField for input
UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(viewHalf-30, 100, 200, 40)];
[myTextField setBackgroundColor:[UIColor clearColor]];
[myTextField setText:#"0"];
[myTextField setFont:[UIFont fontWithName:#"AppleGothic" size:30.0f]];
myTextField.textColor = RGB(255,255,255);
[[self view] addSubview:myTextField];
UILabel *dollarSignLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 25, 40)];
dollarSignLabel.text = #"$";
dollarSignLabel.textColor = RGB(255,255,255);
[dollarSignLabel setFont:[UIFont fontWithName:#"AppleGothic" size:30.0f]];
[myTextField setLeftView:dollarSignLabel];
[myTextField setLeftViewMode:UITextFieldViewModeAlways];
The reason you can't apply that because UILabel doesn't have a method named setLeftView as UITextField do.
What you can do is :
Create two labels next to each other.
Set left labels trailingSpace to right label to 0. Arrange other constraints whatever you want.
Set left label's textAlingment property to NSTextAlignmentRight and right label's to NSTextAlignmentLeft.
Set dolar sign on a left label and numbers to another.
Since a label isn't editable by the user anyway, there is no reason not just to add your $ sign to the label itself.
label.text = [#"$" stringByAppedingString:yourText];
if the special symbol should be an image instead, then look at NSTextAttachment & draw attributed Text
hope this will help u out.
add a dollar image on your label.
override following method of UILabel
-(CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
bounds.origin.x =+leftMargin;
return bounds;
}
- (void)drawTextInRect:(CGRect)rect
{
[super drawTextInRect: CGRectInset(self.bounds, leftMargin , 0)];
}

UITextFields aren't allowing me to edit text

I've programmatically created two UITextFields in my iOS app, and set their text to the _minPrice and _minPrice variables, respectively.
The _minPrice and _maxPrice values appear correctly in the two fields, but tapping on them doesn't allow the user to edit them, they just remain those static values, backspacing doesn't work. Is there anything about my code thats preventing the text fields from being edited?
// Min Price
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(-25, -76, 70, 30)];
tf.textColor = [UIColor blackColor];
tf.font = [UIFont fontWithName:#"Helvetica-Neue" size:14];
tf.backgroundColor=[UIColor whiteColor];
tf.text= _minPrice;
tf.textAlignment = NSTextAlignmentCenter;
tf.layer.cornerRadius=8.0f;
tf.layer.masksToBounds=YES;
tf.layer.borderColor=[[UIColor lightGrayColor]CGColor];
tf.layer.borderWidth= 1.0f;
// Max Price
UITextField *tf1 = [[UITextField alloc] initWithFrame:CGRectMake(100, -76, 70, 30)];
tf1.textColor = [UIColor blackColor];
tf1.font = [UIFont fontWithName:#"Helvetica-Neue" size:14];
tf1.backgroundColor=[UIColor whiteColor];
tf1.text= _maxPrice;
tf1.textAlignment = NSTextAlignmentCenter;
tf1.layer.cornerRadius=8.0f;
tf1.layer.masksToBounds=YES;
tf1.layer.borderColor=[[UIColor lightGrayColor]CGColor];
tf1.layer.borderWidth= 1.0f;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(100, 200, 400, 400)];
[view addSubview:tf];
[view addSubview:tf1];
[self.view addSubview:view];
Your issue is clearly the frames you're setting...
Setting the color of the view you add the labels to to blue reveals your problem:
If you ensure that the labels are actually within the view you add them to (i.e. not negative), editing will be fine. All I did was change the negative x and y values in tf to positive, and they were editable:
UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(25, 76, 70, 30)];
Try this! Maybe there is another view at the top of the textField
your_textfield.userInteractionEnabled = YES;
If this doesn't work
add another line
[self.view bringSubviewToFront: your_textfield];
Try to add delegate methods on your textfields. Like
- (void) textFieldDidEndEditing:(UITextField *)textField
{
// ADD BREAKPOINT HERE.
}
Check if it goes to that line of code. If not maybe there's a view on top of it. Or you can try to bring textfield to front like .
[self.view bringSubviewToFront:yourTextfield];
But this isn't a good example of how you fix the problem. Just to test if there is a view on top of it.

UIStepper valueChanged.

I'm making an iphone app and I have met a problem..
I'm making sub views which contains labels and a UIStepper..
They are made by a for loop like so:
//subView to contain one ticket
UIView *ticketTypeView = [[UIView alloc]initWithFrame:CGRectMake(10, y, 1000, 60)];
if(ticketCount%2){
ticketTypeView.backgroundColor = [UIColor lightGrayColor];
}
[self.view addSubview:ticketTypeView];
//label for ticket type name
UILabel *ticketType = [[UILabel alloc]initWithFrame:CGRectMake(10, 3, 500, 50)];
[ticketType setText:string];
[ticketType setFont:[UIFont fontWithName:#"Helvetica neue" size:20.0]];
[ticketTypeView addSubview:ticketType];
//UIStepper for ticket amount
UIStepper *stepper = [[UIStepper alloc]initWithFrame:CGRectMake(500, 16, 0, 0)];
stepper.transform = CGAffineTransformMakeScale(1.2, 1.2);
[ticketTypeView addSubview:stepper];
//label for price pr. ticket
UILabel *pricePrTicket = [[UILabel alloc]initWithFrame:CGRectMake(620, 5, 100, 50)];
[pricePrTicket setText:#"1000.00 Kr."];
[ticketTypeView addSubview:pricePrTicket];
//totalPrice label
UILabel *totalTypePrice = [[UILabel alloc]initWithFrame:CGRectMake(900, 5, 100, 50)];
[totalTypePrice setText:#"0.00 Kr."];
[ticketTypeView addSubview:totalTypePrice];
Now.. How do I add a IBAction valueChanged for my UIStepper? the stepper is supposed to take the count, multiply it by the pricePrTicket and display it in the totalPrice label..
Any help or hint will be much appreciated :)
You'll need to assign unique tag to all your subviews of ticketTypeView (each should be unique) then follow #thedjnivek answer. When you get call - (void) stepperChanged:(UIStepper*)theStepper method, get totalPrice label object like this,
UILabel *ticketprice = (UILabel *)[theStepper.superview viewWithTag:kTagPriceTicket];
check if label object is not nil,
if(ticketprice) {
ticketprice.text = theStepper.value * pricePrTicket;
}
In your for loop where you're creating ticketTypeView and other labels.
Your label tag should be unique for labels and the same for individual ticketTypeView views.
Create tags like this (you can give any integer for tags),
#define kTagTicketType 110
#define kTagPriceTicket 111
#define kTagTotalTypePrice 112
...
...
...
[ticketType setTag:kTagTicketType]; //NOTE this
[pricePrTicket setTag:kTagPriceTicket]; //NOTE this
[totalTypePrice setTag:kTagTotalTypePrice]; //NOTE this
Write above lines before adding each of the label.
You have to set the target with addTarget:action: like this :
[stepper addTarget:self action:#selector(stepperChanged:) forControlEvents:UIControlEventValueChanged];
- (void) stepperChanged:(UIStepper*)theStepper{
//This method would be called on UIControlEventsValueChanged
}
I hope that can help you ;)

viewWithTag and addSubview

I am trying to reuse the label by making a call to viewWithTag when I press the UIButton. The code looks ok when it is executed the first time, but is it leaking on executing it multiple times due to line 7? Also is it just better to remove the label from the superview, alloc and addSubview instead of using viewWithTag?
1. UILabel *label = (UILabel *)[self.view viewWithTag:100];
2. if(label == nil) {
3. label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 20)] autorelease];
4. label.tag = 100;
5. }
6.
7. [self.view addSubview:label];
Move the code [self.view addSubview:label]; inside your if block. When your if condition is false, that means the label is already part of of your viewcontroller's view hierarchy, so if you add it again like in your original code it will be double retained.
UILabel *label = (UILabel *)[self.view viewWithTag:100];
if (!label) {
label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 20, 20)] autorelease];
label.tag = 100;
[self.view addSubview:label];
}
If you are using a .xib or storyboard just link it with an IBOutlet.
If you'r using code only, try to save it as a private variable.

Resources