在顶部添加 UILabel 作为 UITextField 的子视图

Add UILabel as subview of UITextField on top

我正在实施 UILabel 作为 UITextField 的子视图,它将显示在 UITextField 本身的正上方。 UITextField 有一个圆形边框,我想要实现的是 UILabel 显示在边框上。

目前一切正常,但 UILabel 绘制在 UITextField 边框的后面。我希望它位于 "over"(上方)边框,这样白色背景颜色将显示在边框的一部分上方,并使文本更易于阅读。

var priceTextField: CustomTextField = {

    let priceTextField = CustomTextField()
    priceTextField.layer.cornerRadius = 10.0
    priceTextField.layer.borderWidth = 1.0
    priceTextField.layer.borderColor = UIColor.darkGray.cgColor
    priceTextField.translatesAutoresizingMaskIntoConstraints = false
    priceTextField.font = UIFont.systemFont(ofSize: 15)
    priceTextField.textColor = .black
    priceTextField.text = "0"
    priceTextField.suffix = "EUR"
    priceTextField.suffixTextColor = .darkGray
    priceTextField.suffixSpacing = 2.0
    priceTextField.textAlignment = .center
    priceTextField.labelText = "Price"

    return priceTextField

}()

在我的 CustomTextField class(UITextField 的子class)中:

public var labelText: String?

var topLabel: UILabel = {

    let topLabel = UILabel()
    topLabel.translatesAutoresizingMaskIntoConstraints = false
    topLabel.textAlignment = .center
    topLabel.font = UIFont.systemFont(ofSize: 12)
    topLabel.textColor = .lightGray
    topLabel.backgroundColor = .white
    topLabel.numberOfLines = 1
    return topLabel

}()

func setupLabel() {

    self.addSubview(topLabel)
    topLabel.centerYAnchor.constraint(equalTo: self.topAnchor).isActive = true
    topLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true
    topLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
    topLabel.text = labelText

}

我在 UITextFielddraw(_ rect: CGRect) 方法的末尾调用了 setupLabel()(因为我用它来显示输入值后面的欧元符号)。

我试过 bringSubviewToFront 并更改 UILabel 层的 zPosition,但没有成功。

现在看起来像这样:

如何使文本 "above" 的边框位于顶部?

编辑:尝试了 Sh_Khan 的解决方案,但它仍然隐藏在边界后面。

import Foundation
import UIKit

public class CustomTextView: UIView, UITextFieldDelegate {

    public var labelText: String?

    var customTextField: CustomTextField = {

        let customTextField = CustomTextField()
        customTextField.translatesAutoresizingMaskIntoConstraints = false
        customTextField.font = UIFont.systemFont(ofSize: 15)
        customTextField.textColor = .black
        customTextField.textAlignment = .center
        customTextField.text = "0"
        customTextField.suffix = "EUR"
        customTextField.suffixTextColor = .lightGray
        customTextField.suffixSpacing = 2.0

        return customTextField

    }()

    var topLabel: UILabel = {

        let topLabel = UILabel()
        topLabel.translatesAutoresizingMaskIntoConstraints = false
        topLabel.font = UIFont.systemFont(ofSize: 12)
        topLabel.textColor = .darkGray
        topLabel.numberOfLines = 1
        topLabel.backgroundColor = .red
        topLabel.textAlignment = .center

        return topLabel

    }()

    override public init(frame: CGRect) {

        super.init(frame: frame)
        setupBorders()

    }

    public override func layoutSubviews() {

        setupViews()

    }

    func setupBorders() {

        self.layer.cornerRadius = 10.0
        self.layer.borderColor = UIColor.lightGray.cgColor
        self.layer.borderWidth = 1.0

    }

    func setupViews() {

        addSubview(topLabel)
//        insertSubview(topLabel, aboveSubview: customTextField)
        insertSubview(customTextField, belowSubview: topLabel)

        customTextField.topAnchor.constraint(equalTo: topAnchor).isActive = true
        customTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        customTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        customTextField.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        topLabel.centerYAnchor.constraint(equalTo: topAnchor).isActive = true
        topLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
        topLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10).isActive = true

        topLabel.text = labelText

    }

    public required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)
        setupViews()

    }

}

您可以尝试通过创建一个 UIView 子类来组织它,这样一切都会按照添加的顺序正确显示

class CustomView: UIView {

    var priceTextField: CustomTextField = {

        let priceTextField = CustomTextField()
        priceTextField.layer.cornerRadius = 10.0
        priceTextField.layer.borderWidth = 1.0
        priceTextField.layer.borderColor = UIColor.darkGray.cgColor
        priceTextField.translatesAutoresizingMaskIntoConstraints = false
        priceTextField.font = UIFont.systemFont(ofSize: 15)
        priceTextField.textColor = .black
        priceTextField.text = "0"
        priceTextField.suffix = "EUR"
        priceTextField.suffixTextColor = .darkGray
        priceTextField.suffixSpacing = 2.0
        priceTextField.textAlignment = .center
        priceTextField.labelText = "Price"

        return priceTextField

    }() 
    var topLabel: UILabel = {

        let topLabel = UILabel()
        topLabel.translatesAutoresizingMaskIntoConstraints = false
        topLabel.textAlignment = .center
        topLabel.font = UIFont.systemFont(ofSize: 12)
        topLabel.textColor = .lightGray
        topLabel.backgroundColor = .white
        topLabel.numberOfLines = 1
        return topLabel

    }()

   var lableStr:String?
   init(frame: CGRect,lblTex:String) {
    super.init(frame: frame)
       lableStr = lblTex
       createSubviews()
    }

    override init(frame: CGRect) {
    super.init(frame: frame)
       createSubviews()
    }
    required init?(coder aDecoder: NSCoder) {
       super.init(coder: aDecoder)
       createSubviews()
    }
    func createSubviews() {
       // all the layout code from above
       // add the textfield then the label and set constraints properly
    }
}

根据Apple specification:它合成在接收者的内容和子层之上。

因此,边框将始终位于所有子视图之上,即使将子视图置于最前面等等。

所以需要做一个背景视图来伪造边框。

类似于Whosebug Question

示例:

这里是自己 "TextField" activeborderView 是 "UiView"

activeborderView.frame = CGRect.init(x: -1, y: -1, 宽度: self.frame.size.width+2, 高度: self.frame.size.height+2) activeborderView.translatesAutoresizingMaskIntoConstraints = 假 self.addSubview(activeborderView)

        activeborderView.topAnchor.constraint(equalTo: self.topAnchor, constant:-1).isActive = true // Place our label 10 pts above the text field
        activeborderView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: -1).isActive=true

        activeborderView.heightAnchor.constraint(equalToConstant: self.frame.size.height+2).isActive=true

        activeborderView.widthAnchor.constraint(equalToConstant: self.frame.size.width+2).isActive=true

        activeborderView.layer.borderWidth = 3
        activeborderView.layer.borderColor = CustomColor.blue().cgColor

         activeborderView.layer.cornerRadius = 5
        activeborderView.backgroundColor = .white

        self.sendSubviewToBack(activeborderView)
        self.setNeedsDisplay()