Swift.国家/地区区号选择器

效果图

实现功能:

  • 中英文双语,根据系统语言获取不同源内容,以及不同的提示语言。

  • 通过闭包回调,点击后将选中国家和区号以不同字段回调。

  • 带有SearchBar,实现即时搜索功能。

实现方式:

  1. 获取数据源plist文件,英语/中文各一个文件。并将文件中的数据以array/dictionary的形式存储.

  2. 新建viewController,添加tableView将数据展示.

  3. 新建UISearchController,并实现UISearchResultsUpdating代理方法。

  4. 实现点击cell方法,实现闭包回调。

  5. 获取系统语言,实现中英文自动匹配。


1.获取数据源plist文件,英语/中文各一个文件。并将文件中的数据以array/dictionary的形式存储.

    /// 从plist文件中获取数据并存储
        let sortedName = isLanguageEnglish() ? "sortedNameEN" : "sortedNameCH"
        let path = Bundle.main.path(forResource: sortedName, ofType: "plist")
        sortedNameDict = NSDictionary(contentsOfFile: path ?? "") as? Dictionary
        indexArray = Array(sortedNameDict!.keys).sorted(by: {$0 < $1})

2.新建viewController,添加tableView,实现tableView代理方法,将数据展示.

extension EWCountryCodeViewController:UITableViewDelegate,UITableViewDataSource{
    func numberOfSections(in tableView: UITableView) -> Int {
        if (searchController!.isActive) {
            return 1;
        } else {
            return sortedNameDict?.keys.count ?? 0
        }
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController!.isActive {
            return results.count
        }else {
            if indexArray!.count > section{
                let array: Array = sortedNameDict?[indexArray![section]] as! Array
                return array.count
            }
        }
        return 0
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "identifier") else {
            return UITableViewCell()
        }
        cell.textLabel?.font = UIFont.systemFont(ofSize: 16.0)
        cell.selectionStyle = .none
        cell.textLabel?.text = self.showCodeStringIndex(indexPath: indexPath as NSIndexPath)
        return cell
    }
    func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return indexArray
    }
    func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
        return index
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return searchController!.isActive ? 0 : 30
    }
    /// 右侧的筛选sectionTitle
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        if ((indexArray?.count) != nil) && indexArray!.count > section {
            return indexArray?[section]
        }
        return nil
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.selectCodeIndex(indexPath: indexPath)
    }
}

3.新建UISearchController,并实现UISearchResultsUpdating代理方法。并修改tableView代理方法,使其能够显示searchController的搜索结果

        /// 当searchResultsController为nil则意味着搜索结果使用原tableView展示
        searchController = UISearchController(searchResultsController: nil)
        searchController?.searchResultsUpdater = self
        searchController?.dimsBackgroundDuringPresentation = false
        searchController?.hidesNavigationBarDuringPresentation = false
        searchController?.searchBar.placeholder = isLanguageEnglish() ? "Search" : "搜索"

extension EWCountryCodeViewController: UISearchResultsUpdating{
    /// searchResults代理方法,将搜索到的内容加入resultArray 赋给tableView
    func updateSearchResults(for searchController: UISearchController) {
        if results.count > 0 {
            results.removeAll()
        }
        let inputText = searchController.searchBar.text
        let array: Array> = Array(sortedNameDict!.values) as! Array>
        for (_, obj) in array.enumerated() {
            for (_, obj) in obj.enumerated() {
                if obj.contains(inputText ?? ""){
                    self.results.append(obj)
                }
            }
        }
        tableView.reloadData()
    }
}

4. 实现点击cell方法,实现闭包回调。

    private func selectCodeIndex(indexPath: IndexPath){
        let originText = self.showCodeStringIndex(indexPath: indexPath as NSIndexPath)
        let array = originText.components(separatedBy: "+")
        let countryName = array.first?.trimmingCharacters(in: CharacterSet.whitespaces)
        let code = array.last

        if self.backCountryCode != nil {
            self.backCountryCode!(countryName ?? "", code ?? "")
        }
        searchController?.isActive = false
        searchController?.searchBar.resignFirstResponder()
        self.navigationController?.popViewController(animated: true)
    }

5. 获取系统语言,实现中英文自动匹配。

/// 获取系统语言方法
fileprivate func getCurrentLanguage() -> String {
    let preferredLang = Bundle.main.preferredLocalizations.first! as NSString
    switch String(describing: preferredLang) {
    case "en-US", "en-CN":
        return "en"//英文
    case "zh-Hans-US","zh-Hans-CN","zh-Hant-CN","zh-TW","zh-HK","zh-Hans":
        return "cn"//中文
    default:
        return "en"
    }
}

调用方法:

let vc = EWCountryCodeViewController()
vc.backCountryCode = { [weak self] country, code in
    self?.showCountryLabel.text = country
    self?.showCodeLabel.text = code
}
self.navigationController?.pushViewController(vc, animated: true)


github地址: EWCountryCode

项目改自OC项目:XWCountryCode,我遇到这个需求,参考这个项目将其修改为了Swift版本,并修改了其一点小bug,有兴趣或者使用OC语言的朋友可以看下这个项目。

有问题欢迎探讨.

你可能感兴趣的:(Swift.国家/地区区号选择器)