如何在父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
相关产品推荐
相关产品推荐

