how to print formated text from keyboard - ios

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.

Related

How to add color to a specific text in Xcode using swift?

I am appending a text on the end of a string that I have received by making the API Call in Xcode. Now, I want to add colour and make only the text "Tap to Read More" bold. Any suggestions on how can I achieve that? Would appreciate your help:)
self.content[i] = recievedData.title! + "\nTap to Read More "
let str = "Tap to Read More"
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: UIColor.red,
]
let attributedQuote = NSAttributedString(string: str, attributes: attributes)
You can try NSAttributedString.
Example:
let str = "Tap to Read More"
// Create your attributed string
let attributes: [NSAttributedString.Key : Any] = [.foregroundColor : UIColor.red]
let attributedStr = NSAttributedString(string: str, attributes: attributes)
// Example for a UILabel
let lbl = UILabel()
lbl.attributedText = attributedStr
Doc on NSAttributedString: https://developer.apple.com/documentation/foundation/nsattributedstring

Not able to give separate color for multiple words

I'm having a certain sentence. I have to give black color to four words in that sentence.
This is how I have attempted that...
In viewDidLoad,
rangeArray = ["Knowledge","Events","Community","Offers"]
for text in rangeArray {
let range = (bottomTextLabel.text! as NSString).range(of: text)
let attribute = NSMutableAttributedString.init(string: bottomTextLabel.text!)
attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.black , range: range)
self.bottomTextLabel.attributedText = attribute
}
But with this code, instead of having black color for all 4 words, I get only the word 'Offers' in black color. What am I doing wrong...?
In your code, you are updating the self.bottomTextLabel.attributedText for each run of the for loop.
Instead of that you must
create an NSMutableAttributedString using the sentence,
add all the relevant attributes as per your rangeArray and
then at last set that attrStr it as attributedText of bottomTextLabel.
Here is what I mean to say,
if let sentence = bottomTextLabel.text {
let rangeArray = ["Knowledge","Events","Community","Offers"]
let attrStr = NSMutableAttributedString(string: sentence)
rangeArray.forEach {
let range = (sentence as NSString).range(of: $0)
attrStr.addAttribute(.foregroundColor, value: UIColor.black, range: range)
}
self.bottomTextLabel.attributedText = attrStr
}

Change color of a certain word in UILabel

I just want to change color of some word in my Label's string.
What I want to do is:
How Im trying to do:
But it doesnt work and it says: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
So I need an advice to do this easy thing, and I need a trick to do this. You guys can send your way.
Try this, your attributed string has no value when you try get the range of the string. You got to give the attributed string a string value before that. You
let descriptionLabel: UILabel = {
let label = UILabel()
// String variable containing the text.
let fullString = "mehmet alper tabak"
// Choose wwhat you want to be colored.
let coloredString = "alper"
// Get the range of the colored string.
let rangeOfColoredString = (fullString as NSString).range(of: coloredString)
// Create the attributedString.
let attributedString = NSMutableAttributedString(string:fullString)
attributedString.setAttributes([NSForegroundColorAttributeName: UIColor.red],
range: rangeOfColoredString)
label.attributedText = attributedString
return label
}()
descriptionLabel.frame = CGRect(x: 50, y: 50, width: 140, height: 100)
self.view.addSubview(descriptionLabel)
Or you can do an extension of UILabel.
extension UILabel {
func colorString(text: String?, coloredText: String?, color: UIColor? = .red) {
let attributedString = NSMutableAttributedString(string: text!)
let range = (text! as NSString).range(of: coloredText!)
attributedString.setAttributes([NSForegroundColorAttributeName: color!],
range: range)
self.attributedText = attributedString
}
To use it.
self.testLabel.colorString(text: "mehmet alper tabak",
coloredText: "alper")
It is out of bounds because myMutableString is empty at the time that you are trying to set attributes. Try instead:
let myMutableString = NSMutableAttributedString.init(string: label.text)
Create attributedString1 with first color
let attributedString1 = NSAttributedString(string: "robert plant ", attributes: [NSForegroundColorAttributeName: color1])
Create attributedString2 with second color
let attributedString1 = NSAttributedString(string: "with queen", attributes: [NSForegroundColorAttributeName: color2])
Add them to myMutableString
myMutableString.append(attributedString1)
myMutableString.append(attributedString1)

How to make bold a part of NSMutableString?

I have this code in my hands:
if let text = trimText?.mutableCopy() as? NSMutableString {
text.insertString("\(prefix) ", atIndex: 0)
textStorage.replaceCharactersInRange(range, withString: text as String)
}
When I try to change my text as:
text = attributedTextFunc(text)
where
func attributedTextFunc(str: NSString) -> NSAttributedString {
var attributedString = NSMutableAttributedString(string: str as String, attributes: [NSFontAttributeName:UIFont.systemFontOfSize(15.0)])
let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFontOfSize(15.0)]
attributedString.addAttributes(boldFontAttribute, range: str.rangeOfString("More"))
return attributedString
}
and I get this error:
Cannot assign value of type 'NSAttributedString' to type 'NSMutableString'
How can I make it bold?
You cannot assing NSAttributedString to text. It's two different types.
String is not subclassed from NSAttributedString.
You should set:
attributedText = attributedTextFunc(text)
Then if you want to present it on UILabel
label.attributedText = attributedText
UPDATE
Struct String doesn't know anything about UIKit and Bold styles.
NSAttributedString knows about UIKit and contains any text styles you want
UPDATE 2
In your case
ReadMoreTextView.attributedTrimText = attributedText
You cannot reassign text because:
text is constant (let)
text is NSMutableString, but attributedTextFunc return NSAttributedString
You have to store result of attributedTextFunc in variable as a NSAttributeString and set attributeText of UILabel instead of text
if let text = trimText?.mutableCopy() as? NSMutableString {
// ...
let attributeText = attributedTextFunc(text)
someLabel.attributeText = attributeText
}
Use this code and pass your normal String and Bold String (which is needed to be bold).
func attributeStrings(first: String, second : String) -> NSMutableAttributedString{
let myNormalAttributedTitle = NSAttributedString(string: first,
attributes: [NSFontAttributeName : UIFont.boldSystemFontOfSize(15)])
let myAttributedTitle = NSAttributedString(string: second,
attributes: [NSForegroundColorAttributeName : UIColor.blackColor()])
let result = NSMutableAttributedString()
result.appendAttributedString(myNormalAttributedTitle)
result.appendAttributedString(myAttributedTitle)
return result
}
and assign the return value of this function to
someLabel.attributeText = attributeStrings("My Name is", second : "Himanshu")
It is because, your text is type of NSMutableString and your function attributedTextFunc is type of NSString.
That is the problem so just change it from NSString to NSMutableString.

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)

Resources