How to detect the country code and change flag in FPNTextField - ios

I am using FlagPhoneno Pod to search or select country codes with flags, by using below codes. But when comes to edit part I get full phone no to the FPNtextFeild ex- +971568573570 and by default i set country code as .AE
I want to detect and automatically change the country flag when any other country phone no fetch from json let recivedPhoneNo = self.json["phone_number"].string ?? ""
For the moment the flag is changing when select only. please show me an example method with code from same pod "FlagPhoneno" module.
I am using following code.
func setupPhoneTF(){
self.phoneTFView.layer.borderColor = UIColor.appColor.customGray.cgColor
self.phoneTFView.layer.cornerRadius = 5
self.phoneTFView.layer.borderWidth = 1
phoneTF.displayMode = .list // .picker by default
listController.setup(repository: phoneTF.countryRepository)
listController.didSelect = { [weak self] country in
self?.phoneTF.setFlag(countryCode: country.code)
}
phoneTF.delegate = self
phoneTF.font = UIFont.systemFont(ofSize: 14)
// Custom the size/edgeInsets of the flag button
phoneTF.flagButtonSize = CGSize(width: 35, height: 35)
phoneTF.flagButton.imageEdgeInsets = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
let items = [
UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.save, target: self, action: nil),
UIBarButtonItem(title: "Item 1", style: .plain, target: self, action: nil),
UIBarButtonItem(title: "Item 2", style: .plain, target: self, action: nil)
]
phoneTF.textFieldInputAccessoryView = getCustomTextFieldInputAccessoryView(with: items)
phoneTF.hasPhoneNumberExample = true
phoneTF.placeholder = "Phone Number"
phoneTF.setFlag(countryCode: .AE)
}
extension AddNewAddressVC: FPNTextFieldDelegate {
func fpnDidValidatePhoneNumber(textField: FPNTextField, isValid: Bool) {
textField.rightViewMode = .whileEditing
textField.rightView = UIImageView(image: isValid ? imageLiteral(resourceName: "success") : imageLiteral(resourceName: "error"))
print(
isValid,
textField.getFormattedPhoneNumber(format: .E164) ?? "E164: nil",
textField.getFormattedPhoneNumber(format: .International) ?? "International: nil",
textField.getFormattedPhoneNumber(format: .National) ?? "National: nil",
textField.getFormattedPhoneNumber(format: .RFC3966) ?? "RFC3966: nil",
textField.getRawPhoneNumber() ?? "Raw: nil"
)
}
func fpnDidSelectCountry(name: String, dialCode: String, code: String) {
print(name, dialCode, code)
self.selectedDialCod = dialCode
}
func fpnDisplayCountryList() {
let navigationViewController = UINavigationController(rootViewController: listController)
listController.title = "Countries"
listController.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(dismissCountries))
self.present(navigationViewController, animated: true, completion: nil)
}
}

// You can change the chosen flag then set the phone number
phoneNumberTextField.setFlag(for: .FR)
phoneNumberTextField.set(phoneNumber: "0600000001")
// Or directly set the phone number with country code, which will update automatically the flag image
phoneNumberTextField.set(phoneNumber: "+33600000001")

FlagPhoneNumber pod have an issue by which flag get disappear after upload and if you reinstall the ipa from testflight the flag will be gone.

Related

largeTitleTextAttributes disappear after programmatic push - Swift

I'm pushing to a navigation controller and the large title I have set within the shootSummary VC text attributes change without warning -- they lose their original formatting. So I've tried putting them as I've done here after the push, but that hasn't worked either. Here's my code:
guard let shootSummaryVC = storyboard?.instantiateViewController(withIdentifier: "ShootPVC") as? ShootPVC else { return }
guard let indexPath = tableView.indexPathForSelectedRow else { return }
guard let shootID = shoots?[indexPath.row].id else { return }
shootSummaryVC.id = shootID
shootSummaryVC.initialPage = 3
DispatchQueue.main.async { [self] in
navigationController?.pushViewController(shootSummaryVC, animated: true)
navigationController?.hidesNavigationBarHairline = true
navigationController?.navigationBar.topItem?.backBarButtonItem =
UIBarButtonItem(title: "Track Payments", style: .plain, target: nil, action: nil)
let p = NSMutableParagraphStyle()
p.firstLineHeadIndent = 10
navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.font: currentTheme.titleFontLarge, NSAttributedString.Key.foregroundColor: currentTheme.navigationBarTextColor, NSAttributedString.Key.paragraphStyle: p]
}
The largeTitleTextAttributes in my attempted solution above don't affect the title. I tried setting them within the VC being pushed to (shootSummaryVC) but that hasn't worked either. Any ideas?

id Identifier swift

I have these lines of code in which if I stop on the X to delete an image I delete it. The problem is that if I have one or more of the same type of image, removing one of them, it also erases all the other identical ones. I think my problem is in calling the "forEach". What should I use?
While if the images are different, I delete correctly the single "sticker".
guard let id = gestureRecognizer.stringIdentifier else {return}
stickerArray.forEach { (sticker) in
if id == sticker.stickerIdentifier {
STKProbes.deleteSticker.send(from: nil, info: sticker.stickerIdentifier)
sticker.removeFromSuperview()
sticker.image = nil
if let index = stickerArray.index(of: sticker) {
stickerArray.remove(at: index)
}
}
}
func appendSticker(model: CoreSceneViewModel.AddSticker.ViewModel) {
let sticker = StickerView(frame: PlacementManager.categoryPlacement(forCategory: model.category, over: self.managedView.workbenchView), name: model.name)
self.managedView.controlsView.alpha = 0
self.managedView.closeButton.alpha = 0
self.stickerArray.append(sticker)
STKProbes.tapSticker.send(from: nil, info: sticker.stickerIdentifier)
sticker.image = model.sticker
sticker.contentMode = .scaleAspectFit
if kFreezeOldStickers {
for view in self.managedView.workbenchView.subviews {
if let grs = view.gestureRecognizers {
for gr in grs {
view.removeGestureRecognizer(gr)
}
}
}
}
draggingGesture = UIPanGestureRecognizer(target: self, action: #selector(dragging(gestureRecognizer:)))
sticker.addGestureRecognizer(draggingGesture)
pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinched(gestureRecognizer:)))
sticker.addGestureRecognizer(pinchGesture)
rotationGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotated(gestureRecognizer:)))
sticker.addGestureRecognizer(rotationGesture)
tapGestureAlpha = UITapGestureRecognizer(target: self, action: #selector(setAlpha0(gestureRecognizer:)))
self.managedView.workbenchView.addGestureRecognizer(tapGestureAlpha)
tapGesture = TapGesture(target: self, action: #selector(tapped(gestureRecognizer:)))
tapGesture.idIdentifier = sticker.stickerIdentifier
sticker.addGestureRecognizer(tapGesture)
dTapGesture = DeleteTapGesture(target: self, action: #selector(cancelTapped(gestureRecognizer:)))
dTapGesture.stringIdentifier = sticker.stickerIdentifier
sticker.xButton.addGestureRecognizer(dTapGesture)
sticker.xButton.isUserInteractionEnabled = true
sticker.isUserInteractionEnabled = true
sticker.layer.zPosition = 0
draggingGesture.delegate = self
self.managedView.workbenchView.addSubview(sticker)
You can try
stickerArray.forEach {
if $0.xButton == gestureRecognizer.view {
$0.removeFromSuperview()
}
}
you may have similar stringIdentifier for items

View is not displayed

I have an alert box that takes user input and starts a download task. After the user clicks "Ok," I want the screen to show a UIView that I added an ActivityIndicator to while the download occurs. The download occurs successfully and the function correctly opens up the next controller, however, the custom view nor activity indicator are ever displayed. Here's my code:
private func getKeyFromAlert() {
let alert = UIAlertController(title: "Enter Key", message: "Enter your text key below. If you want to scan it instead, click \"Scan Key.\" ", preferredStyle: .alert)
alert.addTextField { (textField) in
let attribString = NSAttributedString(string: "Enter your app code here")
textField.attributedPlaceholder = attribString
}
let scanAction = UIAlertAction(title: "Scan Key", style: .default) { _ in
self.openSettingsForApp()
}
let okAction = UIAlertAction(title: "OK", style: .default) { _ in
let textField = alert.textFields![0]
if let text = textField.text {
let encoded = text.toBase64()
let status = APIKeychain.storeToken(encoded)
if !status {
self.displayAlertForBadKeychain(useCamera: false)
} else {
self.addLoader()
self.dismissSetup()
}
} else {
let _ = APIKeychain.storeToken("")
self.addLoader()
self.dismissSetup()
}
}
alert.addAction(scanAction)
alert.addAction(okAction)
show(alert, sender: nil)
}
The function in question that I use to display the UIView is addLoader()
The code for addLoader is:
private func addLoader() {
let frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height)
let loaderView = UIView(frame: frame)
loaderView.alpha = 1.0
loaderView.backgroundColor = UIColor.white
let activitySpinner: UIActivityIndicatorView = UIActivityIndicatorView(frame: loaderView.frame)
activitySpinner.center = loaderView.center
activitySpinner.hidesWhenStopped = false
activitySpinner.style = .whiteLarge
activitySpinner.startAnimating()
loaderView.addSubview(activitySpinner)
self.view.addSubview(loaderView)
self.view.layoutIfNeeded()
}
I've tried several iterations of setNeedsDisplay and setNeedsLayout without luck. I've also tried explicitly declaring this in a DispatchQueue.main.async without any affect as well.
EDIT
I added the code below for dismissSetup()
private func dismissSetup() {
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
DispatchQueue.global(qos: .background).async {
if self.updateDatabase {
//This will start the download process
let _ = WebDataFetcher(dataStack: self.dataStack)
}
dispatchGroup.leave()
}
dispatchGroup.wait()
let mainSB = UIStoryboard(name: "UserInputs", bundle: nil)
let mainVC = mainSB.instantiateViewController(withIdentifier: "userInputs")
appDelegate.window?.rootViewController = mainVC
}

Swift: Not Return to English Version after translate to Arabic

i want to localize my apps between English and Arabic version included RTL. but it not return to English Version with left to right after translate to Arabic, it just repeats to Arabic version when i click navigation item UIButton, also navigation item flag not show properly it is just repeating Arabic flag.
// here is my code
import UIKit
import Foundation
// homeCollectionViewController
class HomeCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout{
let navLanguageBtn = UIButton()
static var language = ""
override func viewDidLoad() {
super.viewDidLoad()
setupHomeNavBarBtn()
}
// NavigationBar
func setupHomeNavBarBtn() {
navLanguageBtn.frame = CGRect(x: 0, y: 0, width: CollectionViewSize.width / 15, height: CollectionViewSize.width / 15)
navLanguageBtn.contentEdgeInsets = UIEdgeInsetsMake(0, 0, CollectionViewSize.width / 60, 0)
navLanguageBtn.setImage(UIImage(named: "arab_flag")?.withRenderingMode(.alwaysOriginal), for: .normal)
navLanguageBtn.contentMode = .scaleAspectFit
navLanguageBtn.addTarget(self, action: #selector(navLanguageBtnClick), for: .touchUpInside)
let navLanguageBtnItem = UIBarButtonItem(customView: navLanguageBtn)
self.navigationItem.setRightBarButtonItems([ navLanguageBtnItem], animated: true)
}
// ButtonClick
public func navLanguageBtnClick(){
if (navLanguageBtn.isSelected == true)
{
print("language btn click true English flag")
navLanguageBtn.setImage(UIImage(named: "english_flag")?.withRenderingMode(.alwaysOriginal), for: UIControlState.normal)
UIView.appearance().semanticContentAttribute = .forceRightToLeft
navLanguageBtn.isSelected = false
let path = Bundle.main.path(forResource: "ar-SA", ofType: "lproj")
let bundal = Bundle.init(path: path!)! as Bundle
HomeCollectionViewController.language = "ar"
navigationItem.title = bundal.localizedString(forKey: "home", value: nil, table: nil)
SecondHomeCell.newProductTrans = bundal.localizedString(forKey: "newProduct", value: nil, table: nil)
SecondHomeCell.populerStoriesTrans = bundal.localizedString(forKey: "populerStories", value: nil, table: nil)
let navController: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController as? UINavigationController)
let layout = UICollectionViewFlowLayout()
let control = HomeCollectionViewController(collectionViewLayout: layout)
navController?.pushViewController(control, animated: true)
let AR_POST_PARAMETERS = ["language": HomeCollectionViewController.language]
self.secondHomeCell?.secondHomeCellDataLoad(POST_PARAMETERS: AR_POST_PARAMETERS as! Dictionary<String, String>)
}
else
{
print("language btn click true arabic flag")
navLanguageBtn.setImage(UIImage(named: "arab_flag")?.withRenderingMode(.alwaysOriginal), for: UIControlState.selected)
UIView.appearance().semanticContentAttribute = .forceLeftToRight
// UIView.appearance().transform = CGAffineTransform(scaleX: 1.0, y: -1.0)
navLanguageBtn.isSelected = true
// self.lblCountryName.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
let path = Bundle.main.path(forResource: "en", ofType: "lproj")
let bundal = Bundle.init(path: path!)! as Bundle
//home
HomeCollectionViewController.language = "en"
navigationItem.title = bundal.localizedString(forKey: "home", value: nil, table: nil)
SecondHomeCell.newProductTrans = bundal.localizedString(forKey: "newProduct", value: nil, table: nil)
SecondHomeCell.populerStoriesTrans = bundal.localizedString(forKey: "populerStories", value: nil, table: nil)
let navController: UINavigationController? = (UIApplication.shared.keyWindow?.rootViewController as? UINavigationController)
let layout = UICollectionViewFlowLayout()
let control = HomeCollectionViewController(collectionViewLayout: layout)
navController?.pushViewController(control, animated: true)
let AR_POST_PARAMETERS = ["language": HomeCollectionViewController.language]
self.secondHomeCell?.secondHomeCellDataLoad(POST_PARAMETERS: AR_POST_PARAMETERS as! Dictionary<String, String>)
}
}
}
For changing the language of application, from a button click within the appliaction, i suggest you to ask the user to relaunch the application, for the change to happen.
In my application, i am changing the language like this.
//On Button click:
if applicationLanguage() == "ar" {
setApplicationLanguage(languageCode: "en-US")
}
else if applicationLanguage() == "en" {
setApplicationLanguage(languageCode: "ar")
}
func applicationLanguage() -> String
{
let languages : NSArray = UserDefaults.standard.object(forKey: "AppleLanguages") as! NSArray
let selectedLanguage : String = languages[0] as! String
return selectedLanguage.components(separatedBy: "-").first!
}
func setApplicationLanguage(languageCode : String)
{
// Show Alert to restart the application. Present it in your view controller.
UserDefaults.standard.set([languageCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
}
The user should manually quit the application, for the change to happen.

Material TextField previous next button

I am trying to get the previous/next arrow button on top of the keyboard when ever a textField is selected.
I have tried the following
textField0.tag = 0 // textField0 : TextField
textField0.addPreviousNextRightOnKeyboardWithTarget(self, rightButtonTitle: "Submit", previousAction: #selector(previousTextField(sender:)), nextAction: #selector(nextTextField(sender:)), rightButtonAction: #selector(saveNewPlan), titleText: nil)
textField1.tag = 1
textField1.addPreviousNextRightOnKeyboardWithTarget(self, rightButtonTitle: "Submit", previousAction: #selector(previousTextField(sender:)), nextAction: #selector(nextTextField(sender:)), rightButtonAction: #selector(saveNewPlan), titleText: nil)
The previous/next action selector defined as such.
func previousTextField(sender: AnyObject){
// I actually get the sender as IQBarButtonItem (subclass of UIBarButtonItem) instead of UITextField here
if let previousField = textField.superview?.viewWithTag(textField.tag - 1) as? UITextField {
_ = previousField.becomeFirstResponder()
}
}
func nextTextField(sender: AnyObject){
if let nextField = textField.superview?.viewWithTag(textField.tag + 1) as? UITextField {
_ = nextField.becomeFirstResponder()
}
}
It's throwing this error whenever I click on the button.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[IQKeyboardManagerSwift.IQBarButtonItem superview]: unrecognized selector sent to instance 0x7fc3775658e0'
Here's what the method do.
public func addPreviousNextRightOnKeyboardWithTarget( _ target : AnyObject?, rightButtonTitle : String, previousAction : Selector, nextAction : Selector, rightButtonAction : Selector, titleText : String?) {
//If can't set InputAccessoryView. Then return
if self.responds(to: #selector(setter: UITextField.inputAccessoryView)) {
// Creating a toolBar for phoneNumber keyboard
let toolbar = IQToolbar()
toolbar.doneTitle = rightButtonTitle
var items : [UIBarButtonItem] = []
let prev : IQBarButtonItem
let next : IQBarButtonItem
// Get the top level "bundle" which may actually be the framework
var bundle = Bundle(for: IQKeyboardManager.self)
if let resourcePath = bundle.path(forResource: "IQKeyboardManager", ofType: "bundle") {
if let resourcesBundle = Bundle(path: resourcePath) {
bundle = resourcesBundle
}
}
var imageLeftArrow : UIImage!
var imageRightArrow : UIImage!
if #available(iOS 10.0, *) {
imageLeftArrow = UIImage(named: "IQButtonBarArrowUp", in: bundle, compatibleWith: nil)
imageRightArrow = UIImage(named: "IQButtonBarArrowDown", in: bundle, compatibleWith: nil)
} else {
imageLeftArrow = UIImage(named: "IQButtonBarArrowLeft", in: bundle, compatibleWith: nil)
imageRightArrow = UIImage(named: "IQButtonBarArrowRight", in: bundle, compatibleWith: nil)
}
//Support for RTL languages like Arabic, Persia etc... (Bug ID: #448)
if #available(iOS 9.0, *) {
imageLeftArrow = imageLeftArrow?.imageFlippedForRightToLeftLayoutDirection()
imageRightArrow = imageRightArrow?.imageFlippedForRightToLeftLayoutDirection()
}
prev = IQBarButtonItem(image: imageLeftArrow, style: UIBarButtonItemStyle.plain, target: target, action: previousAction)
prev.accessibilityLabel = "Toolbar Previous Button"
next = IQBarButtonItem(image: imageRightArrow, style: UIBarButtonItemStyle.plain, target: target, action: nextAction)
next.accessibilityLabel = "Toolbar Next Button"
//Previous button
items.append(prev)
//Fixed space
let fixed = IQBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.fixedSpace, target: nil, action: nil)
if #available(iOS 10.0, *) {
fixed.width = 6
} else {
fixed.width = 20
}
items.append(fixed)
//Next button
items.append(next)
//Flexible space
items.append(UIView.flexibleBarButtonItem())
//Title button
let title = IQTitleBarButtonItem(title: shouldHidePlaceholderText == true ? nil : titleText)
items.append(title)
//Flexible space
items.append(UIView.flexibleBarButtonItem())
//Right button
let doneButton = IQBarButtonItem(title: rightButtonTitle, style: UIBarButtonItemStyle.done, target: target, action: rightButtonAction)
items.append(doneButton)
// Adding button to toolBar.
toolbar.items = items
toolbar.toolbarTitleInvocation = self.titleInvocation
// Setting toolbar to keyboard.
if let textField = self as? UITextField {
textField.inputAccessoryView = toolbar
switch textField.keyboardAppearance {
case UIKeyboardAppearance.dark:
toolbar.barStyle = UIBarStyle.black
default:
toolbar.barStyle = UIBarStyle.default
}
} else if let textView = self as? UITextView {
textView.inputAccessoryView = toolbar
switch textView.keyboardAppearance {
case UIKeyboardAppearance.dark:
toolbar.barStyle = UIBarStyle.black
default:
toolbar.barStyle = UIBarStyle.default
}
}
}
}

Resources