I'm working on an app that has a toggle button to switch between English and Arabic language and should be on the fly. I'm using the method in https://github.com/maximbilan/ios_language_manager and it works fine in all cases except if the storyboard is localized by interface not strings:
Now when I reload the root view controller like this:
func reloadRootVC(){
let delegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
delegate.window?.rootViewController = (storyboard.instantiateInitialViewController())
}
it reload the root with localized strings and in RTL but with the english storyboard not the arabic one.
Tried force loading the arabic one like this:
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle(path: NSBundle.mainBundle().pathForResource(LanguageManager.currentLanguageCode(), ofType: "lproj")!))
but unfortunately it loads the storyboard but with no images. It can't read any resource image.
strings files from the xib, which make localization pretty straight forward. Right click on the xib file in Xcode, and choose Get Info . Select the General tab and on the bottom click Make File Localizable . Then you will be able to add localizations by clicking Add Localization on that same tab.
Localization is the process of making your app support other languages. In many cases, you make your app with English user interface first and then localize the app to other languages such as Japanese. The process of localization is tedious, and steps of it change little by little as XCode gets updated.
I ended up by moving the arabic storyboard outside and name it Main-AR, then adding an extension in UIStoryboard
to swizzle and initializer of storyboard to add -AR
to the end of the storyboard name if i'm on arabic mode.
extension UIStoryboard {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
// make sure this isn't a subclass
if self !== UIStoryboard.self {
return
}
dispatch_once(&Static.token) {
let originalSelector = #selector(UIStoryboard.init(name:bundle:))
let swizzledSelector = #selector(UIStoryboard.initWithLoc(_:bundle:))
let originalMethod = class_getClassMethod(self, originalSelector)
let swizzledMethod = class_getClassMethod(self, swizzledSelector)
class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
// MARK: - Method Swizzling
class func initWithLoc(name: String, bundle storyboardBundleOrNil: NSBundle?) -> UIStoryboard{
var newName = name
if LanguageManager.isCurrentLanguageRTL(){
newName += "-AR"
if #available(iOS 9.0, *) {
UIView.appearance().semanticContentAttribute = .ForceRightToLeft
} else {
// Fallback on earlier versions
}
}
else{
if #available(iOS 9.0, *) {
UIView.appearance().semanticContentAttribute = .ForceLeftToRight
} else {
// Fallback on earlier versions
}
}
return initWithLoc(newName, bundle: storyboardBundleOrNil)
}
}
change the bundle which is used to init the storyboard:
let path = Bundle.main.path(forResource: "ar", ofType: "lproj")
let bundle = Bundle(path: path!)
let delegate : AppDelegate = UIApplication.shared.delegate as! AppDelegate
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
delegate.window?.rootViewController = (storyboard.instantiateInitialViewController())
although this change the storyboard based on language but do not load images! :(
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With