Attributed Text Center Alignment - ios

I have tried everything but cannot seem to center this text. Can someone please tell me where the error is.
NSMutableParagraphStyle *paragraphStyle = NSMutableParagraphStyle.new;
paragraphStyle.alignment = NSTextAlignmentCenter;
label.attributedText = [[NSAttributedString alloc] initWithString:cell.EventTitle.text attributes:#{NSForegroundColorAttributeName : [UIColor whiteColor],NSParagraphStyleAttributeName:paragraphStyle,NSBaselineOffsetAttributeName : #0,NSFontAttributeName : [UIFont fontWithName:#"BrandonGrotesque-Black" size:34]}];

In Swift 5
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
textView.attributedText = NSAttributedString(string: "String",
attributes: [.paragraphStyle: paragraph])
In Swift-4
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
let attributes: [NSAttributedString.Key : Any] = [NSAttributedString.Key.paragraphStyle: paragraph]
let attrString = NSAttributedString(string:"string", attributes: attributes)
textView.attributedText = attrString
In Swift-3
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
let attributes: [String : Any] = [NSParagraphStyleAttributeName: paragraph]
let attrString = NSAttributedString(string:"string", attributes: attributes)
textView.attributedText = attrString

You can set the center alignment using this. Remember to set range.
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setAlignment:NSTextAlignmentCenter];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [string length])];

In Swift 4
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
textView.attributedText = NSAttributedString(string: "string",
attributes: [.paragraphStyle: paragraph])

Another way:
Swift:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attributedString = NSAttributedString(string: "This will be centered.", attributes: [ NSAttributedString.Key.paragraphStyle: paragraphStyle])
Obj-C:
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = NSTextAlignmentCenter;
NSAttributedString *attributedString = [NSAttributedString.alloc initWithString:#"This will be centered."
attributes: #{NSParagraphStyleAttributeName:paragraphStyle}];

Swift 4+
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
// Swift 4.2++
let attributedString = NSMutableAttributedString(string: "Your String", attributes: [NSAttributedString.Key.paragraphStyle:paragraphStyle])
// Swift 4.1--
let attributedString = NSMutableAttributedString(string: "Your String", attributes: [NSAttributedStringKey.paragraphStyle:paragraphStyle])
let yourLabel = UILabel()
yourLabel.attributedText = attributedString
Objective-C
NSString *string = #"Your String";
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentCenter;
NSMutableAttributedString * attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes: #{NSParagraphStyleAttributeName:paragraphStyle}];
UILabel *label = [[UILabel alloc] init];
label.attributedText = attributedString;

In Swift
let titleString = "title here"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Center
let attributedString = NSAttributedString(
string: titleString,
attributes: [NSParagraphStyleAttributeName: paragraphStyle]
)
titleAttributedLabel.attributedText = attributedString

Swift4
let attributedString = NSMutableAttributedString(string: "Example text that is centered using a paragraph style. With the ability to change the width between lines.", attributes: [NSAttributedStringKey.font: GothamFont.medium(with: 14)])
let myParagraphStyle = NSMutableParagraphStyle()
myParagraphStyle.alignment = .center // center the text
myParagraphStyle.lineSpacing = 14 //Change spacing between lines
myParagraphStyle.paragraphSpacing = 38 //Change space between paragraphs
attributedString.addAttributes([.paragraphStyle: myParagraphStyle], range: NSRange(location: 0, length: attributedString.length))

helper method based on the helpful answers above
public extension NSAttributedString
{
var centered: NSAttributedString
{
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
let m = NSMutableAttributedString(attributedString: self)
m.addAttribute(.paragraphStyle, value: paragraph, range: NSMakeRange(0, length))
return m
}
}
in case you want the Is dotted and Ts crossed el verbositas version
var centered: NSAttributedString {
let paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.center
let attributedString = NSMutableAttributedString(attributedString: self)
attributedString.addAttributes([NSAttributedString.Key.paragraphStyle : paragraphStyle],
range: NSRange(location: 0, length: attributedString.length))
return attributedString
}

To do it in Swift 2.x
let attributeString = NSMutableAttributedString(string: "text")
style.alignment = .Center
attributeString.addAttribute(NSParagraphStyleAttributeName, value: style, range: range)

Sometimes when text is in Arabic or other right align languages then when doing alignment Justified, last line text ends at left side. for this we can add baseWritingDirection below is sample code
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .justified
paragraphStyle.baseWritingDirection = .rightToLeft
attribute.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:range)
txtView.attributedText = attribute

Set line breakmode, if you set attributed text on UIButton.
Swift 5
let paragraph = NSMutableParagraphStyle()
paragraph.alignment = .center
paragraph.lineBreakMode = .byClipping
Objective-C
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
style.alignment = NSTextAlignmentCenter;
style.lineBreakMode = NSLineBreakByClipping;

This works for me
label.textAlignment = .center

Related

Can I change the location of the ellipsis on the uilabel in swift?

I used UiLabel with byTruncatingTail attribute.
I want to fix the ellipsis from the middle to the bottom vertically.
It is now stated as follows.
But I want to have the ellipsis placed on the floor as follows.
My code is as follows.
let paragraphStyle = NSMutableParagraphStyle()
let range = NSRange(location: 0, length: mutableAttributedString.length)
paragraphStyle.lineSpacing = 2
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byTruncatingTail
mutableAttributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: range)
titleLabel.attributedText = mutableAttributedString
Is this possible?

How to adjust a UILabel line spacing programmatically in Swift?

I have a multiline UILabel as shown here:
I achieved this using the following code:
label.lineBreakMode = .ByWordWrapping
label.numberOfLines = 2
I'm trying to "decrease" the line spacing between the 1st line and 2nd line, and I tried to use the following code:
let text = label.attributedText
let mas = NSMutableAttributedString(attributedString:text!)
mas.replaceCharactersInRange(NSMakeRange(0, mas.string.utf16.count),
withString: label.text!)
label.attributedText = mas
However, it does not seem to work.
Thanks
Programmatically with Swift 4
Using label extension
extension UILabel {
// Pass value for any one of both parameters and see result
func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {
guard let labelText = self.text else { return }
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = lineSpacing
paragraphStyle.lineHeightMultiple = lineHeightMultiple
let attributedString:NSMutableAttributedString
if let labelattributedText = self.attributedText {
attributedString = NSMutableAttributedString(attributedString: labelattributedText)
} else {
attributedString = NSMutableAttributedString(string: labelText)
}
// Line spacing attribute
attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
self.attributedText = attributedString
}
}
Now call extension function
let label = UILabel()
let stringValue = "How\nto\nadjust\na\nUILabel\nline\nspacing\nprogrammatically\nin\nSwift"
// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) . // try values 1.0 to 5.0
// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0
Or using label instance (Just copy & execute this code to see result)
let label = UILabel()
let stringValue = "How\nto\nadjust\na\nUILabel\nline\nspacing\nprogrammatically\nin\nSwift"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))
label.attributedText = attrString
Swift 3
let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString
From Interface Builder:
You're on the right track with NSAttributedString. You need to set the line spacing of the paragraph style:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 30 // Whatever line spacing you want in points
attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
label.attributedText = attributedString;
Do this in the storyboard.....
func updateLabel(with title: String) {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineHeightMultiple = 0.8
paragraphStyle.alignment = .center
let string = NSAttributedString(string: title, attributes: [.paragraphStyle: paragraphStyle])
label.attributedText = string
}

Center justify UILabel text?

I'm trying to center-justify the text of my UILabel like the picture :
Sample of my code :
myLabel.textAlignment = .Justified
myLabel.lineBreakMode = .ByWordWrapping
The result I have :
Did I miss something ?
I found the answer there : https://stackoverflow.com/a/27548566/833816
It works by adding paragraphStyle.firstLineHeadIndent = 0.001
Full sample:
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .Justified
paragraphStyle.firstLineHeadIndent = 0.001
let mutableAttrStr = NSMutableAttributedString(attributedString: detailsLabel.attributedText)
mutableAttrStr.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, mutableAttrStr.length))
myLabel.attributedText = mutableAttrStr
Try
myLabel.textAlignment = NSTextAlignment.Center

iOS NSAttributedString on UIButton

I'm using iOS 6, so attributed strings should be easy to use, right? Well... not so much.
What I want to do:
Using a custom subclass of UIButton (it doesn't do anything custom to titleLabel), I'd like to have a multi-line, attributed title that is:
All caps (I realize that's not part of the attributes) on the first line
Bolded on the first line
Underlined on the first line
"Normal" weight on the second line
Non-underlined on the second line
Centered on both lines
I've been able to get #'s 1 through 5 so far (at least, I thought I did, but current testing is yielding errors with multi-line text), but when I tried to do something (anything!) to get the text to be centered, my app keeps crashing. When I try to get all 6 items working (through various methods), I get the following crash/error:
Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason:
'NSAttributedString invalid for autoresizing,
it must have a single spanning paragraph style
(or none) with a non-wrapping lineBreakMode.'
Based on what I've tried, it appears that I can have one of the following options, but not both:
A multi-line, centered label
An attributed label
I can live with one or the other if I must, but I can't believe that I can't have what seems to be a fairly straightforward concept.
Can someone please tell me what I've got wrong?
Here's the last iteration of the code I'm trying:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];
UIFont *font1 = [UIFont fontWithName:#"HelveticaNeue-Medium" size:20.0f];
UIFont *font2 = [UIFont fontWithName:#"HelveticaNeue-Light" size:20.0f];
NSDictionary *dict1 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleSingle),
NSFontAttributeName:font1};
NSDictionary *dict2 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleNone),
NSFontAttributeName:font2};
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#"LINE 1\n" attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#"line 2" attributes:dict2]];
[[self buttonToStyle] setAttributedTitle:attString forState:UIControlStateNormal];
[[[self buttonToStyle] titleLabel] setNumberOfLines:0];
[[[self buttonToStyle] titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
It looks to me like you forgot in your code to use the "style" object that you set up.. you just instantiated it. You should modify your code to look like this:
NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
[style setAlignment:NSTextAlignmentCenter];
[style setLineBreakMode:NSLineBreakByWordWrapping];
UIFont *font1 = [UIFont fontWithName:#"HelveticaNeue-Medium" size:20.0f];
UIFont *font2 = [UIFont fontWithName:#"HelveticaNeue-Light" size:20.0f];
NSDictionary *dict1 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleSingle),
NSFontAttributeName:font1,
NSParagraphStyleAttributeName:style}; // Added line
NSDictionary *dict2 = #{NSUnderlineStyleAttributeName:#(NSUnderlineStyleNone),
NSFontAttributeName:font2,
NSParagraphStyleAttributeName:style}; // Added line
NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#"LINE 1\n" attributes:dict1]];
[attString appendAttributedString:[[NSAttributedString alloc] initWithString:#"line 2" attributes:dict2]];
[self.resolveButton setAttributedTitle:attString forState:UIControlStateNormal];
[[self.resolveButton titleLabel] setNumberOfLines:0];
[[self.resolveButton titleLabel] setLineBreakMode:NSLineBreakByWordWrapping];
Note that I only added the lines that define the NSParagraphStyleAttributeName.. everything else is the same.. and this is what I get for the button:
And here it is in Swift 3.0
let style = NSMutableParagraphStyle()
style.alignment = .center
style.lineBreakMode = .byWordWrapping
guard
let font1 = UIFont(name: "HelveticaNeue-Medium", size: 20),
let font2 = UIFont(name: "HelveticaNeue-Light", size: 20) else { return }
let dict1:[String:Any] = [
NSUnderlineStyleAttributeName:NSUnderlineStyle.styleSingle.rawValue,
NSFontAttributeName:font1,
NSParagraphStyleAttributeName:style
]
let dict2:[String:Any] = [
NSUnderlineStyleAttributeName:NSUnderlineStyle.styleNone.rawValue,
NSFontAttributeName:font2,
NSParagraphStyleAttributeName:style
]
let attString = NSMutableAttributedString()
attString.append(NSAttributedString(string: "LINE 1", attributes: dict1))
attString.append(NSAttributedString(string: "line 2", attributes: dict2))
button.setAttributedTitle(attString, for: .normal)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = .byWordWrapping
With Swift 5.1 and iOS 13.1, you can use the UIButton subclass implementation below in order to solve your problem:
import UIKit
class CustomButton: UIButton {
required init(title: String, subtitle: String) {
super.init(frame: CGRect.zero)
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
style.lineBreakMode = NSLineBreakMode.byWordWrapping
let titleAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.foregroundColor: UIColor.label,
NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.largeTitle),
NSAttributedString.Key.paragraphStyle : style
]
let subtitleAttributes = [
NSAttributedString.Key.foregroundColor: UIColor.label,
NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body),
NSAttributedString.Key.paragraphStyle : style
]
let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
attributedString.append(NSAttributedString(string: "\n"))
attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))
setAttributedTitle(attributedString, for: UIControl.State.normal)
titleLabel?.numberOfLines = 0
titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Usage:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = CustomButton(title: "Title", subtitle: "Subtitle")
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
}
}
As an alternative if you really need a button of type system, you may use the following code:
import UIKit
extension UIButton {
static func customSystemButton(title: String, subtitle: String) -> UIButton {
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
style.lineBreakMode = NSLineBreakMode.byWordWrapping
let titleAttributes: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.underlineStyle : NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.largeTitle),
NSAttributedString.Key.paragraphStyle : style
]
let subtitleAttributes = [
NSAttributedString.Key.font : UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body),
NSAttributedString.Key.paragraphStyle : style
]
let attributedString = NSMutableAttributedString(string: title, attributes: titleAttributes)
attributedString.append(NSAttributedString(string: "\n"))
attributedString.append(NSAttributedString(string: subtitle, attributes: subtitleAttributes))
let button = UIButton(type: UIButton.ButtonType.system)
button.setAttributedTitle(attributedString, for: UIControl.State.normal)
button.titleLabel?.numberOfLines = 0
button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping
return button
}
}
Usage:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton.customSystemButton(title: "Title", subtitle: "Subtitle")
button.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(button)
let horizontalConstraint = button.centerXAnchor.constraint(equalTo: view.centerXAnchor)
let verticalConstraint = button.centerYAnchor.constraint(equalTo: view.centerYAnchor)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
}
}
The two screen shots below show the result display for the UIButton subclass (on the left) and for the system type button (on the right):
Two line UIButton with NSAttributedString title in Swift 5.1:
func customizeSubscribeButton() {
subscribeButton.titleLabel?.numberOfLines = 2
let title = NSMutableAttributedString()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let part1 = NSAttributedString(string: "SUBSCRIBE FOR 12 MONTH\n",
attributes: [NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 24, weight: .semibold),
NSAttributedString.Key.paragraphStyle: paragraphStyle])
let part2 = NSAttributedString(string: "999.00 RUB ECONOMY 85%",
attributes: [NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12, weight: .light),
NSAttributedString.Key.paragraphStyle: paragraphStyle])
title.append(part1)
title.append(part2)
subscribeButton.setAttributedTitle(title, for: .normal)
}

Truncating head of a UILabel with 2 lines

I have a UIlabel which has numberOfLines as 2
and lineBreakMode = Truncate Head
But when i run it
Instead of truncating head on first line like
...1st Line Content
2nd Line Content
It truncates like
1st Line Content
...2nd Line Content
How do i truncate the head of the label in the first line itself?
Try this code tested in Swift 3
let text = "Hello World! Hello World! Hello World! Hello World! "
let attString = NSMutableAttributedString(string: text)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
paragraphStyle.firstLineHeadIndent = 0
paragraphStyle.headIndent = 40 // set any vallue
paragraphStyle.lineBreakMode = .byTruncatingHead
attString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attString.length))
attString.addAttribute(NSFontAttributeName, value: UIFont(name: "Arial", size: 25)!, range: NSMakeRange(0, attString.length))
label.attributedText = attString // label is your UILabel
label.numberOfLines = 2
Output 1:
paragraphStyle.firstLineHeadIndent = 40 // set any vallue
paragraphStyle.headIndent = 0
Output 2:
Updated: You can achieve by combain two attribute string
let dotAttributes = [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: UIFont(name: "Arial", size: 25)]
let textAttributes = [NSForegroundColorAttributeName: UIColor.red, NSFontAttributeName: UIFont(name: "Arial", size: 25)]
let dotString = NSMutableAttributedString(string: ". . . ", attributes: dotAttributes)
let textString = NSMutableAttributedString(string: "Hello World! Hello World! Hello World! Hello World!", attributes: textAttributes)
let totalString = NSMutableAttributedString()
totalString.append(dotString)
totalString.append(textString)
label.numberOfLines = 2
label.attributedText = totalString
Note: You can use paragraphStyle(headIndent) to create left margin.
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .left
paragraphStyle.firstLineHeadIndent = 5
paragraphStyle.headIndent = 5 // set any vallue
paragraphStyle.lineBreakMode = .byTruncatingHead
totalString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, totalString.length))
Output:

Resources