How to center a UILabel on UIView - ios

How can I center the UILabel on the UIView? I am using the following code
float width = weatherView.bounds.size.width;
float height = weatherView.bounds.size.height;
[self.label setFrame:CGRectMake(width-100,height-100, 100, 100)];

How about:
[self.label setCenter:view.center];

If the label is a subview of view:
[self.label setCenter:CGPointMake(view.frame.size.width / 2, view.frame.size.height / 2)]
Don't use view.center unless the label and view have the same superview.
If there is no immediate connection, then you'll have to transform view's center to the coordinate space of label's parent. Then you could use PengOne's answer with the transformed point.

Use NSTextAlignmentCenter if what you have is the label already set and you want to center its content.
cell.menuLabel.textAlignment = NSTextAlignmentCenter;

A better posible solution is:
First: If you are doing this programmatically you'll need to initialize with frame and some customizations:
// Simple example
int yPosition = 10;
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0, yPosition, self.view.frame.size.width, 0)];
[label setText: #"Testing..."];
[label setBackgroundColor: [UIColor clearColor]];
[label setNumberOfLines: 0];
[label sizeToFit];
Second: If a label what you are trying to center you can just run this after setNumberOflines selector called and 0 value assigned, your text will have all lines needed, and sizeToFit method called to have a good customization, and finally:
[self.label setCenter: CGPointMake(self.view.center.x, self.label.center.y)];
This will center only the X axis, and the Y axis will stay as you desired in the frame initialization.
PS: It's also valid if not a UILabel but depends on the control you are using will need another simple customization or neither, and if you only want to center programmatically but interface builder designed, just need to run the second code.

PengOne / Alex Lockwood's answer is simple and useful. If you intend to support rotation, add the following to keep it centered:
[self.myLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth];

Something like this should do the trick...
Make sure that your label is set to have centered alignment and is sufficiently big/wide to handle your text string.
float viewWidth = weatherView.frame.size.width;
float viewHeight = weatherView.frame.size.height;
float labelWidth = label.frame.size.width;
float labelHeight = label.frame.size.height;
float xpos = (viewWidth/2.0f) - (labelWidth/2.0f);
float ypos = (viewHeight/2.0f) - (labelHeight/2.0f);
[label setFrame:CGRectMake(xpos,ypos,labelWidth,labelHeight)];
I think that should do what you are asking for.

There are two possibility if your UILabel is added via .xib or else added programmatically .
If first case i.e added via .xib then you can set the position from xib file size inspector tab with the 'Arrange' property
And if second case persist then you can set as --- [self.label setCenter:view.center];

Related

Creating UILabel programmatically with dynamic size

I am trying to create UILabel programmatically, but height and width should be set dynamically depending on the content. I don't want to create initial CGRect with some width and height, which cause design issues in my case.
What I tried to do is:
self.freeLabel = [[UILabel alloc] initWithFrame:CGRectMake(frameView.layer.frame.size.width - 50, -8, 120, 25)];
self.freeLabel.numberOfLines = 0;
[self.freeLabel setBackgroundColor:[UIColor colorWithRed:0.91 green:0.18 blue:0.42 alpha:1.0]];
self.freeLabel.layer.cornerRadius = 5;
self.freeLabel.layer.masksToBounds = YES;
[self addSubview:self.freeLabel];
[self sizeToFit];
but this way I cannot add the UILabel to my view.
you have to add below codes so that self.freeLabel with take new height.
[self.freeLabel sizeToFit];
self.freeLabel.frame = CGRectMake(frameView.layer.frame.size.width - 50, -8, 120, self.freeLabel.frame.size.height)];
self.frame = // update size based on the height of the label.
But I have some points which I feel are wrong.
Why x position of self.freeLabel is defined as frameView.layer.frame.size.width - 50 but width of label as 120. For sure this label will go out of your view. So frameView.layer.frame.size.width - 50 should be frameView.layer.frame.size.width - 120

How to programmatically sizeToFit width AND height on UILabel?

I'm programmatically creating multi-line UILabels ([label setNumberOfLines:0];).
The built-in sizeToFit method of UILabel works great for 1 line UILabels, but for multi-line text, it sets the height properly, but the width is set too small, causing longer text lines to wrap.
I don't know the label width until after the user enters their text. I want to resize the labels to fit the width of the longest line of text. And per #DonMag's comment, I also want to restrict the label to not be wider than the screen.
I tried different lineBreakMode settings but there isn't a 'nowrap' option.
I've searched SO and there are many related solutions but none that solve the problem of sizeToFit for both width and height.
Is there a way to programmatically size a multi-line UILabel to fit BOTH the width AND the height of the text?
You can do this with boundingRectWithSize...
Add your label to the view and give it a starting width constraint (doesn't really matter what value, as it will be changed).
Keep a reference to that width constraint (IBOutlet works fine if you're using IB).
Don't give it a height constraint.
When you set the text of the label, you can use this to change its width:
// get the font of the label
UIFont *theFont = _theLabel.font;
// get the text of the label
NSString *theString = _theLabel.text;
// calculate the bounding rect, limiting the width to the width of the view
CGRect r = [theString boundingRectWithSize:CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:#{NSFontAttributeName: theFont}
context:nil];
// change the constant of the constraint to the calculated width
_theWidthConstraint.constant = ceil(r.size.width);
// NOTE: If you are *not* using auto-layout,
// this same calculation can be used to explicitly set
// the .frame of the label.
Edit:
As per the OP's requirement, a complete, runnable example -- using code only, no storyboards / IB -- can be found here: https://github.com/DonMag/MultilineLabelFitWidth
Edit 2:
GitHub project updated... now includes examples for both manual frame setting and auto layout / constraints.
With some more experimentation, I found something that does the trick that I have not seen in SO (yet...). In general it works like this:
Find the longest text line
Set numberOfLines to 1 (temporarily)
Set label text to longest text line
Call label.sizeToFit (sets label width for longest line)
Set numberOfLines to 0 (multi-line)
Set label text to full multi-line text
Call label.sizeToFit (sets label height for all lines)
Voila! Now your UILabel is sized to fit your multi-line text.
Here is an example (demo project on GitHub: UILabelSizeToFitDemo):
- (UILabel *)label = nil;
- (void)updateLabel:(NSString *)notes {
// close to the "sticky" notes color
UIColor *bananaColor = [ViewController colorWithHexString:#"#FFFC79"];
if (_label == nil) {
_label = [[UILabel alloc] init];
_label.numberOfLines = 0;
_label.textColor = UIColor.blackColor;
[_label setBackgroundColor:[bananaColor colorWithAlphaComponent:0.9f]];
_label.textAlignment = NSTextAlignmentLeft;
[self.view addSubview:_label];
}
// make font size based on screen size
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat fontSize = MIN(screenWidth,screenHeight) / 12;
[_label setFont:[UIFont systemFontOfSize:fontSize]];
// split lines
NSArray *lines = [notes componentsSeparatedByString:#"\n"];
NSString *longestLine = lines[0]; // prime it with 1st line
// fill a temp UILabel with each line to find the longest line
for (int i = 0; i < lines.count; i++) {
NSString *line = (NSString *)lines[i];
if (longestLine == nil || line.length > longestLine.length) {
longestLine = line;
}
}
// force UILabel to fit the largest line
[_label setNumberOfLines:1];
[_label setText:longestLine];
[_label sizeToFit];
// make sure it doesn't go off the screen
if (_label.frame.size.width > screenWidth) {
CGRect frame = _label.frame;
frame.size.width = screenWidth - 20;
_label.frame = frame;
}
// now fill with the actual notes (this saves the previous width)
[_label setNumberOfLines:0];
[_label setText:notes];
[_label sizeToFit];
// center the label in my view
CGPoint center = CGPointMake(self.view.bounds.size.width / 2, self.view.bounds.size.height / 2);
[_label setCenter:center];
}
UPDATE: Here is an alternate complete solution, using the boundinRectWithSize from the code snippet by #DonMag:
-(void)updateLabel:(NSString *)notes {
// close to the "sticky" notes color
UIColor *bananaColor = [ViewController colorWithHexString:#"#FFFC79"];
if (_label == nil) {
_label = [[UILabel alloc] init];
_label.numberOfLines = 0;
_label.textColor = UIColor.blackColor;
_label.backgroundColor = [bananaColor colorWithAlphaComponent:0.9f];
_label.textAlignment = NSTextAlignmentLeft;
[self.view addSubview:_label];
}
// set new text
_label.text = notes;
// make font size based on screen size
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
CGFloat fontSize = MIN(screenWidth,screenHeight) / 12;
[_label setFont:[UIFont systemFontOfSize:fontSize]];
// calculate the bounding rect, limiting the width to the width of the view
CGRect frame = [notes boundingRectWithSize:CGSizeMake(self.view.frame.size.width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
attributes:#{NSFontAttributeName: _label.font}
context:nil];
// set frame and then use sizeToFit
[_label setFrame:frame];
[_label sizeToFit];
// center the label in my view
CGPoint center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
[_label setCenter:center];
}

Can I change the frame of UILabel runtime in IOS simulator by stretching the corner of UILabel?

I want to provide user to change the frame of label in simulator and adjust label frame as per text requirement .
Below is the image and can i make same view in IOS simulator to allow user change frame of label?
for label only and i want to show editable frame
If any one have idea how to do this thing or is it possible to do this type of functionality in IOS?
let me know.!
Thanks
Here are one very nice class for make this task possible much easy. IQLabelView is a Github project that you need to use
Import IQLabelView and add Label like following
IQLabelView *labelView = [[IQLabelView alloc] initWithFrame:labelFrame];
labelView.delegate = self;
[labelView setAutoresizingMask:(UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth)];
[labelView setShowContentShadow:NO];
[labelView setTextField:aLabel];
[labelView setFontName:#"Baskerville-BoldItalic"];
[labelView setFontSize:21.0];
[labelView sizeToFit];
[self.view addSubview:labelView];
To change size of UILabel according to text length you can use this code
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);
CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode];
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;
Hope this would help , Thank you.
UILabel according to text length .. Try only two line . It will auto adjust your max width and auto change height according to text .
yourLabel.numberOfLines = 0;
[yourLabel sizeToFit];

Rotate a UIlabel to make it vertical

I have a UILabel. I need to rotate it programmatically.
I have my horizontal UILabel, for example with frame: x:0, y:0, w: 200, h:80.
Now I would like to rotate the label to make it vertical:
I try this code:
[self setTransform:CGAffineTransformMakeRotation(M_PI_2 / 2)];
I can see the contained text rotated. But I would like to rotate the whole frame: With my code, the UILabel continues to have the same frame.
Try this working code:
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 200, 80)];
//set background color to see if the frame is rotated
[label setBackgroundColor:[UIColor redColor]];
[label setText:#"Text Here"];
label.transform=CGAffineTransformMakeRotation( ( 90 * M_PI ) / 180 );
[self.view addSubview:label];
Hope it helps
If you prefer set the label position and size visually in you xib or storyboard do the following:
Set the labels position and size in the interface builder like you want them to stay after the rotation.
Rotate the label and set the frame again:
-(void)rotateLabel:(UILabel*) label
{
CGRect orig = label.frame;
label.transform=CGAffineTransformMakeRotation(M_PI * 3/2);//270º
label.frame = orig;
}
Your Label is a square(w:100,h:100).So your label has transformed, but you can't see the change,because the width is equal to the height.

UIImageView and autolayout

I have a view that is set up nicely using autolayout. The view contains a series of labels stacked from top to bottom. I am allowing the intrinsic size of these labels to determine the size of the view.
The final step is to add a background from an image. I started by trying the colorWithPatternImage method on UIColor but this isn't quite what I am looking for. I do not want to tile the image, and I can not guarantee it will always be larger than the intrinsic size of the view.
Similarly, adding a uiImageView to the view itself doesn't quite work. The view will expand to accommodate the image when I want to keep the intrinsic size based on the labels.
I guess what I am looking for is the following.
1) The background should have no effect on the size of the view.
2) The image should be scaled to fill the view but in it's original aspect ration (so cropping edges if necessary).
Any ideas appreciated.
In my case, I needed it for a UIImageView inside a dynamically-sized view in a UITableViewCell, but the image refused to shrink below its instristic size and instead worked as a minimum-size constraint for the superview. The only way I could get it ignore the intristic size is by lowering the priority at which it is enforced, right after creating the cell:
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisVertical];
After this, all my constraints magically started working. In the OP's case, setting UIViewContentModeScaleAspectFill is also required, as per Mundi's answer.
In Interface Builder, add a UIImageView as the first subview to the view. Make sure its size always matches the view.
Then, in Interface Builder or code, set the contentMode:
backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
Here's how I would approach this. Hopefully it helps. :)
CGRect contentFrame = CGRectMake(0, 0, self.view.frame.size.width, 0); // This will be the frame used to create the background image view.
UIEdgeInsets contentInsets = UIEdgeInsetsMake(20, 20, 20, 20); // The margins by which the labels will be inset from the edge of their parent view.
CGFloat labelHeight = 21;
CGFloat verticalGap = 8; // The vertical space between labels
CGFloat y = contentInsets.top;
int numberOfLabels = 10;
for (int i = 0; i < numberOfLabels; i++) {
CGRect frame = CGRectMake(contentInsets.left, y, self.view.frame.size.width - (contentInsets.left + contentInsets.right), labelHeight);
UILabel *label = [[[UILabel alloc] initWithFrame: frame] autorelease];
// customize the label here
[self.view addSubview: label];
contentFrame = CGRectUnion(contentFrame, label.frame);
y += labelHeight + verticalGap;
}
contentFrame.size.height += contentInsets.bottom;
UIImageView *backgroundImageView = [[[UIImageView alloc] initWithFrame: contentFrame] autorelease];
[backgroundImageView setClipsToBounds: YES];
[backgroundImageView setContentMode: UIViewContentModeScaleAspectFill];
[backgroundImageView setImage: [UIImage imageNamed: #"background_image.png"]];
[self.view insertSubview: backgroundImageView atIndex: 0];

Resources