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

如何在父UIView中居中且适配多屏地排列6个UITextField

问题描述

我需要在一个已居中、宽度为self.view 0.85倍的UIView内放置6个UITextField,实现它们在父视图内完美居中且均匀分布的效果。此前用硬编码适配了单一iPhone尺寸,但在其他设备上表现不佳,现寻求最优实现方案。

当前代码如下:

class FormView: UIViewController {
    //INSTANTIATING VARIABLES
    ...


    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        setupCodeFieldView()
    }
    
    private func setupCodeFieldView(){
        codeFieldView.backgroundColor = .green
        codeFieldView.translatesAutoresizingMaskIntoConstraints = false
        parentSubview.addSubview(codeFieldView)
        codeFieldView.heightAnchor.constraint(equalToConstant: 60).isActive = true
        codeFieldView.topAnchor.constraint(equalTo: parentSubview.bottomAnchor, constant: 5).isActive = true
        //SETTING WIDTH SIZE AND CENTERING PARENT VIEW
        codeFieldView.widthAnchor.constraint(equalTo:view.widthAnchor, multiplier: 0.85).isActive = true
        codeFieldView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        
        setupCodeFields()
    }

    fileprivate func setupCodeFields() {
        var textFieldArr: [UITextField] = []
        for index in 0...5{
            let field: UITextField = UITextField()
            field.returnKeyType = .next
            field.setUnderline()
            field.borderStyle = .none
            field.keyboardType = .numberPad
            field.backgroundColor = UIColor.white
            field.tag = index
            field.textAlignment = .center
            let valueWidth = codeFieldView.bounds.size.width/6
            field.placeholder = String(describing: valueWidth)
            field.accessibilityIdentifier = "field" + String(index)
            codeFieldView.addSubview(field)
            field.layer.cornerRadius = 5.0
            field.layer.borderWidth = 1.0
            field.layer.borderColor = UIColor(red: 0.45, green: 0.46, blue: 0.50, alpha: 1.00).cgColor
            field.translatesAutoresizingMaskIntoConstraints = false
            
            //HERE IS HOW SET THE WIDTH OF THE BUTTON
            field.widthAnchor.constraint(equalToConstant: floor(valueWidth)-5).isActive = true
            field.heightAnchor.constraint(equalToConstant: 60).isActive = true
            field.topAnchor.constraint(equalTo: codeFieldView.topAnchor).isActive = true
            if index == 0 {
                field.leftAnchor.constraint(equalTo:codeFieldView.leftAnchor).isActive = true
                
            } else {
                field.leftAnchor.constraint(equalTo: textFieldArr[index-1].rightAnchor, constant: 5).isActive = true
            }
            textFieldArr.append(field)
        }
    }
}

当前问题:父视图已居中,但6个UITextField无法在绿色父视图内均匀分布,期望实现6个带边框的输入框水平居中、彼此间距相等、左右留有合适边距的效果。


最优解决方案

使用UIStackView是实现该需求最简洁可靠的方式,它能自动处理间距、适配不同设备尺寸,无需手动计算每个输入框的位置和宽度。

修改后的完整代码:

class FormView: UIViewController {
    // 假设codeFieldView和parentSubview已提前声明
    let codeFieldView = UIView()
    let parentSubview = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        // 将布局初始化移至viewDidLoad,避免重复调用创建视图
        setupCodeFieldView()
    }
    
    private func setupCodeFieldView(){
        codeFieldView.backgroundColor = .green
        codeFieldView.translatesAutoresizingMaskIntoConstraints = false
        parentSubview.addSubview(codeFieldView)
        
        // 批量激活约束,代码更简洁
        NSLayoutConstraint.activate([
            codeFieldView.heightAnchor.constraint(equalToConstant: 60),
            codeFieldView.topAnchor.constraint(equalTo: parentSubview.bottomAnchor, constant: 5),
            codeFieldView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.85),
            codeFieldView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])
        
        setupCodeFields()
    }

    fileprivate func setupCodeFields() {
        // 创建水平方向的StackView
        let stackView = UIStackView()
        stackView.axis = .horizontal
        stackView.alignment = .center
        stackView.distribution = .fillEqually // 让所有子视图均分可用宽度
        stackView.spacing = 8 // 输入框之间的间距,可按需调整
        stackView.translatesAutoresizingMaskIntoConstraints = false
        codeFieldView.addSubview(stackView)
        
        // 给StackView添加约束,控制其在父视图内的位置和边距
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: codeFieldView.topAnchor),
            stackView.bottomAnchor.constraint(equalTo: codeFieldView.bottomAnchor),
            stackView.leadingAnchor.constraint(equalTo: codeFieldView.leadingAnchor, constant: 16), // 左侧边距
            stackView.trailingAnchor.constraint(equalTo: codeFieldView.trailingAnchor, constant: -16) // 右侧边距
        ])
        
        for index in 0...5{
            let field = UITextField()
            field.returnKeyType = .next
            field.setUnderline() // 假设该自定义下划线方法已实现
            field.borderStyle = .none
            field.keyboardType = .numberPad
            field.backgroundColor = .white
            field.tag = index
            field.textAlignment = .center
            field.accessibilityIdentifier = "field\(index)"
            
            // 输入框样式设置
            field.layer.cornerRadius = 5.0
            field.layer.borderWidth = 1.0
            field.layer.borderColor = UIColor(red: 0.45, green: 0.46, blue: 0.50, alpha: 1.00).cgColor
            
            // 仅需设置高度约束,宽度由StackView自动分配
            field.heightAnchor.constraint(equalToConstant: 60).isActive = true
            
            stackView.addArrangedSubview(field)
        }
    }
}

关键修改点:

  • 将布局初始化代码从viewWillLayoutSubviews移至viewDidLoad,避免重复创建视图和约束
  • 用UIStackView管理6个UITextField,通过fillEqually属性让输入框自动均分StackView的可用宽度
  • 通过StackView的spacing属性控制输入框之间的间距,左右边距通过StackView的leading/trailing约束设置,自动适配所有设备
  • 每个UITextField仅需设置高度约束,无需手动计算宽度和位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 09:06:17