I'm trying to localize my application to have both English and Arabic.
I have a UIDatePicker of CountDownTimer mode and when my app in English all is fine. However, when I switch it to arabic problems arises.
I have got two problems. I will be happy if I can solve at least one.
1. Count Down Timer Picker texts wont change from English to Arabic if I change the picker locale. And Since its made by apple I don't know if I can manually localize it.
2. Since I can't solve the above problem I decided to keep it in English but fix it layout (Since Arabic is RightToLeft and I forced the UIView to be that). Problem is picker semantic is being ignored when I set it to LeftToRight. So I'm stuck with Right To Left Count Down Picker & in English. P.S: Sometimes the picker looks backward and weird when the language is Arabic see picture: https://imgur.com/a/AdHZBBM
Here is my code:
First of All Not using StoryBoard
I have Count Down Timer in a xib file. Pic: https://imgur.com/681pOjx
My ViewController is a TableController with one cell which is the Count Down Timer Picker. Code:
var lang = "en"
import UIKit
class ViewController: UIViewController {
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .gray
ConfigureTableView()
}
func ConfigureTableView() {
tableView = UITableView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height), style: .grouped)
view = tableView
tableView.register(UINib(nibName: HoursPickerTableCell.nibName(), bundle: nil), forCellReuseIdentifier: HoursPickerTableCell.reuseIdentifier())
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "DefaultCell")
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if (indexPath.row == 1) {
let hoursPickerCell = tableView.dequeueReusableCell(withIdentifier: HoursPickerTableCell.reuseIdentifier()) as! HoursPickerTableCell
return hoursPickerCell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "DefaultCell")!
cell.textLabel?.text = "test"
return cell
}
}
}
extension ViewController: UITableViewDelegate {
}
HoursPickerTableCell Code:
import UIKit
protocol HoursPickerDelegate: class {
func didChangeHours(date: Date, indexPath: IndexPath)
}
class HoursPickerTableCell: UITableViewCell {
@IBOutlet weak var hoursPicker: UIDatePicker!
var indexPath: IndexPath!
weak var delegate: HoursPickerDelegate?
class func reuseIdentifier() -> String {
return "HoursPickerTableCellIdentifier"
}
class func nibName() -> String {
return "HoursPickerTableCell"
}
class func cellHeight() -> CGFloat {
return 162.0
}
override func awakeFromNib() {
super.awakeFromNib()
initView()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func initView() {
hoursPicker.addTarget(self, action: #selector(hoursDidChange), for: .valueChanged)
}
func updateCell(date: Date, indexPath: IndexPath) {
hoursPicker.setDate(date, animated: true)
self.indexPath = indexPath
}
@objc func hoursDidChange(_ sender: UIDatePicker) {
print("Test")
}
}
App Delegate: (For Now the way to change the language manually is to set the lang to "ar" or "en" depend on which you want.
var currentLanguage = lang
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
lang = "en"
lang = "ar"
currentLanguage = lang
print(lang)
UserDefaults.standard.set(lang, forKey: "AppleLanguage")
if (lang == "en") {
UIView.appearance().semanticContentAttribute = .forceLeftToRight
} else {
UIView.appearance().semanticContentAttribute = .forceRightToLeft
}
Bundle.swizzleLocalization()
// Override point for customization after application launch.
return true
}
extension Bundle {
static func swizzleLocalization() {
let orginalSelector = #selector(localizedString(forKey:value:table:))
guard let orginalMethod = class_getInstanceMethod(self, orginalSelector) else { return }
let mySelector = #selector(myLocaLizedString(forKey:value:table:))
guard let myMethod = class_getInstanceMethod(self, mySelector) else { return }
if class_addMethod(self, orginalSelector, method_getImplementation(myMethod), method_getTypeEncoding(myMethod)) {
class_replaceMethod(self, mySelector, method_getImplementation(orginalMethod), method_getTypeEncoding(orginalMethod))
} else {
method_exchangeImplementations(orginalMethod, myMethod)
}
}
@objc private func myLocaLizedString(forKey key: String,value: String?, table: String?) -> String {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
let bundlePath = Bundle.main.path(forResource: appDelegate.currentLanguage, ofType: "lproj"),
let bundle = Bundle(path: bundlePath) else {
return Bundle.main.myLocaLizedString(forKey: key, value: value, table: table)
}
return bundle.myLocaLizedString(forKey: key, value: value, table: table)
}
}
What I have tried:
1. Changed semantic to Force LeftToRight in the xib file and in initView() Didn't Work.
2. Changed Locale to any Arabic Country in the xib and in initView() Didn't Work.
Help Please!
Thanks!