How to set alignment for WKInterface Label using setAttributedText - swift

I'm trying to set alignment for WKInterfaceLabel using setAttributedText function. Here is my code:
var paragraphStyle = NSParagraphStyle.defaultParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.Center
var attributedDictonary = [NSForegroundColorAttributeName:UIColor.greenColor(), NSParagraphStyleAttributeName:paragraphStyle]
var attributeString = NSAttributedString(string: "TextAttributed", attributes: attributedDictonary)
self.titleLabel.setAttributedText(attributeString)
But I got a problem with this line:
paragraphStyle.alignment = NSTextAlignment.Center
I got error: Cannot assign to 'alignment' in 'paragraphStyle'
How to set alignment for WKInterfaceLabel using setAttributedText?

You need to use NSMutableParagraphStyle:
var paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.CenterTextAlignment

Related

CIAttributedTextImageGenerator filter - text doesn't fit (NSAttributedString)

I use a Core Image filter CIAttributedTextImageGenerator to generate text as a CIImage. However, sometimes the text just doesn't fit into the resulted CIImage as you can see at the picture:
I tried to play with different key-values of NSAttributedString to make some padding around text but with no success:
func generateImageFromText(_ text: String, style: TextStyle) -> CIImage? {
let font = UIFont.init(name: style.fontName, size: style.fontSize)!
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = style.textAlignment
paragraphStyle.headIndent = 5.0
paragraphStyle.tailIndent = -5.0
paragraphStyle.firstLineHeadIndent = 0
let shadow = NSShadow()
if let shadowStyle = style.shadowStyle {
shadow.shadowColor = shadowStyle.color
shadow.shadowOffset = shadowStyle.offset
shadow.shadowBlurRadius = shadowStyle.blurRadius
}
var strokeColor = UIColor.clear
var strokeWidth: CGFloat = 0.0
if let strokeStyle = style.strokeStyle {
strokeColor = strokeStyle.color
strokeWidth = strokeStyle.width
}
let attributes: [NSAttributedString.Key: Any] = [
.baselineOffset: 50,
.font: font,
.foregroundColor: style.color,
.paragraphStyle: paragraphStyle,
.shadow: shadow,
.strokeColor: strokeColor,
.strokeWidth: strokeWidth
]
let attributedQuote = NSAttributedString(string: text, attributes: attributes)
let textGenerationFilter = CIFilter(name: "CIAttributedTextImageGenerator")!
textGenerationFilter.setValue(attributedQuote, forKey: "inputText")
textGenerationFilter.setValue(NSNumber(value: Double(1.0)), forKey: "inputScaleFactor")
guard let textImage = textGenerationFilter.outputImage else {
return nil
}
return textImage
}
Maybe there are some values of NSAttributedString that I miss which can help to fit in the text?

How to display multiple rows in macos menubar app?

Originally I thought adding new line should work. The problem is, the line height is too big. How can I make it more dense(closer to each other)?
There's the following example on git starting line 41. But apple docs say that custom view inside of NSStatusItem is deprecated. (not sure if it's deprecated for views inside of NSMenuItem)
let statusBar = NSStatusBar.system
statusBarItem = statusBar.statusItem(withLength: NSStatusItem.squareLength)
statusBarItem.button?.title = "123\n456"
UPD
What I got so far. It's not Y centred though. And statusItem?.button?.frame = CGRect(x: 0.0, y: -2.0, ... seems incorrect and shifts the leading icon to the bottom.
var comb = NSMutableAttributedString(attributedString: str1)
comb.append(br) // new line
comb.append(str2)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.maximumLineHeight = 9
comb.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, comb.length))
statusItem?.button?.attributedTitle = comb
UPD (retarted approach with \n and baselineoffset)
var comb = NSMutableAttributedString(attributedString: NSAttributedString(string: "\n")) // this
comb.append(top)
comb.append(br)
comb.append(bottom)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.maximumLineHeight = 9
comb.addAttribute(NSAttributedString.Key.baselineOffset, value: 3.0, range:NSMakeRange(0, comb.length))
As matt noted, use attributeTitle and NSMutableParagraph
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.maximumLineHeight = 9
paragraphStyle.alignment = .left
Columns formatting can be achieved by using tabs, spaces, or other separators
NSAttributedString(string: "\n10 \u{2022} 220 \u{2022} 4999", attributes: textAttr) // this is a row
statusItem?.button?.attributedTitle = rows
And to shift text from the bottom:
rows.addAttribute(NSAttributedString.Key.baselineOffset, value: 2.0, range:NSMakeRange(0, rows.length))

Add a label after a String

I need to create a line of text with two colors
There will Be a text, which is string in black and there will be one $ Symbol and it should be red.
lazy var dollarSmb: UILabel = {
let smb = UILabel()
smb.text = "$"
smb.font = UIFont.systemFont(ofSize: 17, weight: .regular)
smb.textColor = UIColor.red
smb.baselineAdjustment = .alignCenters
smb.translatesAutoresizingMaskIntoConstraints = false
return smb
}()
And I want to add it after the label string, something like that:
Var label = "This is a test" + " \(dollarSmb)"
It's not working
Could anyone help me the best way to do that?
Many thanks
You could use NSAttributedString to construct a single string with a different color.
let attributedString = NSMutableAttributedString(string: "This is a test ")
let dollarSymbl = NSAttributedString(string: "$", attributes: [.foregroundColor: UIColor.red])
attributedString.append(dollarSymbl)
// Then assign it to a UILabel
label.attributedText = attributedString
Use an NSAttributedString and instead of setting smb.text, set smb.attributedText.
Something like
smb.attributedText = NSAttributedString(string: "$", attributes [.foregroundColor: UIColor.red])

center and bold TextView swift

Hi all I am trying to set a bold and centre to my text view I have 3 different colours in the view but I want the 2 colours that change to be centred. Is there a way to do this? below is my code.
let myString:String = DisplayableContents.texts[10]
var myMutableString = NSMutableAttributedString()
myMutableString = NSMutableAttributedString(string: myString, attributes: [NSFontAttributeName:UIFont(name: "Calibri", size: 17.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location:74, length:96))
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.gray, range: NSRange(location:96, length:19))
// set label Attribute
infoBox.attributedText = myMutableString
Try with
let myString:String = DisplayableContents.texts[10]
var myMutableString = NSMutableAttributedString()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = NSTextAlignment.Center
myMutableString = NSMutableAttributedString(string: myString, attributes: [NSParagraphStyleAttributeName:paragraphStyle, NSFontAttributeName:UIFont(name: "Calibri", size: 17.0)!])
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location:74, length:96))
myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor.gray, range: NSRange(location:96, length:19))
// set label Attribute
infoBox.attributedText = myMutableString
But 'Calibri' doesn't exist in iOS. You can check fonts in http://iosfonts.com/. If you are adding the font to your project check its bold variation, probably 'Calibri-Bold'

is it possible to set the UILabel distance between the line?

Is it possible to set a UILabel's distance between the line, as i had a UILabel contain 3 lines, and linebreakmode is wordwrap?
If you're referring to "leading", which refers to the gap between lines of type - you cannot change this on a UILabel. That is inferred from the front of the label itself. Some people have tried to create categories to override the "leading" property of the UIFont for the label but it doesn't actually work when rendering.
If you really need to control the vertical spacing between lines of text then your best bet is to programmatically drop 1 UILabel per line of fixed width and control the vertical gap yourself.
Here is how you can set line spacing using interface builder and programatically as well.
From Interface Builder:
Programmatically:
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 = "is\nit\npossible\nto\nset\nthe\nUILabel\ndistance\nbetween\nthe\nline?"
// 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 = "is\nit\npossible\nto\nset\nthe\nUILabel\ndistance\nbetween\nthe\nline?"
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