Newbie xcode: UILabel is null but it's not - ios

I was going through a tutorial that seemed quite straightforward but could not get it to work. The goal is to have a label and a button in the UI view that are created with IB. The label is supposed to say "Hello World" and when you click the button it will change the text to "Hello iPhone". When I implement the code, the label doesn't change. when I debug, I found out the label is "null" but I can't figure out why... I would really appreciate your help with this.
The label has a tag value "55".
My code looks like this:
in the interface file:
-(IBAction)buttonTapped;
in the main file:
-(IBAction)buttonTapped{
UILabel *label = (UILabel*) [window viewWithTag:55];
NSLog(#"The label's text is %s",label.text); //my debug statement
if([label.text isEqualToString:#"Hello World"])
label.text = #"Hello iPhone";
else
label.text = #"Hello World";
}

Assuming you're in a ViewController. I don't know what your window property is. Also you should be using "%#" for strings. Format Specifiers
-(IBAction) buttonTapped:(UIButton*)sender{
UILabel *label = (UILabel*) [self.view viewWithTag:55];
NSLog(#"The label's text is %#",label.text); //my debug statement
if([label.text isEqualToString:#"Hello World"])
label.text = #"Hello iPhone";
else
label.text = #"Hello World";
}

Reading between the lines it sounds like your action method is not being fired.
You weren't explicit in saying how you knew the label text was blank, but can we assume that you did actually get the NSLog to output its results? If you didn't then I refer to my first sentence... Check that you have wired up your Button correctly in the Interface Builder, to point to an outlet action.

in your #interface you should have:
IBOutlet UILabel *label;
then in your -(IBAction)buttonTapped just:
NSLog(#"The label's text is %s",label.text); //my debug statement
if([label.text isEqualToString:#"Hello World"])
label.text = #"Hello iPhone";
else
label.text = #"Hello World";
}

Related

Adding multiple lines to a UILabel that is updated by a UITextField

So i'm making an application where the user converts the data from a UITextField into a UILabel. However, when updating a large amount of text instead of overflowing into another line, it simply displays '...' when there are too many words. I've tried changing the number of lines in the UILabel, even changing it to '0' which should mean the text displayed should fit the words in the UITextField, but this isn't the case. The following code I have for the UITextField to the UILabel is:
- (IBAction)add:(id)sender {
NSString *input = text1.text;
label1.text = input;
NSString *Input = text2.text;
label2.text = Input;
I'm new to developing and I've checked documentation and have found nothing. I did notice someone saying I should use a UITextField, however this doesn't suit my needs as to what i require the UILabel to display.
Maybe try setting the lineBreakMode property of the UILabel to NSLineBreakByWordWrapping, as the default value for this property is actually NSLineBreakByTruncatingTail which could explain the '...' that you're experiencing when the label has too much text. Also make sure the adjustsFontSizeToFitWidth property is set to NO.
textLabel.adjustsFontSizeToFitWidth = NO; // this is default value
textLabel.lineBreakMode = NSLineBreakByWordWrapping;
textLabel.numberOfLines = 0;
Options for UITextView that you may have not seen
UITextView * _descriptionText = [UITextView new];
[_descriptionText setTextAlignment:NSTextAlignmentLeft];
[[_descriptionText textContainer] setMaximumNumberOfLines:11];
[[_descriptionText textContainer] setLineBreakMode:NSLineBreakByTruncatingTail];
Not sure if this helps, but combining this with Bamsworlds answer should do it

Cannot make programmatically created UITextField editable (iOS)

I created a UITextField programatically, (I do not use storyboard) and added it as a subview to ViewController with this code:
#interface ViewController ()
#property (nonatomic, strong) UITextField *searchLocationBar;
#end
...
#synthesize searchLocationBar;
...
self.searchLocationBar = [[UITextField alloc] init];
self.searchLocationBar.frame = CGRectMake(0.0f, 0.0f, 320.0f, 40.0f);
self.searchLocationBar.delegate = self;
self.searchLocationBar.borderStyle = UITextBorderStyleRoundedRect;
self.searchLocationBar.placeholder = #"a temporary placeholder";
self.searchLocationBar.userInteractionEnabled = YES;
self.searchLocationBar.clearButtonMode = UITextFieldViewModeAlways;
[self.view addSubview:self.searchLocationBar];
However, I cannot enter any text - nothing happens, when I tap on a textfield. It's not overlapped by any other view.
I've checked UITextfield not editable-iphone but no effect
I'm newbie and totally sure I simply miss something - please advice.
Thanks!
EDIT:
One more thing: I have a Google Maps GMSMapView assigned to self.view as
self.view = mapView_; as written in Google API documentation.
After some tests I found that with this declaration all controls work perfectly, but not textfields. I would prefer not to move a map view to any subview as I will need to rewrite lots of things.
Can someone please add any suggestions?
you forget add:
[self.view bringSubviewToFront:self.searchLocationBar];
In Xcode 5 your code should work.Better you check your Xcode version.May be the problem with your code with Xcode versions.You can try by following way.
UITextField *lastName = [[[UITextField alloc] initWithFrame:CGRectMake(10, 100, 300, 30)];
[self.view addSubview:lastName];
lastName.placeholder = #"Enter your last name here"; //for place holder
lastName.textAlignment = UITextAlignmentLeft; //for text Alignment
lastName.font = [UIFont fontWithName:#"MarkerFelt-Thin" size:14.0]; // text font
lastName.adjustsFontSizeToFitWidth = YES; //adjust the font size to fit width.
lastName.textColor = [UIColor greenColor]; //text color
lastName.keyboardType = UIKeyboardTypeAlphabet; //keyboard type of ur choice
lastName.returnKeyType = UIReturnKeyDone; //returnKey type for keyboard
lastName.clearButtonMode = UITextFieldViewModeWhileEditing;//for clear button on right side
lastName.delegate = self; //use this when ur using Delegate methods of UITextField
There are lot other attributes available but these are few which we use it frequently.if u wanna know about more attributes and how to use them refer to the following link.
You can also make property for UITextField.Either way should work fine in Xcode.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITextField_Class/Reference/UITextField.html

Make only part of a sentence a link (add selector)

so I am trying to implement the following. I have a view, which has a sentence. Only part of the sentence links to another view. This is what it looks like:
I am a cat. Learn More
The Learn More would be a link (blue in color), which when clicked would open another view.
Currently I am using a UILabel to write "I am a cat". I realize that the best way to add selectors is to use a button, so "Learn More" should be a button?
Is there any way to write this sentence out without using two different UIComponents?
If not, then how do I make the UILabel and the UIButton completely horizontally aligned with each other?
The following is my code for the label in -layoutSubviews:
CGSize labelSize = [_label.text sizeWithFont:_label.font constrainedToSize:bounds.size lineBreakMode:_label.lineBreakMode];
_label.frame = CGRectMake(0, 0, bounds.size.width - kMarginForText, labelSize.height);
_label.center = CGPointMake(horizontalCenter, CGRectGetMaxY(_previousLabel.frame) + kDistanceBetweenPreviousAndCurrentLabel);
And the code for the label itself.
_label = [[UILabel alloc] initWithFrame:CGRectZero];
_label.text = "I am a cat";
_label.font = [UIFont systemFontOfSize:14];
_label.textAlignment = NSTextAlignmentCenter;
_label.numberOfLines = 0;
_label.lineBreakMode = UILineBreakModeWordWrap;
[self addSubview:_label];
Any help would be appreciated!
To answer your question about a single UIComponent, you could use a UILabel in conjunction with a UITapGestureRecognizer to create the intended effect. Granted this would make the whole label tappable... but having a bigger tap target area is almost never a bad thing.
In particular you would use an NSAttributedString to set the label text (NSAttributedString change color at end of string):
UILabel *label = [[UILabel alloc] init];
//Use initwithframe or setup your constraints after initialization here
label.attributedText = (your nsattributed string here)
Then to initialize the tap recognizer onto the UILabel you would do something like this:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(userDidTapLearnMore)];
label.userInteractionEnabled = YES;
[label addGestureRecognizer:tap];
What you want to do is to align them by their baselines, which you can easily do in Interface Builder by selecting them and choosing Editor > Align > Baselines, as shown in this illustration:

Is there an option to implicitly localise labels in Interfacebuilder

Somewhere in a blog post I stumbled upon a strings file which looked like this:
// de.lproj/Localizable.strings
"This is the title" = "Das ist der Titel"
To me this looked like the actual labels in Interface builder were processed by the compiler so that no explicit translations using NSLocalizedString(#"SOME_IDENTIFIER", #""); would be necessary any more.
My question now, is whether there is some kind of shortcut or do I need to localise all my individual labels on my view e.g. in the awakeFromNib method.
I have figured out a way to semi-automate the process so that I don't have to do this:
label1.text = NSLocalizedString(#"label1_key", #"");
label2.text = NSLocalizedString(#"label2_key", #"");
....
labeln.text = NSLocalizedString(#"labeln_key", #"");
So for all labels which should be localised I set their text to __KeyForLabelX in IB. Then in the viewWillAppear method of the viewcontroller I loop through the items on the view and set the text to the localized value:
for (UIView *view in self.view){
if([view isMemberOfClass:[UILabel class]]){
UILabel *l = (UILabel *)view;
BOOL shouldTranslate = [l.text rangeOfString:#"__"].location != NSNotFound;
NSString *key = [l.text stringByReplacingOccurrencesOfString:#"__" withString:#"TranslationPrefix"];
if (shouldTranslate){
l.text = NSLocalizedString(key, #"");
}
}
}
My .strings file then look like this:
"TranslationPrefixKeyForLabelX" = "Translation of Label X";
Update: To further adapt the mechanism you could also check for other UIViews like UIButtons, UITextFields (including prompt text) etc.

How to add line break for UILabel?

Let see that I have a string look like this:
NSString *longStr = #"AAAAA\nBBBBB\nCCCCC";
How do I make it so that the UILabel display the message like this
AAAAA
BBBBB
CCCCC
I don't think \n is recognized by UILabel, so is there anything that I can put inside NSString so that UILabel knows that it has to create a line break there?
Use \n as you are using in your string.
Set numberOfLines to 0 to allow for any number of lines.
label.numberOfLines = 0;
Update the label frame to match the size of the text using sizeWithFont:. If you don't do this your text will be vertically centered or cut off.
UILabel *label; // set frame to largest size you want
...
CGSize labelSize = [label.text sizeWithFont:label.font
constrainedToSize:label.frame.size
lineBreakMode:label.lineBreakMode];
label.frame = CGRectMake(
label.frame.origin.x, label.frame.origin.y,
label.frame.size.width, labelSize.height);
Update : Replacement for deprecatedsizeWithFont:constrainedToSize:lineBreakMode:
Reference, Replacement for deprecated sizeWithFont: in iOS 7?
CGSize labelSize = [label.text sizeWithAttributes:#{NSFontAttributeName:label.font}];
label.frame = CGRectMake(
label.frame.origin.x, label.frame.origin.y,
label.frame.size.width, labelSize.height);
Use option-return when typing in the little box in Interface Builder to insert a line feed (\n). In Interface Builder's Label attributes, set # Lines = 0.
Select the label and then change Lines property to 0 like in the above image, and then use \n in your string for line break.
In the interface builder, you can use Ctrl + Enter to insert /n to the position you want.
This way could implement the following situation
aaaaaaaaaa
If you read a string from an XML file, the line break \n in this string will not work in UILabel text. The \n is not parsed to a line break.
Here is a little trick to solve this issue:
// correct next line \n in string from XML file
NSString *myNewLineStr = #"\n";
myLabelText = [myLabelText stringByReplacingOccurrencesOfString:#"\\n" withString:myNewLineStr];
myLabel.text = myLabelText;
So you have to replace the unparsed \n part in your string by a parsed \n in a hardcoded NSString.
Here are my other label settings:
myLabel.numberOfLines = 0;
myLabel.backgroundColor = [UIColor lightGrayColor];
myLabel.textColor = [UIColor redColor];
myLabel.font = [UIFont fontWithName:#"Helvetica Neue" size:14.0];
myLabel.textAlignment = UITextAlignmentCenter;
Most important is to set numberOfLines to 0 (= unlimited number of lines in label).
No idea why Apple has chosen to not parse \n in strings read from XML?
You have to set the numberOfLines property on the UILabel. The default is 1, if you set it to 0 it will remove all limits.
Important to note it's \n (backslash) rather than /n.
For those of you who want an easy solution, do the following in the text Label input box in Interface Builder:
Make sure your number of lines is set to 0.
Alt + Enter
(Alt is your option key)
Cheers!
In Swift 2.2, > iOS 8
I've set Lines = 0 on Storyboard, under Attribute Inspector and linked a referencing outlet to the label. Then use in controller like this:
#IBOutlet weak var listLabel: UILabel!
override func viewDidLoad() {
...
listLabel.text = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8"
}
In xCode 11, Swift 5 the \n works fine, try the below code:
textlabel.numberOfLines = 0
textlabel.text = "This is line one \n This is line two \n This is line three"
Just do it like this
NSString * strCheck = #"A\nB";
strCheck = [strCheck stringByReplacingOccurrencesOfString:#"\\n" withString:#"\n"]; //This is to prevent for fetching string from plist or data structure
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.text = strCheck;
// DO not forget to set numberOfLines to zero
UILabel* locationTitle = [[UILabel alloc] initWithFrame:CGRectMake(5, 30, 230, 40)];
locationTitle.font = [UIFont systemFontOfSize:13.0];
locationTitle.numberOfLines = 0;
locationTitle.text = [NSString stringWithFormat:#"Eaton industries pvt. Ltd \nUK Apr 12"];
[cell addSubview:locationTitle];
If your using a UILabel you have to remember that the default setting is 1 line, so it does not matter how many breaks you add (\n or \r), you need to make sure it is set to more than one line so it could be allowed to append more lines.
One alternative is to use UITextView which is really meant for multilines.
You can easily achieve this in XCode attribute section of the UILabel, see screenshot:
On Xcode 6, you can just use \n even inside a string when using word wrap. It will work. So for example:
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 100, screenRect.size.width, 50)];
label.textAlignment = NSTextAlignmentCenter;
label.text = #"This will be on the first line\nfollowed by a line under it.";
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
In my case also \n was not working, I fixed issue by keeping number of lines to 0 and copied and pasted the text with new line itself for example instead of Hello \n World i pasted
Hello
World
in the interface builder.
Just using label.numberOfLines = 0;
textLabel.text = #"\nAAAAA\nBBBBB\nCCCCC";
textLabel.numberOfLines = 3; \\As you want - AAAAA\nBBBBB\nCCCCC
textLabel.lineBreakMode = UILineBreakModeWordWrap;
NSLog(#"The textLabel text is - %#",textLabel.text);
For anyone else that might have trouble with sizeWithFont:constrainedToSize:lineBreakMode: or anyone switching to ios8 (the method is deprecated as of ios7), I adjusted my height by using sizeToFit instead.
UILabel *label;
label.numberOfLines = 0;
// Setup label with desired settings
...
[label sizeToFit];
label.frame = CGRectMake(label.frame.origin.x, // Or use any desired origin
label.frame.origin.y,
label.frame.size.width, // Or use any desired width
label.frame.size.height);
NSCharacterSet *charSet = NSCharacterSet.newlineCharacterSet;
NSString *formatted = [[unformatted componentsSeparatedByCharactersInSet:charSet] componentsJoinedByString:#"\n"];
It seems wrong to me to change the label frame sizes especially when using autolayout. Using the appendFormat method seems more appropriate. Here is my example:
NSMutableString *list = [[NSMutableString alloc] init];
NSArray *textArray = #[#"AAAA", #"BBBB"];
for (NSString *string in textArray) {
[list appendFormat:#"%#\n", string.mutableCopy];
}
self.label.text = list;
self.label.numberOfLines = 0;
If you set your UILable properties from Plain to Attributed...the UILabel will hold multiline text no matter how many paragraphs for along as your UILabel height and width are set to fit the screen area you want to display the text in.
I have faced same problem, and here is, how i solved the problem. Hope this will be helpful for someone.
// Swift 2
lblMultiline.lineBreakMode = .ByWordWrapping // or use NSLineBreakMode.ByWordWrapping
lblMultiline.numberOfLines = 0
// Objective-C
lblMultiline.lineBreakMode = NSLineBreakByWordWrapping;
lblMultiline.numberOfLines = 0;
// C# (Xamarin.iOS)
lblMultiline.LineBreakMode = UILineBreakMode.WordWrap;
lblMultiline.Lines = 0;
on Xcode 6, I can use \n without problem on swift programmatically

Resources