Capitalized text in UILabel from visual editor in xcode - ios

I am starter in iOS. I found out that there are ways around making the text bold, and changing font and font size etc from visual editor. But are there any ways to set the UILabel text All Capitalized from visual editor (STORYBOARD, NOT CODE). I searched but only found code (Swift/Objective C) based answers like this:
testDisplayLabel.text = testDisplayLabel.text.uppercased()

A legitimate question -- and a useless (if not arrogant) answer marked as Accepted. It is not unusual when you receive from a copywriter a LOT of text that is not All Caps. So the answer is -- you have to process it all programmatically.
EDIT Generally it is a good idea to wrap your text constants programmatically. First it gives you the opportunity to localize your app (even in the future):
extension String {
func localized (lang: String) -> String {
guard let path = Bundle.main.path (forResource: lang, ofType: "lproj") else { return "" }
guard let bundle = Bundle (path: path) else { return "" }
return NSLocalizedString(self, tableName: nil, bundle: bundle, value: "", comment: "")
}
func localized () -> String {
guard let loc = Locale.current.languageCode else { return "" }
return localized(lang: loc)
}
}
So whenever you need to display a string, you apply this method like this:
"My String".localized()
Likewise, your string should start with a common localisation, and then you make them capitalized when needed:
"This should be all caps".localized().uppercased()

By default "lowercase word" and "uppercase word" are unbound in Preferences -> Key Bindings -> Text Key Bindings. Just create a new set and bind them to something. Then you will be able to use the binding to capitalize the text.

Just turn ON caps lock and type text :) that's the way we do in storyboard, Other thing you can do is select a font that has only Uppercase character in it.

Related

Any standard String in SWIFT similar to UIColor.systemgray

In Android, we can access some standard string resources provided by the platform, e.g. cancel, OK, delete etc. It is convenient since I don't have to store all the translation for those simple texts.
I know that Swift provides something similar to UIColor, e.g. UIColor.systemgray.
My question is: Is there something similar but for String. Thanks!
You can technically load localized strings from Apple's own frameworks. For instance, to load from UIKit, you'd use
let bundle = Bundle(for: UIView.self)
let string = bundle.localizedString(forKey: "Cancel", value: nil, table: nil)
When the current locale is German, this gives "Abbrechen".
The downside of this approach is that you'll only know whether or not a specific string exists in the framework at runtime.
The best workaround I can think of for this is to define the keys that you use yourself and continuously verify them with a unit test.
For example you could gather all your system-string keys in a case-iterable enumeration
public enum SystemStringKey: String, CaseIterable {
case cancel = "Cancel"
...
}
and use them to load the system strings via an extension on String
public extension String {
static var systemStringBundle: Bundle {
return Bundle(for: UIView.self)
}
static func systemString(for key: SystemStringKey) -> String {
return systemStringBundle.localizedString(forKey: key.rawValue, value: nil, table: nil)
}
}
In code you can then use the system strings like constants
label.text = .systemString(for: .cancel)
To verify their continued existence, you could use a unit test such as this
class SystemStringKeyTests: XCTestCase {
func testAllKeysExist() throws {
let path = try XCTUnwrap(String.systemStringBundle.path(forResource: "Localizable", ofType: "strings"))
let dict = try XCTUnwrap(NSDictionary(contentsOfFile: path))
for key in SystemStringKey.allCases {
XCTAssertNotNil(dict[key.rawValue])
}
}
}
This isn't 100% bulletproof as it could still happen that Apple removes a string in an iOS update and then any released app that relied on that string would show the untranslated English string until you ship an update yourself.
Update: I threw together a Swift package for conveniently exploring and accessing available strings from system bundles. There are some caveats though. See https://nosuchdomain.mooo.com/git/doc/swift-systemstrings for further info.
No, there are no such static properties in Swift

How to change language of ios app in runtime itself with Base internationalizations swift 3?

I have referred the below link as well as other links. I am able to change the language of the app after exiting.
Is there anyway I can change the language of the app with Base Internationalisation on the go?
For ex: If user selects English it should be reflected throughout the app.
manual language selection in an iOS-App (iPhone and iPad)
This is how I did it. I created an extension on String class and created a localized variable which gets the string values from my Localizable.strings files of a language
public extension String {
var localized: String {
// currentLanguageCode is e.g. "en" or "nl"
let path = Bundle.main.path(forResource: LocalizationService.shared.currentLanguageCode, ofType: "lproj")
let bundle = Bundle(path: path!)
return NSLocalizedString(self, tableName: nil, bundle: bundle!, value: "", comment: "")
}
}
Then everywhere in my code when I want to assign localized string values I do:
titleLabel.text = "settings_label_userProfile".localized
When user changes the language e.g. in my settings section, LocalizationService sets a different language code and from then on localized property will return the values of that language code. You need to make sure that the UI is reloaded if it's still displaying the previous language strings.
EDIT:
This solution will only work if you set your localizable strings programatically.

iOS Localization: Localize views dynamically without messing with the storyboard/nib strings files

So I had this problem, I wanted to localize all views in my app. I have been provided with Localizable strings files including all translations. However, when I tried to localize the storyboard using strings files, it shows as code like this:
/* Class = "UILabel"; text = "Name:"; ObjectID = "21M-2X-4Pf"; */
"21M-2X-4Pf.text" = "Some text to localize";
And I already have the translation to Some Text to localize in the localizable strings files. But manually cross-referencing them for all languages seemed like a pain. Especially when the storyboard changes and I have to re-export them and add the new ones.
I already have a class Language Manager that localises strings for me. It is a very simple class which most important method is this
func localizeString(stringToLocalize:String) -> String
{
// Get the corresponding bundle path.
let selectedLanguage = self.getLanguage()
let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
// Get the corresponding localized string.
let languageBundle = Bundle(path: path!)
return languageBundle!.localizedString(forKey: stringToLocalize, value: "", table: nil)
}
I expanded upon this by writing a method to loop recursively through all views in a view controller, localizing them as it goes. I decided to share this because I think it is quite useful, will work as plug and play in any view controller, and will avoid the cycle of exporting Storyboardy strings files, adding to them, and reintegrating them whenever there is a change. This way you just add to the Localizable.strings file(s) and everything is automatically handled for you.
func localizeUI(parentView:UIView)
{
for view:UIView in parentView.subviews
{
if let potentialButton = view as? UIButton
{
if let titleString = potentialButton.titleLabel?.text {
potentialButton.setTitle(localizeString(stringToLocalize: titleString), for: .normal)
}
}
else if let potentialLabel = view as? UILabel
{
if potentialLabel.text != nil {
potentialLabel.text = localizeString(stringToLocalize: potentialLabel.text!)
}
}
localizeUI(parentView: view)
}
}

How to copy text to clipboard/pasteboard with Swift

I'm looking for a clean example of how to copy text to iOS clipboard that can then be used/pasted in other apps.
The benefit of this function is that the text can be copied quickly, without the standard text highlighting functions of the traditional text copying.
I am assuming that the key classes are in UIPasteboard, but can't find the relevant areas in the code example they supply.
If all you want is plain text, you can just use the string property. It's both readable and writable:
// write to clipboard
UIPasteboard.general.string = "Hello world"
// read from clipboard
let content = UIPasteboard.general.string
(When reading from the clipboard, the UIPasteboard documentation also suggests you might want to first check hasStrings, "to avoid causing the system to needlessly attempt to fetch data before it is needed or when the data might not be present", such as when using Handoff.)
Since copying and pasting is usually done in pairs, this is supplemental answer to #jtbandes good, concise answer. I originally came here looking how to paste.
iOS makes this easy because the general pasteboard can be used like a variable. Just get and set UIPasteboard.general.string.
Here is an example showing both being used with a UITextField:
Copy
UIPasteboard.general.string = myTextField.text
Paste
if let myString = UIPasteboard.general.string {
myTextField.insertText(myString)
}
Note that the pasteboard string is an Optional, so it has to be unwrapped first.
Copying text from the app to the clipboard:
let pasteboard = UIPasteboard.general
pasteboard.string = employee.phoneNumber
SWIFT 4
UIPasteboard.general.string = "TEXT"
in Swift 5 i can copy text to clipboard using
UIPasteboard.general.string = "Hello world"
then you can paste the text anywhere of your device
Write below the code where you want to Copying String or Text
UIPasteboard.general.string = "Dhaval Gevariya" // Put your String here
this is for read String from clipboard.
var readString = UIPasteboard.general.string
import UIKit.UIPasteboard
extension UIPasteboard {
static func pasteToClipboard(_ content: String) {
self.general.string = content
}
static func readFromClipboard() -> String? {
return self.general.string
}
}

Localized String with Interface Builder User Defined Runtime Attributes

I am currently trying to create a localized accessibilityLabel in the storyboard (I am trying to avoid doing it programatically). It seems that whenever I use the Localized String option, the accessibilityLabels ends up being set to the localized string key that I have provided rather than the string itself. Does anyone have the solution to this problem? Any help would be greatly appreciated.
I guess you expect the localized string to be taken from Localizable.strings. The "Localized String" type doesn't work this way, it's just a marker to indicate that the value of the user defined runtime attribute will participate in the localization process when you use base localization. Please take a look at https://stackoverflow.com/a/24527990/2876231 for a lengthier explanation.
The attribute type needs to be Localizable String, and then you'd translate it in the .strings file using the following property:
"KLc-fp-ZVK.ibExternalUserDefinedRuntimeAttributesLocalizableStrings[0]" = "¡Hola!";
Unfortunately, it doesn't seem to work with a named attribute, but only with the long property above.
(Based on Andrew's answer here: Localize a view within a storyboard using "User Defined Runtime Attributes")
I did the customization of an attribute with the simple solution of localizing the attribute by code:
private struct AssociatedKeys {
static var someTagKey = "someTag"
}
#IBInspectable var someTag: String? {
get {
return NSLocalizedString(
objc_getAssociatedObject(self, &AssociatedKeys.someTagsKey) as? String ?? "", comment: "")
}
set {
if let newValue = newValue {
objc_setAssociatedObject(
self,
&AssociatedKeys.someTagsKey,
newValue as NSString?,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
}
}
}
And after that you can easily extract all the strings from the xib and storyboard files with an egrep:
egrep -ohr --include="*.xib" --include="*.storyboard" '<userDefinedRuntimeAttribute type="string" keyPath="someTag" value="[^"]+"/>' . >> extracted-strings.txt
And after that eliminate the tags in the strings file by the following sed and then you have to plain strings file for xcode ready:
sed -i -e 's/^<userDefinedRuntimeAttribute type="string" keyPath="someTag" value=\("[^"]*"\)\/>/\1 = \1;/g' extracted-strings.txt

Resources