How to make bold a part of NSMutableString? - ios

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.

Related

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.

appendAttributedString return value of type Void

I am trying to append two NSAttributedString.
let string_1 : NSAttributedString = self.answerTextView.attributedText
let string_2 : NSAttributedString = handleHtml(i) // a function that returns a NSAttributedString
let finalStr : NSAttributedString = string_1.mutableCopy().appendAttributedString(string_2)
But I got an error at the third line:
Cannot convert value of type 'Void' (aka '()') to specified type 'NSAttributedString'
How can I solve this? Thanks
appendAttributedString updates the caller. It doesn't return a new string. Try the following:
let string_1 : NSAttributedString = self.answerTextView.attributedText
let string_2 : NSAttributedString = handleHtml(i) // a function that returns a NSAttributedString
let tmpStr : NSMutableAttributedString = string_1.mutableCopy()
tmpStr.appendAttributedString(string_2)
let finalStr : NSAttributedString = tmpStr.copy()
Def something like this:
//MARK: Custom functions
func getQueueAttributedString(number N: Int) -> NSAttributedString? {
let uploadSymbolAttributes = [NSForegroundColorAttributeName: UEColor.brown.six, NSFontAttributeName: UEFont.unearthCharacterFont(13)]
let attributedString = NSMutableAttributedString(string: UEFontCharacter.triangle_up, attributes: uploadSymbolAttributes)
let queueAttributes = [NSForegroundColorAttributeName: UEColor.brown.six, NSFontAttributeName: UEFont.museo300(withSize: 13)]
let queueString = NSAttributedString(string: " \(N) items queued", attributes: queueAttributes)
attributedString.append(queueString)
return attributedString
}
Where UEFont is a custom UIFont, UEColor is a static struct of custom UIColor's and UEFontCharacter are linear icon fonts.

Swift : Append Characters in Attributed String

I want to change color to all characters in string. But my code is giving just last character in string. I want to append characters in attributed string. How can I do this ?
My Code :
func test(){
var str:String = "test string"
for i in 0...count(str)-1{
var test = str[advance(str.startIndex, i)]
var attrString = NSAttributedString(string: toString(test), attributes: [NSForegroundColorAttributeName: rainbowColors()])
label.attributedText = attrString
}
}
In this case you don't need to append characters if you want each character to have the same rainbow color. You could do the following:
label.attributedText = NSAttributedString(string: str, attributes: [NSForegroundColorAttributeName: rainbowColors()])
If you want to append characters you need to use NSMutableAttributedString. It has a method called append.
Given the fact that you want a different color for each index do the following:
var str:String = "test string"
var attributedString = NSMutableAttributedString()
for (index, character) in enumerate(str) {
attributedString.appendAttributedString(NSAttributedString(string: String(character), attributes: [NSForegroundColorAttributeName: colorForIndex(index)]))
}
label.attributedText = attributedString
colorForIndex is a function you need to implement to get the rainbow color for that particular index
func colorForIndex(index: Int) -> UIColor {
let color = // your function to get the color
return color
}
If you need help to implement that function take a look at this question iOS rainbow colors array

Can't get attributed string to work in Swift

I'm trying to set some attributes of a string in code, but can't get NSAttributedString to work. This is the function, that's supposed to change the string:
func getAttributedString(string: String) -> NSAttributedString
{
var attrString = NSMutableAttributedString(string: string)
var attrs = [NSFontAttributeName : UIFont.boldSystemFontOfSize(18.0)]
attrString.setAttributes(attrs, range: NSMakeRange(0, attrString.length))
return attrString
}
And this is how I use it:
if (self.product.packageDimensions != nil) {
self.descriptionLabel.text =
self.descriptionLabel.text + self.getAttributedString("Package dimensions:").string +
"\n\(self.product.packageDimensions) \n"
}
But the font stays the same. What am I doing wrong ?
You make 2 errors in your code.
setAttributes needs a Dictionary, not an Array
when you use the string attribute, you will only get a String, all attributes are lost.
To add or change attributes to a attributedString it has to be mutable. You only get a NSMutableString from the attributedText attribute. If you want to change it create a mutable version from it and change it. Then you may set the attributedText to the new mutable version.
If you can give the attributed string as an argument, I will give you an example that works:
func setFontFor(attrString: NSAttributedString) -> NSMutableAttributedString {
var mutableAttrString: NSMutableAttributedString = NSMutableAttributedString(attributedString: attrString)
let headerStart: Int = 0
let headerEnd: Int = 13
mutableAttrString.addAttribute(NSFontAttributeName, value: UIFont.boldSystemFontOfSize(18.0), range: NSMakeRange(headerStart, headerEnd))
return mutableAttrString
}
Usage:
myLabel.attributedText = setFontFor(myLabel.attributedText)
As you can see I used the attributedText property of the UILabel class, it also works for UITextView and others. If you have another label, you can create a new NSAttributedString with the initializer NSAttributedString(normalString) as you already used in the question code.
if (self.product.packageDimensions != nil) {
self.descriptionLabel.attributedText =
self.descriptionLabel.attributedText + self.getAttributedString("Package dimensions:").string +
"\n\(self.product.packageDimensions) \n"
}
You should use the attributedText method

Resources