How to make UIButton's text alignment center? Using IB - ios

I can't set the title of UIButton using IB as center. My title is multi line.It is giving like this one
But I want like this one
I have given space in this but I don't want to do that. As it is not aligned exactly for some cases and I know there is a property of UILabel to set the alignment but I don't want to write a code for that.. just want to set everything from IB.
Thanks

This will make exactly what you were expecting:
Objective-C:
[myButton.titleLabel setTextAlignment:UITextAlignmentCenter];
For iOS 6 or higher it's
[myButton.titleLabel setTextAlignment: NSTextAlignmentCenter];
as explained in tyler53's answer
Swift:
myButton.titleLabel?.textAlignment = NSTextAlignment.Center
Swift 4.x and above
myButton.titleLabel?.textAlignment = .center

Use the line:
myButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
This should center the content (horizontally).
And if you want to set the text inside the label to the center as well, use:
[labelOne setTextAlignment:UITextAlignmentCenter];
If you want to use IB, I've got a small example here which is linked in XCode 4 but should provide enough detail (also mind, on top of that properties screen it shows the property tab. You can find the same tabs in XCode 3.x):

Solution1
You can set the key path in the storyboard
Set the text to your multiline title e.g. hello ⌥ + ↵ multiline
You need to press ⌥ + ↵ to move text to next line.
Then add the key path
titleLabel.textAlignment as Number and value 1, 1 means NSTextAlignmentCenter
titleLabel.numberOfLines as Number and value 0, 0 means any number of lines
This will not be reflected on IB/Xcode, but will be in centre at run time (device/simulator)
If you want to see the changes on Xcode you need to do the following: (remember you can skip these steps)
Subclass the UIButton to make the button designable:
import UIKit
#IBDesignable class UIDesignableButton: UIButton {}
Assign this designable subclass to the buttons you're modifying:
Iff done right, you will see the visual update in IB when the Designables state is "Up to date" (which can take several seconds):
Solution2
If you want to write the code, then do the long process
1.Create IBOutlet for button
2.Write code in viewDidLoad
btn.titleLabel.textAlignment = .Center
btn.titleLabel.numberOfLines = 0
Solution3
In newer version of xcode (mine is xcode 6.1) we have property attributed title
Select Attributed then select the text and press centre option below
P.S. The text was not coming multiline for that I have to set the
btn.titleLabel.numberOfLines = 0

For UIButton you should use:-
[btn setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];

For ios 8 and Swift
btn.titleLabel.textAlignment = NSTextAlignment.Center
or
btn.titleLabel.textAlignment = .Center

For those of you who are now using iOS 6 or higher, UITextAlignmentCenter has been deprecated. It is now NSTextAlignmentCenter
EXAMPLE: mylabel.textAlignment = NSTextAlignmentCenter; Works perfectly.

For swift 4, xcode 9
myButton.contentHorizontalAlignment = .center

Assuming that btn refers to a UIButton, to change a multi-line caption to be centered horizontally, you can use the following statement in iOS 6 or later:
self.btn.titleLabel.textAlignment = NSTextAlignmentCenter;

For Swift 4:
#IBAction func myButton(sender: AnyObject) {
sender.titleLabel?.textAlignment = NSTextAlignment.center
sender.setTitle("Some centered String", for:UIControlState.normal)
}

UITextAlignmentCenter is deprecated in iOS6
Instead you can use this code:
btn.titleLabel.textAlignment=NSTextAlinmentCenter;

For Swift 3.0
btn.titleLabel?.textAlignment = .center

Try Like this :
yourButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
yourButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;

Actually you can do it in interface builder.
You should set Title to "Attributed" and then choose center alignment.

You can do this from storyboard.
Select your button. Set Line Break 'Word Wrap', Set your title 'Plain' to 'Attributed'.
Select 'Center alignment'. This part is important => Click ...(More) Button. And select line breaking mode to 'Character Wrap'.

UIButton will not support setTextAlignment. So You need to go with setContentHorizontalAlignment for button text alignment
For your reference
[buttonName setContentHorizontalAlignment:UIControlContentHorizontalAlignmentCenter];

Related

Difference between setTitle:forState: and titleLabel.text

After looking over the internet and other SO questions(this one is great iOS: UIButton titleLabel -- does it do anything at all?), it is unclear to me what is the difference between these two, more accurately, how these two work.
I know that setTitle:forState: let me set text of the button for different states(Normal, Disabled,Highlighted etc.). I know, as well, that titleLabel is read only, but its properties are read/write.
At this point you might ask: What is the problem then?
I will explain it through example. I have following hierarchy:
UITableViewCell - MyView - MyButton
MyView is xib in which, through interface builder, I set button. When I set buttons title like:
self.myButton.titleLabel.text = #"Something"; // some string I get from server
It works. But if I try the similar approach when only MyView is included (somewhere else in the project) and try:
myView.myButton.titleLabel.text = #"Something else";
It doesn't work. Let me be more specific. In one part of the second(even in viewDidApper) buttons title is what I want. After that, the buttons label returns to its default value. The one I set in the interface builder. When I change to
[myView.myButton setTitle:#"Something else" forState:UIControlStateNormal];
It works as expected.
What I want to know is why does this happen? It is unclear to me why does this glitch occurs with the title? Is this strange thing documented somewhere(looked over apple documentation)? Is it possible to get implementation of setTitle:forState:?
I'm not sure how the internals of UIButton are actually implemented but this is a guess. There are times when iOS needs to redraw the button ie. the button is tapped so the button's state changes (let's say from UIControlStateNormal to UIControlStateHighlighted). Then iOS would find the title associated to UIControlStateHighlighted then display that text by using something like.
myButton.titleLabel.text = #"Title for UIControlStateHighlighted";
Sample scenario:
[myButton setTitle:#"Normal" forState:UIControlStateNormal];
[myButton setTitle:#"Highlighted" forState:UIControlStateHighlighted];
// somewhere in the code, you call this to change the label
myButton.titleLabel.text = #"Something else";
// when user taps the button, iOS will do something like
myButton.titleLabel.text = #"Highlighted"; // will overwrite "Something Else"
// when user releases, iOS will again do something like
myButton.titleLabel.text = #"Normal"; // will overwrite "Highlighted"
so it's required to use setTitle:forState: in order to associate the given title to a certain state. The instances where iOS redraws the button is of course not limited to the the user interacting with the button. It could also be triggered by layout changes.
You should not use button.titleLabel.text = to set the button title.
The documentation for the titleLabel property says
Although this property is read-only, its own properties are read/write. Use these properties primarily to configure the text of the button. For example:
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.titleLabel.font = [UIFont systemFontOfSize: 12];
button.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
Do not use the label object to set the text color or the shadow color. Instead, use the setTitleColor(:for:) and setTitleShadowColor(:for:) methods of this class to make those changes. To set the actual text of the label, use setTitle(_:for:) (button.titleLabel.text does not let you set the text).
I normally don't set button titles in interface builder, but do it in the viewDidLoad, and get the title from Localizable.strings..
You must use setTitle:forState and setTitleColor:forState to change text and color. All other label properties can be changed directly though.
"Do not use the label object to set the text color or the shadow color. Instead, use the setTitleColor:forState: and setTitleShadowColor:forState: methods of this class to make those changes."
-source

UITextView - setting font not working with iOS 6 on XCode 5

I'm using storyboards for my UI. I was previously using XCode 4.6 and released on iOS 6. I have since updated to iOS 7 using XCode 5 and updated the Storyboard to work nicely with XCode 5. I have one issue though:
UITextView doesn't want to display font changes within code. Text colour changes work fine. Any other property changes are fine. Font, not at all. I was using a custom font, so I checked different fonts with different sizes (i.e. systemFontOfSize:) but that didn't work. The text view only shows the font that's set in the Storyboard. What could I be missing here? Are there any auto-layout constraints that mess with this sort of thing? I had a few issues with constraints during the migration, but as I said, the fonts work fine in iOS 7.
I guess it's something in the Storyboard that I'm missing, as if I create a UIViewController and add a text view in code, it works fine.
I'd put up some code, but I'm not sure it'd help at all in this case.
Even stranger, this only happens on iPhone, not iPad.
If you're setting the font in code and don't want an editable text view, do this:
textView.editable = YES;
textView.font = newFont;
textView.editable = NO;
In my case, it is matter of 'selectable' property of UITextView.
So I checked 'selectable' property of UITextView in Storyboard Editor to set it YES
and later in viewWillAppear set this property to NO.
textview.text = #"some text";
textview.selectable = NO;
The issue was caused by the editable property being false in the Storyboard. I have absolutely no idea why this caused the font to remain unchanged - and only on iOS 6.
For me it's work if you set the text of your UITextView and after set the font (same for color) :
_myTextView.text = #"text";
[_myTextView setFont:[UIFont fontWithName:#"Helvetica Neue" size:18.0f]];
_myTextView.textColor = [UIColor whiteColor];
Thank you for all the answers guys. Issue is still present on iOS9. What i've found out, is that when you set "User Interaction Enabled = false" in the Interface Builder you can leave Editable and Selectable = true and user will not be able to edit a text view.
So, my solution is:
Set User Interaction Enabled = False in IB
Set Editable = True in IB
Set Selectable = True in IB
Configure your text view in whatever way you want.
Code for swift:
textOutlet.editable = true
textOutlet.textColor = UIColor.whiteColor()
textOutlet.font = UIFont(name: "ArialMT", size: 20)
textOutlet.editable = false
Or if you change the text first it magically gets solved
textOutlet.text = "omg lol wtf"
textOutlet.textColor = UIColor.whiteColor()
textOutlet.font = UIFont(name: "ArialMT", size: 20)
I found the font size was being ignored. This was resolved by ticking the checkbox called: Selectable (having selected the UITextView within the storyboard)
This issue only happens when setting Selectable property to FALSE in the Interface Builder.
In case you are required to have the Editable and Selectable properties set to FALSE do it from the CODE and not in the Interface Builder.
Summing up, make Editable and Selectable properties = YES in the Interface Builder and then add the following code in case you need the properties to be FALSE:
_textView.editable = NO;
_textView.selectable = NO;
Hope this helps,
Swift 3 category that worked for me:
extension UITextView {
func setFontAndUpdate(_ font: UIFont?) {
self.font = font
// Font doesn't update without text change
let text = self.text
self.text = nil
self.text = text
}
}
In my case(Developing on Xcode 7.3, iOS 9),
The cause was the order of setting text and font-family/size, not the options of editable or selectable many answers tell there.(and I don't get any storyboard, xib on that Textview.)
If I input like
[myTextView setFont:[UIFont fontWithName:#"HelveticaNeue-Italic" size:20]];
myTextView.attributedText = mAttStr;
then the font's family and size are not changed, but else
when I reverse those two step, it works. Setting text should be ahead of setting font's family/size.
As mentioned by others:
textView.font = UIFont.systemFont(ofSize: 16)
textView.isEditable = false
p.s. no need to first set isEditable as true since it's true by default: a little shorter, a little nicer
In my case, I solved by setting the new font in "viewDidLayoutSubviews".

UIButton with multi-line titleLabel in InterfaceBuilder

I've been wondering, is there a nice way to make UIButtons with multi-line titleLabel in Interface Builder? I've found none and puttin a separate UILabel on top of each button and tracking it's color on press and other events is not very straightforward.
Maybe there are better alternatives done in code if there's no such way in IB?
Code:
To allow multiple line you can use:
button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: #"Line1\nLine2" forState: UIControlStateNormal];
In iOS 6, UILineBreakModeWordWrap and UITextAlignmentCenter are deprecated, so use:
button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
Interface Builder:
In interface builder select UIButton
on the right side Utilities pane under Attributes Inspector, you'll see an option for Line Break
Choose Word Wrap
You can do solely in Interface Builder a couple ways.
First by simply setting the wrap feature. This offers limited customizability though.
For more customizability, change the "Plain Text" to "Attributed Text" and then you can do most things without any code.
In the case you are using only plain XCode 9.4:
Set Line Break to any option (to enable numberOfLines) in the Attributes inspector:
Then you can set KeyPath as
titleLabel.numberOfLines
in the Identity inspector:
Just to mention if one does not want word wrap but still want to achieve multi line title on a UIButton it can be done by setting lineBreakMode before numberOfLines,
This is because lineBreakMode seems to cancel out numberOfLines set hence we are doing it in this order.
Swift:
button.titleLabel?.lineBreakMode = NSLineBreakMode.byTruncatingTail
button.titleLabel?.numberOfLines = 2
button.setTitle(myTitle, for: UIControlState.normal)

UIButton title appears with dots when set programatically

When I set the title of the UIButton in the xib, it works fine, but when I set the same text programatically to the title of the button it is trimmed.
BUY THIS FILM FOR 20.00$ -> BUY THIS FI...FOR 20.00$
Try this way:
[_button setTitle:#"BUY THIS FILM FOR 20.00$" forState:UIControlStateNormal];
What is displayed in interface builder when you edit the xib is not guaranteed to look exactly like when it is loaded on the simulator or device.
Solution: just make your Button a little bit wider.
Also, double check that the text is exactly the same as in IB.
Try this way:
btnObj.titlelabel.minimumFontSize = 8.0; // or some more adequate size
btnObj.titleLabel.adjustsFontSizeToFitWidth = YES;

How to not stretch an image in UIButton

I'm trying to create a custom UITableViewCell programmatically and one of the subviews of this cell is going to be a button with an image in it (a simple image of a magnifying glass). However, I want the button's image to be centered and scaled proportionately down to fit in the button and NOT to be stretched to fill the entire button. Below is my code where self refers to the custom UITableViewCell which I am placing the button into.
self.myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.myButton setBackgroundImage:[UIImage imageNamed: #image_name_here"] forState:UIControlStateNormal];
self.myButton.frame = CGRectMake(...//something, something)
self.myButton.imageView.contentMode = UIViewContentModeCenter;
[self.contentView addSubview:self.mySearchHelpButton];
Right now the image stretches to fill the entire button rather than scaling proportionately so that it fits nicely.
I have also tried setting the contentMode to UIViewContentModeScaleAspectFill but this doesn't seem to change anything. In fact, none of the different contentModes seem to change anything.
Have you tried setImage instead of setBackgroundImage?
Make sure the button is a Custom UIButton
Just using setImage: did not work for me on iOS9.
But it worked combined with myButton.imageView.contentMode = UIViewContentMode.ScaleAspectFit;
In Swift...
button.imageView?.contentMode = . scaleAspectFit
Storyboard
Property image.
You must define specific property in Runtime Attributes of Identity inspector – imageView.contentMode, where you set value relatively to rawValue position of enum UIViewContentMode. 1 means scaleAspectFit.
And button's alignment, in Attributes inspector:
Swift 4.2
myButton.imageView!.contentMode = .scaleAspectFit
Swift earlier version
myButton.imageView!.contentMode = UIViewContentMode.scaleAspectFit
Swift 4.X and 5.X
button.imageView!.contentMode = .scaleAspectFit
button.contentVerticalAlignment = .fill
button.contentHorizontalAlignment = .fill
I think you guys are missing the obvious issue. The image is too large for the button and iOS then has to guess how you want to scale it. Make sure your images are the right size and you won't have this issue. Of course this is for static images and buttons that you know the size for up-front -- not dynamic content.

Resources