mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Improve phone number entry
This commit is contained in:
parent
d584c0317d
commit
b901cdfb0d
@ -25,6 +25,7 @@ private func loadCountryCodes() -> [Country] {
|
||||
let endOfLine = "\n"
|
||||
|
||||
var result: [Country] = []
|
||||
var countriesByPrefix: [String: (Country, Country.CountryCode)] = [:]
|
||||
|
||||
var currentLocation = data.startIndex
|
||||
|
||||
@ -46,8 +47,11 @@ private func loadCountryCodes() -> [Country] {
|
||||
let maybeNameRange = data.range(of: endOfLine, options: [], range: idRange.upperBound ..< data.endIndex)
|
||||
|
||||
let countryName = locale.localizedString(forIdentifier: countryId) ?? ""
|
||||
if let countryCodeInt = Int(countryCode) {
|
||||
result.append(Country(code: countryId, name: countryName, localizedName: nil, countryCodes: [Country.CountryCode(code: countryCode, prefixes: [], patterns: [])], hidden: false))
|
||||
if let _ = Int(countryCode) {
|
||||
let code = Country.CountryCode(code: countryCode, prefixes: [], patterns: [])
|
||||
let country = Country(id: countryId, name: countryName, localizedName: nil, countryCodes: [code], hidden: false)
|
||||
result.append(country)
|
||||
countriesByPrefix["\(code.code)"] = (country, code)
|
||||
}
|
||||
|
||||
if let maybeNameRange = maybeNameRange {
|
||||
@ -57,15 +61,35 @@ private func loadCountryCodes() -> [Country] {
|
||||
}
|
||||
}
|
||||
|
||||
countryCodesByPrefix = countriesByPrefix
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private var countryCodes: [Country] = loadCountryCodes()
|
||||
private var countryCodesByPrefix: [String: (Country, Country.CountryCode)] = [:]
|
||||
|
||||
public func loadServerCountryCodes(accountManager: AccountManager, network: Network) {
|
||||
public func loadServerCountryCodes(accountManager: AccountManager, network: Network, completion: @escaping () -> Void) {
|
||||
let _ = (getCountriesList(accountManager: accountManager, network: network, langCode: nil)
|
||||
|> deliverOnMainQueue).start(next: { countries in
|
||||
countryCodes = countries
|
||||
|
||||
var countriesByPrefix: [String: (Country, Country.CountryCode)] = [:]
|
||||
for country in countries {
|
||||
for code in country.countryCodes {
|
||||
if !code.prefixes.isEmpty {
|
||||
for prefix in code.prefixes {
|
||||
countriesByPrefix["\(code.code)\(prefix)"] = (country, code)
|
||||
}
|
||||
} else {
|
||||
countriesByPrefix[code.code] = (country, code)
|
||||
}
|
||||
}
|
||||
}
|
||||
countryCodesByPrefix = countriesByPrefix
|
||||
Queue.mainQueue().async {
|
||||
completion()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -129,9 +153,13 @@ private final class AuthorizationSequenceCountrySelectionNavigationContentNode:
|
||||
}
|
||||
|
||||
public final class AuthorizationSequenceCountrySelectionController: ViewController {
|
||||
static func countries() -> [Country] {
|
||||
return countryCodes
|
||||
}
|
||||
|
||||
public static func lookupCountryNameById(_ id: String, strings: PresentationStrings) -> String? {
|
||||
for country in countryCodes {
|
||||
if id == country.code {
|
||||
for country in self.countries() {
|
||||
if id == country.id {
|
||||
let locale = localeWithStrings(strings)
|
||||
if let countryName = locale.localizedString(forRegionCode: id) {
|
||||
return countryName
|
||||
@ -143,24 +171,72 @@ public final class AuthorizationSequenceCountrySelectionController: ViewControll
|
||||
return nil
|
||||
}
|
||||
|
||||
static func lookupCountryById(_ id: String) -> Country? {
|
||||
return countryCodes.first { $0.id == id }
|
||||
}
|
||||
|
||||
public static func lookupCountryIdByNumber(_ number: String, preferredCountries: [String: String]) -> (Country, Country.CountryCode)? {
|
||||
var results: [(Country, Country.CountryCode)]? = nil
|
||||
if number.count == 1, let preferredCountryId = preferredCountries[number], let country = lookupCountryById(preferredCountryId), let code = country.countryCodes.first {
|
||||
return (country, code)
|
||||
}
|
||||
|
||||
for i in 0..<number.count {
|
||||
let prefix = String(number.prefix(number.count - i))
|
||||
if let country = countryCodesByPrefix[prefix] {
|
||||
if var currentResults = results {
|
||||
if let result = currentResults.first, result.1.code.count > country.1.code.count {
|
||||
break
|
||||
} else {
|
||||
currentResults.append(country)
|
||||
}
|
||||
} else {
|
||||
results = [country]
|
||||
}
|
||||
}
|
||||
}
|
||||
if let results = results {
|
||||
if !preferredCountries.isEmpty, let (_, code) = results.first {
|
||||
if let preferredCountry = preferredCountries[code.code] {
|
||||
for (country, code) in results {
|
||||
if country.id == preferredCountry {
|
||||
return (country, code)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return results.first
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public static func lookupCountryIdByCode(_ code: Int) -> String? {
|
||||
for country in countryCodes {
|
||||
for country in self.countries() {
|
||||
for countryCode in country.countryCodes {
|
||||
if countryCode.code == "\(code)" {
|
||||
return country.code
|
||||
return country.id
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public static func lookupPatternByCode(_ code: Int) -> String? {
|
||||
for country in countryCodes {
|
||||
for countryCode in country.countryCodes {
|
||||
if countryCode.code == "\(code)" {
|
||||
return countryCode.patterns.first
|
||||
public static func lookupPatternByNumber(_ number: String, preferredCountries: [String: String]) -> String? {
|
||||
if let (_, code) = lookupCountryIdByNumber(number, preferredCountries: preferredCountries), !code.patterns.isEmpty {
|
||||
var prefixes: [String: String] = [:]
|
||||
for pattern in code.patterns {
|
||||
let cleanPattern = pattern.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: "X", with: "")
|
||||
let cleanPrefix = "\(code.code)\(cleanPattern)"
|
||||
prefixes[cleanPrefix] = pattern
|
||||
}
|
||||
for i in 0..<number.count {
|
||||
let prefix = String(number.prefix(number.count - i))
|
||||
if let pattern = prefixes[prefix] {
|
||||
return pattern
|
||||
}
|
||||
}
|
||||
return code.patterns.first
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -57,12 +57,15 @@ private func loadCountryCodes() -> [(String, Int)] {
|
||||
|
||||
private let countryCodes: [(String, Int)] = loadCountryCodes()
|
||||
|
||||
func localizedContryNamesAndCodes(strings: PresentationStrings) -> [((String, String), String, Int)] {
|
||||
func localizedCountryNamesAndCodes(strings: PresentationStrings) -> [((String, String), String, Int)] {
|
||||
let locale = localeWithStrings(strings)
|
||||
var result: [((String, String), String, Int)] = []
|
||||
for (id, code) in countryCodes {
|
||||
if let englishCountryName = usEnglishLocale.localizedString(forRegionCode: id), let countryName = locale.localizedString(forRegionCode: id) {
|
||||
result.append(((englishCountryName, countryName), id, code))
|
||||
for country in AuthorizationSequenceCountrySelectionController.countries() {
|
||||
if country.hidden {
|
||||
continue
|
||||
}
|
||||
if let englishCountryName = usEnglishLocale.localizedString(forRegionCode: country.id), let countryName = locale.localizedString(forRegionCode: country.id), let codeValue = country.countryCodes.first?.code, let code = Int(codeValue) {
|
||||
result.append(((englishCountryName, countryName), country.id, code))
|
||||
} else {
|
||||
assertionFailure()
|
||||
}
|
||||
@ -103,7 +106,7 @@ final class AuthorizationSequenceCountrySelectionControllerNode: ASDisplayNode,
|
||||
self.searchTableView.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
|
||||
let countryNamesAndCodes = localizedContryNamesAndCodes(strings: strings)
|
||||
let countryNamesAndCodes = localizedCountryNamesAndCodes(strings: strings)
|
||||
|
||||
var sections: [(String, [((String, String), String, Int)])] = []
|
||||
for (names, id, code) in countryNamesAndCodes.sorted(by: { lhs, rhs in
|
||||
@ -116,8 +119,7 @@ final class AuthorizationSequenceCountrySelectionControllerNode: ASDisplayNode,
|
||||
sections[sections.count - 1].1.append((names, id, code))
|
||||
}
|
||||
self.sections = sections
|
||||
var sectionTitles = sections.map { $0.0 }
|
||||
self.sectionTitles = sectionTitles
|
||||
self.sectionTitles = sections.map { $0.0 }
|
||||
|
||||
super.init()
|
||||
|
||||
|
@ -78,6 +78,7 @@ private func cleanSuffix(_ text: String) -> String {
|
||||
|
||||
extension String {
|
||||
func applyPatternOnNumbers(pattern: String, replacementCharacter: Character) -> String {
|
||||
let pattern = pattern.replacingOccurrences( of: "[0-9]", with: "X", options: .regularExpression)
|
||||
var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
|
||||
for index in 0 ..< pattern.count {
|
||||
guard index < pureNumber.count else { return pureNumber }
|
||||
@ -175,8 +176,12 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||
private func updatePlaceholder() {
|
||||
if let mask = self.mask {
|
||||
let mutableMask = NSMutableAttributedString(attributedString: mask)
|
||||
mutableMask.replaceCharacters(in: NSRange(location: 0, length: mask.string.count), with: mask.string.replacingOccurrences(of: "X", with: "-"))
|
||||
mutableMask.replaceCharacters(in: NSRange(location: 0, length: mask.string.count), with: mask.string.replacingOccurrences(of: "X", with: "–"))
|
||||
if let text = self.numberField.textField.text {
|
||||
mutableMask.replaceCharacters(in: NSRange(location: 0, length: min(text.count, mask.string.count)), with: text)
|
||||
}
|
||||
mutableMask.addAttribute(.foregroundColor, value: UIColor.clear, range: NSRange(location: 0, length: min(self.numberField.textField.text?.count ?? 0, mask.string.count)))
|
||||
mutableMask.addAttribute(.kern, value: 1.6, range: NSRange(location: 0, length: mask.string.count))
|
||||
self.placeholderNode.attributedText = mutableMask
|
||||
} else {
|
||||
self.placeholderNode.attributedText = NSAttributedString(string: "")
|
||||
@ -212,7 +217,7 @@ public final class PhoneInputNode: ASDisplayNode, UITextFieldDelegate {
|
||||
} else {
|
||||
self.numberField.textField.keyboardType = .numberPad
|
||||
}
|
||||
self.numberField.textField.defaultTextAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.kern: 2.0]
|
||||
self.numberField.textField.defaultTextAttributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.kern: 1.6]
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.countryCodeField)
|
||||
|
@ -165,6 +165,7 @@ private var declaredEncodables: Void = {
|
||||
declareEncodable(TelegramMediaImage.VideoRepresentation.self, f: { TelegramMediaImage.VideoRepresentation(decoder: $0) })
|
||||
declareEncodable(Country.self, f: { Country(decoder: $0) })
|
||||
declareEncodable(Country.CountryCode.self, f: { Country.CountryCode(decoder: $0) })
|
||||
declareEncodable(CountriesList.self, f: { CountriesList(decoder: $0) })
|
||||
|
||||
return
|
||||
}()
|
||||
|
@ -7,7 +7,7 @@ import SyncCore
|
||||
|
||||
public struct Country: PostboxCoding, Equatable {
|
||||
public static func == (lhs: Country, rhs: Country) -> Bool {
|
||||
return lhs.code == rhs.code && lhs.name == rhs.name && lhs.localizedName == rhs.localizedName && lhs.countryCodes == rhs.countryCodes && lhs.hidden == rhs.hidden
|
||||
return lhs.id == rhs.id && lhs.name == rhs.name && lhs.localizedName == rhs.localizedName && lhs.countryCodes == rhs.countryCodes && lhs.hidden == rhs.hidden
|
||||
}
|
||||
|
||||
public struct CountryCode: PostboxCoding, Equatable {
|
||||
@ -34,14 +34,14 @@ public struct Country: PostboxCoding, Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
public let code: String
|
||||
public let id: String
|
||||
public let name: String
|
||||
public let localizedName: String?
|
||||
public let countryCodes: [CountryCode]
|
||||
public let hidden: Bool
|
||||
|
||||
public init(code: String, name: String, localizedName: String?, countryCodes: [CountryCode], hidden: Bool) {
|
||||
self.code = code
|
||||
public init(id: String, name: String, localizedName: String?, countryCodes: [CountryCode], hidden: Bool) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.localizedName = localizedName
|
||||
self.countryCodes = countryCodes
|
||||
@ -49,7 +49,7 @@ public struct Country: PostboxCoding, Equatable {
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.code = decoder.decodeStringForKey("c", orElse: "")
|
||||
self.id = decoder.decodeStringForKey("c", orElse: "")
|
||||
self.name = decoder.decodeStringForKey("n", orElse: "")
|
||||
self.localizedName = decoder.decodeOptionalStringForKey("ln")
|
||||
self.countryCodes = decoder.decodeObjectArrayForKey("cc").map { $0 as! CountryCode }
|
||||
@ -57,7 +57,7 @@ public struct Country: PostboxCoding, Equatable {
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
encoder.encodeString(self.code, forKey: "c")
|
||||
encoder.encodeString(self.id, forKey: "c")
|
||||
encoder.encodeString(self.name, forKey: "n")
|
||||
if let localizedName = self.localizedName {
|
||||
encoder.encodeString(localizedName, forKey: "ln")
|
||||
@ -130,6 +130,7 @@ public func getCountriesList(accountManager: AccountManager, network: Network, l
|
||||
return fetch(nil, nil)
|
||||
} else {
|
||||
return accountManager.sharedData(keys: [SharedDataKeys.countriesList])
|
||||
|> take(1)
|
||||
|> map { sharedData -> ([Country], Int32) in
|
||||
if let countriesList = sharedData.entries[SharedDataKeys.countriesList] as? CountriesList {
|
||||
return (countriesList.countries, countriesList.hash)
|
||||
@ -158,7 +159,7 @@ extension Country {
|
||||
init(apiCountry: Api.help.Country) {
|
||||
switch apiCountry {
|
||||
case let .country(flags, iso2, defaultName, name, countryCodes):
|
||||
self.init(code: iso2, name: defaultName, localizedName: name, countryCodes: countryCodes.map { Country.CountryCode(apiCountryCode: $0) }, hidden: (flags & 1 << 0) != 0)
|
||||
self.init(id: iso2, name: defaultName, localizedName: name, countryCodes: countryCodes.map { Country.CountryCode(apiCountryCode: $0) }, hidden: (flags & 1 << 0) != 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,8 +58,6 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
||||
self.openUrl = openUrl
|
||||
self.back = back
|
||||
|
||||
loadServerCountryCodes(accountManager: sharedContext.accountManager, network: account.network)
|
||||
|
||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(theme: AuthorizationSequenceController.navigationBarTheme(presentationData.theme), strings: NavigationBarStrings(presentationStrings: presentationData.strings)))
|
||||
|
||||
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
|
||||
@ -140,6 +138,12 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
||||
self.controllerNode.checkPhone = { [weak self] in
|
||||
self?.nextPressed()
|
||||
}
|
||||
|
||||
loadServerCountryCodes(accountManager: sharedContext.accountManager, network: account.network, completion: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerNode.updateCountryCode()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@ -185,7 +189,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
||||
self.loginWithNumber?(self.controllerNode.currentNumber, self.controllerNode.syncContacts)
|
||||
}
|
||||
} else {
|
||||
hapticFeedback.error()
|
||||
self.hapticFeedback.error()
|
||||
self.controllerNode.animateError()
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
var selectCountryCode: (() -> Void)?
|
||||
var checkPhone: (() -> Void)?
|
||||
|
||||
var preferredCountryIdForCode: [String: String] = [:]
|
||||
|
||||
init(strings: PresentationStrings, theme: PresentationTheme) {
|
||||
self.strings = strings
|
||||
|
||||
@ -124,29 +126,71 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
||||
self.countryButton.contentEdgeInsets = UIEdgeInsets(top: 0.0, left: 15.0, bottom: 10.0, right: 0.0)
|
||||
self.countryButton.contentHorizontalAlignment = .left
|
||||
|
||||
// self.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
|
||||
self.countryButton.addTarget(self, action: #selector(self.countryPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.phoneInputNode.countryCodeUpdated = { [weak self] code, name in
|
||||
let font = Font.with(size: 20.0, design: .monospace, traits: [])
|
||||
func removePlus(_ text: String?) -> String {
|
||||
var result = ""
|
||||
if let text = text {
|
||||
for c in text {
|
||||
if c != "+" {
|
||||
result += String(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
let processNumberChange: (String) -> Bool = { [weak self] number in
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
let number = removePlus(number)
|
||||
if let (country, _) = AuthorizationSequenceCountrySelectionController.lookupCountryIdByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode) {
|
||||
let flagString = emojiFlagForISOCountryCode(country.id as NSString)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(country.id, strings: strongSelf.strings) ?? country.name
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
let maskFont = Font.with(size: 20.0, design: .regular, traits: [.monospacedNumbers])
|
||||
if let mask = AuthorizationSequenceCountrySelectionController.lookupPatternByNumber(number, preferredCountries: strongSelf.preferredCountryIdForCode).flatMap({ NSAttributedString(string: $0, font: maskFont, textColor: theme.list.itemPlaceholderTextColor) }) {
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = nil
|
||||
strongSelf.phoneInputNode.mask = mask
|
||||
} else {
|
||||
strongSelf.phoneInputNode.mask = nil
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.numberTextUpdated = { [weak self] number in
|
||||
if let strongSelf = self {
|
||||
if let code = Int(code), let name = name, let countryName = countryCodeAndIdToName[CountryCodeAndId(code: code, id: name)] {
|
||||
let _ = processNumberChange(strongSelf.phoneInputNode.number)
|
||||
}
|
||||
}
|
||||
|
||||
self.phoneInputNode.countryCodeUpdated = { [weak self] code, name in
|
||||
if let strongSelf = self {
|
||||
if let name = name {
|
||||
strongSelf.preferredCountryIdForCode[code] = name
|
||||
}
|
||||
|
||||
if processNumberChange(strongSelf.phoneInputNode.number) {
|
||||
} else if let code = Int(code), let name = name, let countryName = countryCodeAndIdToName[CountryCodeAndId(code: code, id: name)] {
|
||||
let flagString = emojiFlagForISOCountryCode(name as NSString)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(name, strings: strongSelf.strings) ?? countryName
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
strongSelf.phoneInputNode.mask = AuthorizationSequenceCountrySelectionController.lookupPatternByCode(code).flatMap { NSAttributedString(string: $0, font: font, textColor: theme.list.itemPlaceholderTextColor) }
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
} else if let code = Int(code), let (countryId, countryName) = countryCodeToIdAndName[code] {
|
||||
let flagString = emojiFlagForISOCountryCode(countryId as NSString)
|
||||
let localizedName: String = AuthorizationSequenceCountrySelectionController.lookupCountryNameById(countryId, strings: strongSelf.strings) ?? countryName
|
||||
strongSelf.countryButton.setTitle("\(flagString) \(localizedName)", with: Font.regular(20.0), with: theme.list.itemPrimaryTextColor, for: [])
|
||||
|
||||
strongSelf.phoneInputNode.mask = AuthorizationSequenceCountrySelectionController.lookupPatternByCode(code).flatMap { NSAttributedString(string: $0, font: font, textColor: theme.list.itemPlaceholderTextColor) }
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
} else {
|
||||
strongSelf.countryButton.setTitle(strings.Login_SelectCountry_Title, with: Font.regular(20.0), with: theme.list.itemPlaceholderTextColor, for: [])
|
||||
|
||||
strongSelf.phoneInputNode.mask = nil
|
||||
strongSelf.phoneInputNode.numberField.textField.attributedPlaceholder = NSAttributedString(string: strings.Login_PhonePlaceholder, font: Font.regular(20.0), textColor: theme.list.itemPlaceholderTextColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -322,6 +366,10 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||
self.tokenEventsDisposable.dispose()
|
||||
}
|
||||
|
||||
func updateCountryCode() {
|
||||
self.phoneAndCountryNode.phoneInputNode.codeAndNumber = self.codeAndNumber
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user