Cocoa/Swift: NSStatusBarItem's text gets trimmed when using a picture - swift

When creating an NSStatusBar.systemStatusBar related application for MacOS, I stumbled upon a problem that seemed strange to begin with. The problem is: when using an image and a text for the NSStatusBar, the text was being clipped unless you manually specified a sufficient length, which would be hardcoded and causes problems with alternating lengths. How can this be solved?
// The -1 is supposed to mean "variable length"
let myStatusItem = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(-1))
myStatusItem.image = NSImage(named: "customImage")
myStatusItem.title = "Some special information"
This would be the normal case where this problem will occur.

After playing around with some ridiculous variations, I realized that the problem can be fixed when using BOTH .title and .attributedTitle parameters of the NSStatusBar item.
Also make sure that you declare the .image BEFORE you declare the titles. If you want to use the .attributedTitle, define it after .title - if you want to use the plain .title, just define it after the .attributedTitle.
// The -1 is supposed to mean "variable length"
let myStatusItem = NSStatusBar.systemStatusBar().statusItemWithLength(CGFloat(-1))
myStatusItem.image = NSImage(named: "customImage")
myStatusItem.title = "Some special information"
myStatusItem.attributedTitle = NSAttributedString(string: "Some special information")

Related

Button text shrinks when the text is changed

Ones I change the text in button it's getting stink to font size of ~18 even though initial font size is 55. Button is not custom. It has System font.
button.setTitle("Some button text", for: .normal)
I tried manually change font size in code but it doesn't help
button.titleLabel?.font = UIFont.systemFont(ofSize: 55)
I also tried to change the name through configuration function, but there is no font size and it shrinks anyway.
`
button.configuration = paperButtonConfiguration()
func buttonConfiguration() -> UIButton.Configuration {
var config: UIButton.Configuration = .plain()
config.title = "Some button text"
//Should probably be something like this but it doesn't work
//config.font = UIFont.systemFont(ofSize: 55)
return config
}
`
While I was writing this question I kind of solve this, but not completely. If I change the button style from "plain" to "default" it works, but some weird animation of fading and appearance occurs.
How could I do this with "plain"?
UIButton has four type are Plain,Grain,Tinted,Filled .When you create a button in storyboard , button type automatically set with Plain that means new UIButton configurations is on. If you want to old behaviour , you must set style plain to default.
Or , If you want one of the style above . You need to set font like
button.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { incoming in
var outgoing = incoming
outgoing.font = UIFont.systemFont(ofSize: 50)
return outgoing
}

Forcing UIButton to have just one title line

I'm trying to force the UIButton to accept just one line of text, and if the title is too long I would like to have "..." at the end or in the middle of the title. but when I try out the code below, unfortunately, it doesn't work, it still gives multiline title text.
titleButton.titleLabel!.lineBreakMode = .byWordWrapping
titleButton.titleLabel!.numberOfLines = 1
titleButton.titleLabel!.textAlignment = .center
The main problem was the button style which was on the "plain", the magic happened after changing it to default!
It sounds like you want lineBreakMode.byTruncatingTail or .byTruncatingMiddle.

How did NPM create the border for their update message?

I'm assuming they used unicode characters to render the yellow box around the update message.
What characters were used and does it look the same on all platforms?
How did NPM create the border for their update message?
NPM uses npmlog to print to the console, and npmlog utilizes console-control-strings & gauge.
console-control-strings mostly offers convenience functions for moving the cursor around the line and coloring the text.
gauge provides the progress bar and spinner and a way to style them.
What characters were used and does it look the same on all platforms?
Unicode box-drawing characters are used for the border characters. I didn't research the exact unicode characters that NPM uses. Assuming that the terminal/platform is implemented to support unicode and, doesn't override the standard charset with its own characters (ie. emojis), I don't see why it wouldn't look the same across platform.
The below snippet unicode characters don't match exactly. Instead, it demonstrates how to use control-control-strings to print something close to what NPM outputs. I'm sure with enough tinkering you could get it to be exact.
const control = require('console-control-strings')
let title = `${control.color('cyan')}Update available 5.0.3 \u2192 5.0.4${control.color('reset')}`
let subtitle = `Run ${control.color('cyan')} npm i -g npm ${control.color('reset')}`
let borderWidth = (title.length > subtitle.length ? title.length : subtitle.length)
let topLeftCorner = '\u256D'
let topRightCorner = '\u256E'
let btmRightCorner = '\u256F'
let btmLeftCorner = '\u2570'
let border = [...Array(borderWidth)].map(() => { return '\u2500' }).join('')
let topBorder = `${control.nextLine()}${control.color('yellow')}${topLeftCorner}${border}${topRightCorner}${control.color('reset')}`
let btmBorder = `${control.nextLine()}${control.color('yellow')}${btmLeftCorner}${border}${btmRightCorner}${control.color('reset')}`
let lineWrapper = `${control.color('yellow')}\u2502${control.color('reset')}`
console.log(topBorder)
console.log(`${lineWrapper}${control.forward(borderWidth)}${lineWrapper}`)
console.log(`${control.nextLine()}${lineWrapper}${control.forward(4)}${title}${control.forward(5)}${lineWrapper}`)
console.log(`${lineWrapper}${control.forward(11)}${subtitle}${control.forward(10)}${lineWrapper}`)
console.log(`${lineWrapper}${control.forward(borderWidth)}${lineWrapper}`)
console.log(`${btmBorder}${control.color('reset')}`)

Add Placeholder to UITextField, how to set the placeholder text programmatically in swift?

I'm pulling out a phone number from a database, and when the user begins editing in the text field to change that phone number I'd like to use the number I currently have in the database as the placeholder. Since this information changes with each user, how can I set it programmatically in swift?
You need to get the phone number from your database first (convert them to String), then you set placeholder of your textField to that String, like so
textField.placeholder = phoneNumberString
Swift 3
If your textField has text, you need to first set text property to nil, then set placeholder text:
textField.text = nil
textField.placeholder = "My Placeholder Text"
Important to note for anyone else reading this, setting placeholder text in the main.storyboard seems to nullify this solution, so I had to first clear out my placeholders in the storyboard before implementing this. Once that was done #Khuong and #Himanshu's answer worked perfectly.
Apply this line of code in to View Did Load
new_Password.attributedPlaceholder =
NSAttributedString(string: " New Password", attributes: [NSForegroundColorAttributeName : UIColor.white]) // new_Password : our text feild name
Fetch your desired data from your database (Core data) and after converting it into string format... say phoneString
use this line to set this string as a placeholder text
phoneTextField.placeholder = phoneString
Objective-C code:
[usernameText setPlaceholder:#"My Placeholder Text"];
Just a note to say if you have changed your textfield's text and background colors programmatically, you can't do that with the placeholder text's colors and must set up an Attributed Placeholder instead. This is a problem if your device is in put in "dark mode" and are trying to make a non-dark mode screen by hand - you might not be able to see the placeholder!

Changing app language on the fly in iOS

I am new to iOS and I know this is a very frequently asked question, but I have found no appropriate answer for my query.
I have added text to controls on the app like this
let productDescriptionCell = tableView.dequeueReusableCellWithIdentifier("textDescriptionCell") as! TextDescriptionCell
productDescriptionCell.labelForCell.text = "Description"
productDescriptionCell.labelForCell.sizeToFit()
productDescriptionCell.labelForCell.adjustsFontSizeToFitWidth = true
like the 'Description' text above.
I want to have a button in my app, which lets the user change the language on the fly. I have found the following code as the most relevant but this requires an app restart.
userDefaults.setObject(["\(cc)"], forKey: "AppleLanguages")
userDefaults.synchronize()
In addition, I have text hard coded in my storyboard controllers, I want those localized as well. How can I achieve this?
Thai and English are the languages I need localization for
productTitleCell.textFieldForCell.placeholder = SpecProvider.spec.localizedTuv(createLocalizedString("en", tuvEnglish: "Enter Title", tuvThai: "ป้อนชื่อ"))
func localizedTuv(localizedString: LocalizedString) -> String {
var locale = LocaleSelectionService.sharedInstance.getCachedLocale()
if locale.isEmpty {
locale = ""
}
switch(locale) {
case "en": return localizedString.getTuvEnglish()
case "th": return localizedString.getTuvThai()
default: return localizedString.getTuvEnglish()
}
}
I have tried the above code, but this could get very tedious. Please help, I am really stuck!
You have to create string files, and add the labels for every language you want to support. Once this is done you can use NSLocalizedString for the text used in your ViewController.
Here's a tutorial http://www.raywenderlich.com/64401/internationalization-tutorial-for-ios-2014