How to center AttributedText link in UITextView swift4 - ios

Is there any way I can just make the text center and change the size/font?
I set it in storyboard but nothing happen when I ran the app. I also tried to use UILabel but it didn't work (when I click it the web didn't show)
The answer I found they didn't include the URL just attributes.paragraphstyle.
I don't know how to write it so I can keep the URL string also change the font/size/alignment.
func searchMealRecipe() {
MealRecipeService.sharedInstance.foodID = foodID
MealRecipeService.sharedInstance.getMealRecipe { (responseString, mealRecipeItem) in
if responseString == "error" {
/* popup here alerting user about error*/
} else {
self.mealRecipeItem = mealRecipeItem
self.ingredientRecipeTitleLabel.text = (mealRecipeItem.name)?.htmlString?.string
self.ingredientRecipeImageView.sd_setImage(with: URL(string: mealRecipeItem.imageURL!), placeholderImage: UIImage(named: ""))
self.ingredientRecipeTextView.text = mealRecipeItem.ingredients?.joined(separator: "\n")
let string = "Sounds Good! Show Me the Steps 📖"
let attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedString.Key.link: URL(string: "\(mealRecipeItem.link!)")!])
self.ingredientRecipeLinkTextView.attributedText = attributedString
}
}
}
I'm using xcode10 beta and swift4.2
//Update(I figured it out the answer and it's working)
//the attributes accept array so I can put multiple styles in the array.
let string = "Sounds Good! Show Me the Steps 📖"
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
let attributedString = NSMutableAttributedString(string: string, attributes:[NSAttributedString.Key.link: URL(string: "\(mealRecipeItem.link!)")!, NSAttributedString.Key.paragraphStyle: style])
self.ingredientRecipeLinkTextView.attributedText = attributedString

you can use NSMutableParagraphStyle
let style = NSMutableParagraphStyle()
style.alignment = NSTextAlignment.center
lbl.centerAttributedText = NSAttributedString(string: "Total Balance",attributes: [your Attributed URL Code here])

Related

Bulleted list in Swift - iOS

I need to add bulleted text to textView in iOS app. I am looking at this link and this one and following their ideas. This is my code:
let paragraph = NSMutableParagraphStyle()
paragraph.firstLineHeadIndent = 15
paragraph.headIndent = 15
attributes = [
NSAttributedStringKey.paragraphStyle: paragraph
]
attributedString = NSAttributedString(string: "\u{2022} Some text some text some text some text some text some text", attributes: attributes)
finalText.append(attributedString)
What I need is to get the text indented with the start of the text above. Like it is in the picture:
What I get is the text indented with the starting point of the bullet.
Remove paragraph.firstLineHeadIndent = 15 from code...
let paragraph = NSMutableParagraphStyle()
paragraph.headIndent = 15
attributes = [
NSAttributedStringKey.paragraphStyle: paragraph
]
attributedString = NSAttributedString(string: "\u{2022} Some text some text some text some text some text some text", attributes: attributes)
finalText.append(attributedString)
Please refer my sample code and screenshot
let style = NSMutableParagraphStyle()
style.alignment = .left
style.headIndent = 20
let title = NSMutableAttributedString(string: "\u{2022} I need to add bulleted text to textView in iOS app. I am looking at this link and this one and following their ideas. This is my code:", attributes: [NSAttributedStringKey.paragraphStyle: style,NSAttributedStringKey.foregroundColor:UIColor.blue])
let titleStr = NSMutableAttributedString(string: "\n\n\u{2022} I need to add bulleted text to textView in iOS app. I am looking at this link and this one and following their ideas. This is my code:", attributes: [NSAttributedStringKey.paragraphStyle: style,NSAttributedStringKey.foregroundColor:UIColor.blue])
title.append(titleStr)
titleLabel.attributedText = title
I faced same problem with textView i used custom indent & it working fine-
#IBOutlet var bulletTextView: UITextView!
override func viewDidLoad() {
let bullet1 = "This is a small string,This is a small string,This is a small string,This is a small string,This is a small string,This is a small string,This is a small string"
let bullet2 = "This is more of medium string with a few more words etc."
let bullet3 = "Well this is certainly a longer string, with many more words than either of the previuos two strings"
strings = [bullet1, bullet2, bullet3]
let fullAttributedString = NSMutableAttributedString()
for string: String in strings {
let attributesDictionary:[NSAttributedStringKey:Any] = [NSAttributedStringKey.font : bulletTextView.font,NSAttributedStringKey.foregroundColor : UIColor.red]
let bulletPoint: String = "\u{2022}"
//let formattedString: String = "\(bulletPoint) \(string)\n"
let attributedString = NSMutableAttributedString(string: bulletPoint, attributes: attributesDictionary)
attributedString.append(NSAttributedString(string: " \(string) \n"))
let indent:CGFloat = 15
let paragraphStyle = createParagraphAttribute(tabStopLocation: indent, defaultTabInterval: indent, firstLineHeadIndent: indent - 10, headIndent: indent)
attributedString.addAttributes([NSAttributedStringKey.paragraphStyle: paragraphStyle], range: NSMakeRange(0, attributedString.length))
fullAttributedString.append(attributedString)
}
bulletTextView.attributedText = fullAttributedString
}
func createParagraphAttribute(tabStopLocation:CGFloat, defaultTabInterval:CGFloat, firstLineHeadIndent:CGFloat, headIndent:CGFloat) -> NSParagraphStyle {
let paragraphStyle: NSMutableParagraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
let options:[NSTextTab.OptionKey:Any] = [:]
paragraphStyle.tabStops = [NSTextTab(textAlignment: .left, location: tabStopLocation, options: options)]
paragraphStyle.defaultTabInterval = defaultTabInterval
paragraphStyle.firstLineHeadIndent = firstLineHeadIndent
paragraphStyle.headIndent = headIndent
return paragraphStyle
}
Output:-
Set paragraph.firstLineHeadIndent to zero. This indents only lines starting with the second one. Currently, you are indenting all lines…
let paragraph = NSMutableParagraphStyle()
// paragraph.firstLineHeadIndent = 15
paragraph.headIndent = 15
To have the headIndent resize with dynamic fonts I'm using this:
private func updateUI() {
let bullet: NSString = "• "
var attributes = [NSAttributedString.Key: Any]()
let paragraph = NSMutableParagraphStyle()
leStackView.subviews.compactMap({ $0 as? UILabel }).forEach {
attributes[.font] = $0.font
paragraph.headIndent = bullet.size(withAttributes: attributes).width
attributes[.paragraphStyle] = paragraph
let text = $0.text ?? ""
$0.attributedText = NSAttributedString(string: text, attributes: attributes)
}
}
The labels for each bullet point are set up in the storyboard with plain text (including the bullet) and dynamic fonts.
I really appreciate the contributions to this thread plus https://bendodson.com/weblog/2018/08/09/bulleted-lists-with-uilabel/
Simple solution:
extension Sequence where Self.Element == String {
func toBulletList(_ bulletIndicator: String = "•",
itemSeparator: String = "\n",
spaceCount: Int = 2) -> String {
let bullet = bulletIndicator + String(repeating: " ", count: spaceCount)
let list = self
.map { bullet + $0 }
.reduce("", { $0 + ($0.isEmpty ? $0 : itemSeparator) + $1 })
return list
}
}
usage:
let items: [String] = [
"one",
"two",
"three"
]
let list = items.toBulletList()
po list ->
• one
• two
• three
I had the same problem, and I finally realized that Label didn't support it. If you want to use bullet-list in the same rows you should use text view

Center and bold part of a text in Swift

I want to center and bold the title of my paragraph. So far I can make the title bold but I cant center it.
Here's my code:
let title = "Title of Paragraph"
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)]
let boldString = NSMutableAttributedString(string:title, attributes:attrs)
let normalText = "Something here.............."
let attributedString = NSMutableAttributedString(string:normalText)
boldString.appendAttributedString(attributedString)
label.attributedText = boldString
I tried to add another attribue in attrs:
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15), NSTextAlignment: NSTextAlignment.Center]
I'm not sure if that's the correct way to center it, but it still gives an error "Type of expression is ambiguous without more context"
I've searched the error but it seems I still can't fix the problem
I think the problem is with the NSTextAlignment key that you are trying to add on the dictionary. It's type is Int which becomes ambiguous with the previous key that is a String so I guess that's why the compiler is complaining. Either way NSTextAlignment is not a valid key to be used on NSMutableAttributedString attributes initialiser.
Maybe you are looking for something like that:
let string = "Any String"
let style = NSMutableParagraphStyle()
style.alignment = .Center
let attributes = [
NSFontAttributeName: UIFont.boldSystemFontOfSize(15),
NSParagraphStyleAttributeName: style
]
let attributedString = NSMutableAttributedString(string: string, attributes: attributes)
Try a category on UILabel:
UILabel+boldText
func boldSubstring(substring: String) {
var range: NSRange = self.text!.rangeOfString(substring)
var attributedText: NSMutableAttributedString = NSMutableAttributedString(attributedString: self.attributedText)
attributedText.setAttributes([NSFontAttributeName: UIFont.boldSystemFontOfSize(self.font.pointSize)], range: range)
self.attributedText = attributedText
}
func centerAlginement(substring:String) {
var paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle.new
paragraphStyle.alignment = .Center
var attributedString: NSAttributedString = NSAttributedString.alloc(string: substring, attributes: [NSParagraphStyleAttributeName: paragraphStyle])
self.attributedText = attributedString
}
now you can use it in your view import category class to your view
myLabel.text = "DemoText"
myLabel.boldSubstring(myLabel.text)
myLabel.centerAlginement(myLabel.text)

how to print formated text from keyboard

I was wondering how can I print formated text from the keyboard keys. For example, I have a toolbar attached to the keyboard, I click "bold" on the keyboard and from there on every letter printed from the keyboard will now be bold. This is what I have but it does not work, String's don't seem to hold format.
func keyPressed(sender: AnyObject?) {
let button = sender as! UIButton
let title = button.titleForState(.Normal)
let attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)]
let boldString = NSMutableAttributedString(string:title!, attributes:attrs)
(textDocumentProxy as UIKeyInput).insertText(boldString.string)
}
Strings don't hold format, you're right. You should manipulate your target directly, using NSAttributedString and attributedText to do so.
let str = "Hello, world!"
let attrs = [NSFontAttributeName: UIFont.systemFontOfSize(15)]
let attributedString = NSAttributedString(string: str, attributes: attrs)
yourTextView.attributedText = attributedString
Note that the specific thing you want to do is tricky, because attributed strings attach attributes (like bold) to parts of text and not "from there on every letter". So if you read out the current attributed string then try to modify the attributes at the caret without actually inserting anything, it won't work.
So, this won't work:
let existingAttributedString = yourTextView.attributedText.mutableCopy() as! NSMutableAttributedString
let newAttrs = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15)]
let newAttributedString = NSAttributedString(string: "", attributes: newAttrs)
existingAttributedString.appendAttributedString(newAttributedString)
Whereas this will:
let existingAttributedString = yourTextView.attributedText.mutableCopy() as! NSMutableAttributedString
let newAttrs = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15)]
let newAttributedString = NSAttributedString(string: " ", attributes: newAttrs)
existingAttributedString.appendAttributedString(newAttributedString)
The only difference is that the second example inserts a space, which is enough for iOS to attach attributes to.
That being said, if you're willing to change your approach so that users select existing text before hitting bold, that works great.

How to insert custom emoji in UILabel programmatically, in Swift?

I am building an iOS app where I have to add support for emojis within UILabel, so basically, whenever I receive a string containing either of these:
[kick-off]
[yellow-card]
[red-card]
[introduce]
[substitute]
[attention]
[free-kick]
[penalty]
[offside]
[extra-time]
[throw-in]
[corner]
[goal-post]
[bar]
[cheers]
[goal]
I have to replace these tags with a corresponding emoji. I have custom images for these emojis:
https://cdn-waf-beta.global.ssl.fastly.net/0.55.12/static/images/WAF_live_icons_sprite.png
Any idea how could I pull that off using Swift?
You need to create an NSTextAttachment and append it to an NSAttributedString.
Example:
let stringAttributes = [
// insert any attributes here
NSFontAttributeName : UIFont.systemFontOfSize(14)
,NSForegroundColorAttributeName : UIColor.blackColor()
]
let attributedString = NSMutableAttributedString(string: "the string before your image ", attributes: stringAttributes)
// Image needs to be NSData
let imageData:NSData = UIImagePNGRepresentation(yourImage)!
// Attachment type is very important
let attachment = NSTextAttachment(data: imageData, ofType: "public.png")
let attachmentString = NSAttributedString(attachment: attachment)
attributedString.appendAttributedString(attachmentString)
print(attributedString)
You can find the appropriate uti (Uniform Type Identifier) here
Here is the latest (swift v5) syntax with a few additions:
func strgWithImage(yourImage: String, preImage: String, postImage: String) -> NSMutableAttributedString {
// Call function with attributed text label:
// testLabel.attributedText = strgWithImage(yourImage: "doneX.png", preImage: "preS", postImage: "postS")
let stringAttributes = [
// insert any attributes here
NSAttributedString.Key.font : UIFont.systemFont(ofSize: 14)
,NSAttributedString.Key.foregroundColor : UIColor.black
]
let attributedString = NSMutableAttributedString(string: preImage, attributes: stringAttributes)
let postString = NSMutableAttributedString(string: postImage, attributes: stringAttributes)
let attachment = NSTextAttachment()
attachment.image = UIImage(named:yourImage) // loaded in assets
let imageOffsetY: CGFloat = -15.0
attachment.bounds = CGRect(x: 0, y: imageOffsetY, width: attachment.image!.size.width, height: attachment.image!.size.height)
let attachmentString = NSAttributedString(attachment: attachment)
attributedString.append(attachmentString)
attributedString.append(postString)
return attributedString
}

iPhone -Remove the underline from link in UILabel

I am using TTTAttributedLabel (https://github.com/twotoasters/TTTAttributedLabel). Here I'm correctly getting the label with some clickable text.
I need to display my text like the username in above image(ie. without underline).How could I do that?
Try this code (sorry for formatting, written on phone...)
NSDictionary *linkAttributes = #{[NSNumber numberWithInt:kCTUnderlineStyleNone] : (id)kCTUnderlineStyleAttributeName};
self.label.linkAttributes = linkAttributes;
For swift 4.0
let LinkAttributes = NSMutableDictionary(dictionary: testLink.linkAttributes)
LinkAttributes[NSAttributedStringKey.underlineStyle] = NSNumber(value: false)
yourLabel.linkAttributes = LinkAttributes as NSDictionary as! [AnyHashable: Any]
if you are already having label with underline style and if you want to remove it programatically use the following code
let string = "your text"
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: 13)
]
let attributedString = NSAttributedString(string: string,
attributes: attributes)
yourLabel.attributedText = attributedString

Resources