You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C中手机号输入的国家码前缀UI实现方案问询

我来帮你梳理下这个需求的实现思路和具体代码片段,都是iOS开发里很常用的套路~

整体实现思路拆解

这个需求可以拆成三个核心模块来完成:

  1. 自定义带底部线条+右侧>符号的UITextField
  2. 实现国家码选择页面(用TableView展示你的国家码数组)
  3. 完成选择页和原页面的数据回传,填充选中的国家码

一、自定义带线条和箭头的UITextField

系统默认的UITextField没有底部线条,我们可以通过自定义子类来实现样式,同时把右侧的>做成可点击的按钮(比单纯加Label体验更好),并且禁止TextField手动编辑(毕竟是选择填充,不是输入)。

import UIKit

class CountryCodeTextField: UITextField {
    
    // 右侧箭头按钮
    private let arrowButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle(">", for: .normal)
        button.setTitleColor(.darkGray, for: .normal)
        button.addTarget(self, action: #selector(arrowTapped), for: .touchUpInside)
        return button
    }()
    
    // 底部线条
    private let bottomLine: UIView = {
        let line = UIView()
        line.backgroundColor = .lightGray
        return line
    }()
    
    // 点击箭头的回调,用来通知控制器跳转
    var onArrowTapped: (() -> Void)?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupUI()
    }
    
    private func setupUI() {
        // 禁止手动编辑,只允许点击箭头选择
        isEditable = false
        isUserInteractionEnabled = true
        
        // 添加底部线条约束
        addSubview(bottomLine)
        bottomLine.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            bottomLine.leadingAnchor.constraint(equalTo: leadingAnchor),
            bottomLine.trailingAnchor.constraint(equalTo: trailingAnchor),
            bottomLine.bottomAnchor.constraint(equalTo: bottomAnchor),
            bottomLine.heightAnchor.constraint(equalToConstant: 1)
        ])
        
        // 添加右侧箭头按钮约束
        addSubview(arrowButton)
        arrowButton.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            arrowButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
            arrowButton.centerYAnchor.constraint(equalTo: centerYAnchor),
            arrowButton.widthAnchor.constraint(equalToConstant: 20),
            arrowButton.heightAnchor.constraint(equalTo: heightAnchor)
        ])
        
        // 设置左内边距,避免文字贴边
        leftView = UIView(frame: CGRect(x: 0, y: 0, width: 8, height: 0))
        leftViewMode = .always
    }
    
    @objc private func arrowTapped() {
        onArrowTapped?()
    }
}

二、实现国家码选择页面

用UITableView来展示你现有的国家码数组,建议先把数组转成结构化的模型(方便管理国家名称和代码),然后通过回调把选中的代码回传给原页面。

第一步:定义国家码模型

struct CountryCodeModel {
    let countryName: String
    let code: String // 比如 "+86"、"+1"
}

第二步:实现选择页ViewController

import UIKit

class CountryCodePickerVC: UIViewController {
    
    private let tableView = UITableView()
    // 接收外部传入的国家码数组
    var countryCodes: [CountryCodeModel] = []
    // 选择完成的回调,回传选中的国家码
    var onCodeSelected: ((String) -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
        title = "选择国家/地区码"
        navigationItem.leftBarButtonItem = UIBarButtonItem(title: "取消", style: .plain, target: self, action: #selector(dismissVC))
    }
    
    private func setupTableView() {
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        tableView.dataSource = self
        tableView.delegate = self
    }
    
    @objc private func dismissVC() {
        dismiss(animated: true)
    }
}

extension CountryCodePickerVC: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return countryCodes.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        let model = countryCodes[indexPath.row]
        cell.textLabel?.text = "\(model.countryName) \(model.code)"
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let selectedCode = countryCodes[indexPath.row].code
        onCodeSelected?(selectedCode)
        dismiss(animated: true)
    }
}

三、原页面整合逻辑

在你的主ViewController里,初始化自定义TextField,绑定跳转事件,接收选择页回传的国家码并填充。

import UIKit

class MainVC: UIViewController {
    
    private let countryCodeTextField = CountryCodeTextField()
    // 假设你的国家码数组是这个,替换成你现有的NSMutableArray即可
    private var countryCodesArray: [CountryCodeModel] = [
        CountryCodeModel(countryName: "中国", code: "+86"),
        CountryCodeModel(countryName: "美国", code: "+1"),
        CountryCodeModel(countryName: "日本", code: "+81")
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupTextField()
    }
    
    private func setupTextField() {
        view.addSubview(countryCodeTextField)
        countryCodeTextField.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            countryCodeTextField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 50),
            countryCodeTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            countryCodeTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            countryCodeTextField.heightAnchor.constraint(equalToConstant: 44)
        ])
        
        countryCodeTextField.placeholder = "请选择国家/地区码"
        
        // 绑定箭头点击事件,跳转选择页
        countryCodeTextField.onArrowTapped = { [weak self] in
            guard let self = self else { return }
            let pickerVC = CountryCodePickerVC()
            pickerVC.countryCodes = self.countryCodesArray
            // 接收选中的国家码,填充到TextField
            pickerVC.onCodeSelected = { selectedCode in
                self.countryCodeTextField.text = selectedCode
            }
            self.present(pickerVC, animated: true)
        }
    }
}

额外优化建议

  • 如果你的国家码数组是Objective-C的NSMutableArray,可以遍历转换成Swift数组或者直接在OC中实现相同逻辑(思路完全一致)。
  • 可以给选择页添加搜索栏,方便用户快速定位国家,提升体验。
  • 可以自定义TableViewCell的样式,让国家码展示更清晰。

内容的提问来源于stack exchange,提问作者Hanz Cheah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:35:02