How to localize Accessibility Label(Description) with Interface Builder? - ios

In order to add VoiceOver support for my app(using Interface Builder),I set a button's "Accessibility Identity -> Description" to "Mute" like this.This actually set accessibility label.
And now,I want to add localization for this button,including accessibility label of it.
How can I do that?
ps: I've tried the programmatically way(NSLocalizedString) and creating xib file for each language.But both of them are not good for maintenance.I want to know if I can localize it in ".strings" way

You can create extension like this and then set keys in UI Builder but handle localization in .strings file
#IBDesignable
public extension UIView {
#IBInspectable
var accessibilityLabelKey: String {
get { return "" }
set {
self.accessibilityLabel = NSLocalizedString(newValue, comment:newValue)
}
}
}

Related

How is this showed up?

I want to make a similar UI like that
Login Screen and you can see when i clicked on an image constraint the attribute inspector shows up one more menu "Adaptive Layout Constraint" Layout.
How is this happened and how i can show up the same menu in my project. Thank you.
It looks like a custom class with #IBInspectable property setAdaptiveLayout
class AdaptiveLayoutConstraint: NSLayoutConstraint {
#IBInspectable
var setAdaptiveLayout: Bool {
set {
//doWhatYouWant
}
get {
//doWhatYouWant
}
}
}

How to capture a text value from an UI label / Textfield using accessibility ID in EarlGrey?

I am using EarlGrey framework but not sure which will be the method used to capture text value from an UI lable/ Textfield when using accessibility ID.
You can use grey_accessibilityID("") Like so:
class MyFirstEarlGreyTest: XCTestCase {
func testExample() {
EarlGrey
.select(elementWithMatcher: grey_accessibilityID("phone_number_text_field"))
.assert(grey_sufficientlyVisible())
.perform(grey_replaceText("1234"))
}
}
I hope this helps!

Use localized strings in storyboard

I'm pretty new to iOS development and I was asking my self if it is possible to use localized strings from my "Localizable.strings" file directly into the storyboard.
For example in Android you can do it from the XML file like this:
android:text="#string/notConnected"
I understood that you can make a localized version of the storyboard, but having different strings files and different storyboards looks pretty ugly to me.
So is it possible to have only strings files and use what I need into the storyboard? Preferably without setting it from code?
EDIT:
This is practically what I want to do:
So is this possible? Is there a legit way to call a string from there like in Android?
I think being able to localise Strings in the storyboard is of significant advantage. I don't agree with #elk_cloner that hooking up IBOutlets for every UILabel is the way forward.
One way of getting it to work is using an #IBInspectable property on a UILabel subclass:
class LocalisableLabel: UILabel {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
text = NSLocalizedString(key, comment: "")
}
}
}
In the storyboard set the custom class:
In the attributes inspector the localisedKey field will appear and you can just add your key here.
That's it!
EDIT:
You can localise UIButtons the same way, BUT if the text in the storyboard's title field differs from the localised String (which it will in other languages) the setting of the title will animate.
To fix this, put the setTitle in a performWithoutAnimation block:
class LocalisableButton: UIButton {
#IBInspectable var localisedKey: String? {
didSet {
guard let key = localisedKey else { return }
UIView.performWithoutAnimation {
setTitle(key.localized, for: .normal)
layoutIfNeeded()
}
}
}
}
In addition to Leon's answer, you can get rid of the need for an explicit subclass by using an extension:
extension UILabel {
#IBInspectable var localizableText: String? {
get { return text }
set(value) { text = NSLocalizedString(value!, comment: "") }
}
}
According to your requirement it's not possible but
You don't need different storyboards for localization
Suppose you want to localize a label string.
Draw and outlet and change text using
mylabel.text = nsLocalizedString("THIS_IS_MY_STRING",nil);
Of course in your localization file there will be a line.You must have different files for different language.Suppose you have a file for english and there must be a line.
"THIS_IS_MY_STRING" = "This is my string";
When you compile your app, that function will use mapping to localize your app.
Edit:
If you want detail information please have a look at these tutorials
internationalization-tutorial-for-ios-2014
and ios-localization-tutorial
There are some online script(e.g localize.py) which will help you to automatically search all of your code and find out nslocalizedString function and make lines in your localizableString files. like this.
"THIS_IS_MY_STRING" = "THIS_IS_MY_STRING"
and later on you just have to write actual string there. :)
Make a button class and set #IBInspectable attribute to the button class
class Button: UIButton {
#IBInspectable public var referenceText: String = "" {
didSet {
self.setTitle(NSLocalizedString(referenceText, comment: ""), for: .normal)
}
}
}
Then in the storyboard you can set referenceText
The button text will be "Sign In"
Another possible way is to localize the storyboard and simply change the values for labels and buttons directly on the .string file.
First select the storyboard, and click on localize:
Then you'll be able to select the languages you want.
This way you'll be able to continue developing on your language of choice and simply edit the .string file that is generated
for button
extension UIButton {
#IBInspectable var localizableText: String? {
get { return titleLabel?.text }
set(value)
{
setTitle(NSLocalizedString(value!, comment: ""), for: .normal)
}}}

Can't make User Defined Runtime Attributes work

I would really like to be able to use the "User Defined Runtime Attributes " from xcode Storyboard to build a nice pop up through a container view.
Unfortunately, I can't make it works and can't figure out why !
I found many topics (eg: Is it possible to set UIView border properties from interface builder?) which deal about it but this doesn't work for me... !
Here is the attribute inspector of the containerView embed UIView (I also tried to implement into containerView UIView too with no success).
I added an extension to transform UIColor to CGColor as expected :
extension CALayer {
var borderUIColor: UIColor {
set {
self.borderColor = newValue.CGColor
}
get {
return UIColor(CGColor: self.borderColor!)
}
}
}
Does someone could think about something missing ?
Thank you very much in advance ;)
Instead of layer.borderColor, use layer.borderUIColor in your user defined runtime attributes. Just double click the key name and add UI.

XCode - Change Default Global Font in Storyboard

Very much like how we can set the Global Tint in Storyboard, Is it possible to set the global font-family as something else?
For example, I want to change the Global/Default Font from System to Source Sans Pro 16pt. However, what I have to do (to my knowledge) is one of the following:
Change font of each label, button, textField, etc. in Storyboard.
Set it via Swift ViewDidLoad Code (like this question) or through extensions as explained in this question
My Problem with (2) is that I do not get Visual Feedbacks like in (1) using storyboards. On the other hand, it is also not very eloquent as I have to manually set it anyway.
So, is there a way to change/set the default Storyboard font?
You can use the Appearance API, to ensure that all controls have the same font (at runtime)
Look at this question as to how to set the font for UIButton with Appearance.
For UILabel and UITextView, do the following. This can be done in AppDelegate application(_:didFinishLaunchingWithOptions:)
let labelAppearance = UILabel.appearance()
labelAppearance.font = UIFont.myFont()
let textFieldAppearance = UITextView.appearance()
textFieldAppearance.font = UIFont.myFont()
The previous solution, however will not update storyboard.
To see the changes visually on storyboard, you can look into the function
prepareForInterfaceBuilder()
Here is an answer that explains how to get it visually updated in storyboard, but for this you will need to use custom classes for your textFields, buttons, etc.
Code Example as per above link:
#IBDesignable
public class MyUILabel: UILabel {
public override func awakeFromNib() {
super.awakeFromNib()
configureLabel()
}
public override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
configureLabel()
}
func configureLabel() {
font = UIFont(name: Constants.DefaultFont, size: 40)
}
}

Resources