简体   繁体   English

如何在父 UIView 中居中多个 UI 元素

[英]How to center multiple UI elements within a parent UIView

I'm trying to create these 6 UITextField centered within a UIVIew that I have centered and is 0.85 the width of self.view .我正在尝试创建以 UIVIew 为中心的这 6 个 UITextField ,并且是self.view宽度的 0.85。 I was able to get it working on one iPhone size however it was hardcoded and doesn't transform well on other iPhone sizes.我能够让它在一种 iPhone 尺寸上工作,但是它是硬编码的,并且在其他 iPhone 尺寸上不能很好地转换。

So now I'm trying to figure out the best way to properly center these 6 elements.所以现在我试图找出正确居中这 6 个元素的最佳方法。

Here's what I currently have:这是我目前拥有的:

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)
        }
    }
}

Here's what I currently have.这是我目前拥有的。 You can see that the 6 elements' parent view is centered and that I'm struggling to have the 6 children UITextFields perfectly spaced across the highlighted green parent view.您可以看到 6 个元素的父视图居中,我正在努力让 6 个子 UITextFields 完美地分布在突出显示的绿色父视图中。 在此处输入图像描述

Mockup of how I'd like my UI to look:我希望我的 UI 外观的样机: 关于我希望我的 UI 外观的样机

You can do this easily with a UIStackView您可以使用UIStackView轻松完成此操作

Here's a quick example (based on your code):这是一个简单的示例(基于您的代码):

class FormView: UIViewController {
    //INSTANTIATING VARIABLES
    //...
    
    let codeFieldView = UIView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .gray
        
        setupCodeFieldView()

    }
    
    private func setupCodeFieldView() {
        codeFieldView.backgroundColor = .green
        codeFieldView.translatesAutoresizingMaskIntoConstraints = false
        
        // not clear what you're doing with "parentSubview"
        //  so let's just add it to the root view
        
        view.addSubview(codeFieldView)
        
        // always respect safe-area
        let g = view.safeAreaLayoutGuide
        
        NSLayoutConstraint.activate([
            
            // height of 60
            codeFieldView.heightAnchor.constraint(equalToConstant: 60),
            // 85% of the width
            codeFieldView.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.85),
            // centered vertically and horizontally
            codeFieldView.centerYAnchor.constraint(equalTo: g.centerYAnchor),
            codeFieldView.centerXAnchor.constraint(equalTo: g.centerXAnchor),

        ])
        
        setupCodeFields()
    }
    
    fileprivate func setupCodeFields() {
        
        // let's add a stack view to codeFieldView
        let stackView = UIStackView()
        stackView.spacing = 5
        stackView.distribution = .fillEqually
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        codeFieldView.addSubview(stackView)
        
        NSLayoutConstraint.activate([
            // constrain stack view to all 4 sides of code field view
            stackView.topAnchor.constraint(equalTo: codeFieldView.topAnchor),
            stackView.leadingAnchor.constraint(equalTo: codeFieldView.leadingAnchor),
            stackView.trailingAnchor.constraint(equalTo: codeFieldView.trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: codeFieldView.bottomAnchor),
        ])
        
        // now we add the text fields
        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
            field.accessibilityIdentifier = "field" + String(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
            
            // add it to the stack view
            stackView.addArrangedSubview(field)
        }
        
    }

}

The result:结果:

在此处输入图像描述

Your question didn't indicate how you want the UI to look on a wider device, so here's how that looks when the phone is rotated:您的问题并未表明您希望 UI 如何在更宽的设备上显示,因此以下是手机旋转时的外观:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM