【问题标题】:Custom UITextField with UILabel multiline support for error text自定义 UITextField 与 UILabel 多行支持错误文本
【发布时间】:2018-05-21 18:17:55
【问题描述】:

我想在底部创建带有错误标签的自定义 UITextField。我希望标签是多行的,我试过numberOfLines = 0。但它不起作用。

这是我的班级的sn-p

public class MyTextField: UITextField {
private let helperTextLabel: UILabel = {
    let label = UILabel()
    label.font = UIFont.systemFont(ofSize: 12.0, weight: UIFont.Weight.regular)
    label.textColor = helperTextColor
    label.numberOfLines = 0

    return label
}()

    public override init(frame: CGRect) {
    super.init(frame: frame)
    self.addSubview(errorTextLabel)
}

public required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.addSubview(errorTextLabel)
}

public override func layoutSubviews() {
    super.layoutSubviews()

    errorTextLabel.frame = CGRect(x: bounds.minX, y: bounds.maxY - 20, width: bounds.width, height: 20)
}
public override var intrinsicContentSize: CGSize {
    return CGSize(width: 240.0, height: 68.0)
}

public override func sizeThatFits(_ size: CGSize) -> CGSize {
    return intrinsicContentSize
}
}

我认为根本原因是因为我将高度设置为 20,但是如何根据errorTextLabel.text 值动态设置高度?

【问题讨论】:

  • 使用label.sizeToFit() 并尝试一次
  • 我试过了,还是不行。仍然被截断,只有 1 行。我认为将标签高度硬编码为 20 或将文本字段高度硬编码为 68 的代码存在问题?
  • 添加这个并检查label.lineBreakMode = .byWordWrap
  • 还是不行,还是只显示1行。
  • 你为什么不用自动布局?

标签: ios swift uitextfield


【解决方案1】:

你给你的标签一个固定的大小。

不使用 AutoLayout 并在需要时为文本字段和标签留出空间来扩大其大小。

就个人而言,如果创建这个特定的控件,我会在 UIStackView 中创建一个带有文本字段和标签的 UIView。这样,如果标签在没有错误的情况下被隐藏,stackview 将自动为您调整高度。然后,当您取消隐藏它时,视图将展开以适应两个控件。

一个基本的例子:

//: Playground - noun: a place where people can play
import UIKit
import PlaygroundSupport

class LabelledTextView: UIView {

    private let label = UILabel()
    private let textfield = UITextField()
    private let stackView = UIStackView()


    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = .white
        addSubview(stackView)

        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        stackView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
        stackView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
        stackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        stackView.alignment = .leading
        stackView.axis = .vertical
        stackView.distribution = .fillEqually
        stackView.addArrangedSubview(textfield)
        stackView.addArrangedSubview(label)

        textfield.placeholder = "Please enter some text"
        label.numberOfLines = 0
        label.text = "Text did not pass validation, Text did not pass validation, Text did not pass validation, Text did not pass validation"
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

let labelledTextView = LabelledTextView(frame: CGRect(x: 50, y: 300, width: 300, height: 60))

let vc = UIViewController()
vc.view.addSubview(labelledTextView)
labelledTextView.translatesAutoresizingMaskIntoConstraints = false
labelledTextView.topAnchor.constraint(equalTo: vc.view.topAnchor).isActive = true
labelledTextView.leftAnchor.constraint(equalTo: vc.view.leftAnchor).isActive = true
labelledTextView.widthAnchor.constraint(equalToConstant: 300).isActive = true
labelledTextView.heightAnchor.constraint(greaterThanOrEqualToConstant: 60).isActive = true
PlaygroundPage.current.liveView = vc.view

【讨论】:

  • 如果我以这种代码风格创建而不是使用自定义 UIView @Scriptable,您有什么建议吗?
  • 您是使用故事板还是以编程方式创建?用故事板展示一个例子更难
  • 我以编程方式创建了它。
  • 试试这个例子。文本在标签中的时间越长,它就会扩展。
  • 非常感谢@Scriptable,对不起,当你问我是否使用故事板创作时我误解了。我实际上是使用情节提要创建视图。我试图将初始化框架中的代码复制粘贴到初始化编码器,但如果我使用情节提要,标签仅显示 1 行。你知道它有什么问题吗?抱歉问了太多问题。
【解决方案2】:

你需要使用sizeToFit():

    errorTextLabel.sizeToFit()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多