How can I vertically align my status bar item text? - swift

Left one on the picture is the date and time from Apple and one is my application one. As you may see the text of my application appears lower than the Apple one. Which doesn't look pretty. How can this be resolved?
self.statusBarItem.image = nil
self.statusBarItem.button?.imagePosition = .NoImage
self.statusBarItem.button?.title = "Sun 5 Jun 13:35"

You could do it in offset. You cannot do it like this since it needs to be done on the status item button bar.
button.frame = CGRectMake(0.0, 0.5, button.frame.width, button.frame.height)

I wanted to make a quick addition to this. While the accepted answer does indeed work based on the context of the question. It will not work if you have an image, as this moves everything (image and text). I have found for some reason, the image is vertically centered, but the text is not.
What you actually want to do in that case is set NSAttributedString.Key.baselineOffset, where you derive the baseline value as follows
var displayScale: CGFloat = 1.0
let pstyle = NSMutableParagraphStyle()
pstyle.alignment = .center;
let aStr = NSAttributedString(string: str, attributes: [NSAttributedString.Key.paragraphStyle: pstyle, NSAttributedString.Key.font: font])
if let main = NSScreen.main {
displayScale = main.backingScaleFactor
if displayScale <= 0.0 {
displayScale = 1.0
}
}
let textHeight = aStr.size().height
baselineOffset = ((font.ascender - font.descender) - textHeight) / displayScale
button.attributedTitle = = NSAttributedString(string: str, attributes: [NSAttributedString.Key.paragraphStyle: pstyle, NSAttributedString.Key.baselineOffset: baselineOffset, NSAttributedString.Key.font: font])
Disclaimers here are that I'm not completely sure about the displayScale part. I theorize this is needed to correct for pixels/points.
I've only added this answer because I was struggling to find a good answer for this. I got my inspiration to do this based on this: Center two fonts with different different sizes vertically in an NSAttributedString
If this technique is wrong, I'd be interested to know so I can fix it.

Related

How to smoothly change text in UILabel

I have some UILabels next to each other containing text.
It could be:
2x-5 = 3
I can drag "-5" to the other side.
2x = 3-5
It then moves in to place next to "3" and then I change the sign from - to +, within a UIView.animate() function.
Because "+" is a little bit wider than "-" the text goes past the limits of the UILabel, which cuts of the text in one side.
So I resize the labels width, but it is visible when using the application.
I have tried changing the size of the label before I change the sign, just adding a lot of space.
But it still cuts some of the text off.
Here is the code:
let v = UILabel()
v.text = "+5"
UIView.animate(withDuration: 0.5, animations: {
v.frame.size.width = v.intrinsicContentSize.width + 20
v.text = "-5"
v.font = UIFont.boldSystemFont(ofSize: 45)
v.textAlignment = .center
v.frame.size.width = v.intrinsicContentSize.width
v.frame.size.height = v.intrinsicContentSize.height
}
Optimally I want the label not to cut off any of the text when the width of the text is changed.
(Edit: removed other question unrelated to main question)
Thank you in advance for any help!

NSMenuItem with attributedTitle containing an NSFont object draws the title with baseline shift

I'm tying to create an NSPopUpButton with the list of fonts available in the system. Seemed pretty obvious task but I've failed. I guess, I'm missing something so obvious that I've completely forgot about it.
The code is pretty straight:
let button = NSPopUpButton()
button.menu = NSMenu()
NSFontManager.shared.availableFonts.forEach { fontNameString in
let item = NSMenuItem()
let font = NSFont(name: fontNameString, size: 14)!
let attrs: [NSAttributedString.Key: Any] = [.font: font]
item.attributedTitle = NSAttributedString(string: fontNameString, attributes: attrs)
button.menu?.addItem(item)
}
But that just creates the NSMenu with items having shifted baselines. I've tried to calculate the baseline offset and add it as an attribute but I've failed. Haven't found an algorhythm to satisfy all the font available in the system.
Besides, adding the baseline offset resizes the corresponding NSMenuItem which does not have a fixed size, by the way - the height of an item is different on every font.
To analyse the situation I've added the .backgroundColor attribute and set it to red NSColor. And that brought even more confusing. It appears that some font somehow not drawing in bounds.
How can I center the attributed title vertically? Please, help!
Probably, that is NSAttributedString's issue.
To workaround, I created a custom view and drew a string in it with a trick.
Then set it to NSMenuItem.view.
Get more details, see my codes below.
https://github.com/bluedome/FontSelectionView/blob/main/FontSelectionView.swift
Hope it help, if you're still having the trouble...

Set NSTextView to wrap by char either programmatically or through xcode?

There are a couple of solutions online but they are either 10 years old and no longer work or are written in objective C (And also very outdated). One solution involved AttributedText and changing the line break style every single time the content is updated, which for me would be hundreds of calls every few minutes. Surely this can't be the best way. I must be missing something here, there must be a way to set an NSTextView to wrap by char permanently.
I've tried this but it doesn't work and continues to wrap by word:
consoleTextView.textContainer?.lineBreakMode = NSLineBreakMode.byCharWrapping
I've also tried using the attributes inspector in xcode. I finally found the option for it but clicking it does nothing, it just continues to say 'empty selection' in the 'line breaking' field:
You are supposed to set the line break modes on the paragraph styles. This is the smallest possible example to make it work:
let textView = NSTextView(frame: CGRect(x: 0, y: 0, width: 100, height: 200))
let paragraphStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
paragraphStyle.lineBreakMode = .byCharWrapping
textView.defaultParagraphStyle = paragraphStyle
textView.string = "12345 12345 12345"
view.addSubview(textView)
Anyone looking for an objective-c answer would use something similar to:
NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
myTextView.defaultParagraphStyle = paragraphStyle;

Is it possible to Change the Regular font to Bold of UILable text?

I have a Label with custom font Unica One-Regular. Since, it is not available in bold font, I am getting problem to make it bold. Is there any way to make it bold?. Here is the font link.
https://fonts.google.com/specimen/Unica+One?selection.family=Unica+One
Thanks in advance.
Sorry I’m on my iPhone but,
Please check the exact name of the font on Xcode, but this code should answer your question :
let attrs:[String:AnyObject] = [NSFontAttributeName: UIFont(name: "Unica One-Bold", size: 12)!]
let boldString = NSMutableAttributedString(string: "text", attributes:attrs)
let lbl = UILabel()
lbl.attributedText = boldString
There is a more recent answer to this question at Is it possible to increase the boldness of the font if the bold font file is not available?.
Short summary: if you have a list of font attributes, you can add a negative stroke width. For example (in Swift):
import AppKit
guard let chosenFont = NSFont(name: "VTypewriter Underwood", size: 24) else {
print("No such font")
exit(1)
}
var fontAttributes = [
NSAttributedString.Key.font:chosenFont,
NSAttributedString.Key.strokeWidth:NSNumber(value:-3.0)
]
let fakelyBoldedText = NSAttributedString(string:"Hello World", attributes:fontAttributes)
This is not optimal; it isn’t really bolding. But with low values for the stroke width (in my experiments, from about -3 to -5, possibly relative to the font width), it does look bolded.

Attributed string cutting and displaying single word into two lines on UILabel

I'm creating attributed text using following attributes,
func attributedString(font: UIFont, contentColor: UIColor, alignment: NSTextAlignment) -> NSAttributedString {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 0.6
paragraphStyle.lineHeightMultiple = 0.8
paragraphStyle.alignment = alignment
paragraphStyle.lineBreakMode = .byWordWrapping
let lineSpacingAttribute: [NSAttributedStringKey: Any] = [NSAttributedStringKey.paragraphStyle: paragraphStyle, NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: contentColor]
let attributedString = NSAttributedString(string: self, attributes: lineSpacingAttribute)
return attributedString
}
I'm displaying this text on UILabel inside a custom tableViewCell. But, it is cutting a single word into two (cutting last letter of a word and displaying it on next line). I've set the numberOfLines to zero, and preferredMaxLayoutWidth for label. And I'm using a custom font.
This problem is happening on small screens only, iPhone SE and iPhone 5S simulators. But, on other simulators it is displaying correctly. Could you please help me to figure out what is wrong in this?
Thanks!
From Apple doc:
var preferredMaxLayoutWidth: CGFloat
This property affects the size of the label when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text flows to one or more new lines, increasing the height of the label.
Depending on your text you can use the adjustsFontSizeToFitWidth property with the minimumScaleFactor property