在 Swift 中,以编程方式创建 UIView 并向其添加控件并使用自动布局,导致控件出现在视图的父级上
In Swift, programmatically creating UIView and adding controls to it and using auto layout, causes the controls to appear on the view's parent
我正在尝试为 Swift 3 中的 iOS 编写一个简单的复合组件。它由一个 UILabel 和一个水平布局的 UITextField 组成,然后是它们下面的一行。但是发生的事情是 UILabel 消失了,UITextField 出现在父视图上并且行也消失了。
My design in sketch
What it actually looks like in the Storyboard
My component's constraints in the view controller
我的意图是使用自动布局,将标签锚定到视图的顶部和前导锚点,将文本字段锚定到视图的顶部和标签的尾随锚点,并使用常量,这样它们就会并排显示.
我确实在这方面做了很多研究,一个看起来非常接近我想要的网站是 https://www.raywenderlich.com/125718/coding-auto-layout,我想我或多或少地遵循了相同的方法。
我正在做一些明显错误的事情,但无法弄清楚是什么。非常感谢任何帮助,我已经做了几天了。
import UIKit
@IBDesignable
class OTextEdit: UIView {
@IBInspectable var LabelText: String = "Label"
@IBInspectable var SecureText: Bool = false
@IBInspectable var Color: UIColor = UIColor.black
@IBInspectable var Text: String = "" {
didSet {
edit.text = Text
}
}
fileprivate let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 35))
fileprivate let edit = UITextField(frame: CGRect(x: 210, y: 0, width: 200, height: 35))
fileprivate let line: UIView = UIView()
override var intrinsicContentSize: CGSize {
return CGSize(width: 300, height: 100)
}
func setup() {
label.text = LabelText
label.textColor = Color
label.font = UIFont(name: "Avenir Next Condensed", size: 24)
edit.font = UIFont(name: "Avenir Next Condensed", size: 24)
edit.borderStyle = .roundedRect
edit.isSecureTextEntry = SecureText
line.backgroundColor = UIColor.white
self.addSubview(label)
self.addSubview(edit)
self.addSubview(line)
}
override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
setup()
setupConstaints()
}
func setupConstaints() {
label.translatesAutoresizingMaskIntoConstraints = false
edit.translatesAutoresizingMaskIntoConstraints = false
line.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -10).isActive = true
label.topAnchor.constraint(equalTo: topAnchor)
edit.leadingAnchor.constraint(equalTo: label.leadingAnchor, constant: 10).isActive = true
edit.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
edit.topAnchor.constraint(equalTo: self.topAnchor)
line.heightAnchor.constraint(equalToConstant: 2.0).isActive = true
line.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
line.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
line.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 1.0).isActive = true
}
}
您没有从上到下的一系列约束,因此自动布局无法确定对象的内容大小。您已尝试通过 initrinsicContentSize
进行设置,但您不需要这样做。
您还需要为标签设置水平拥抱优先级,让自动布局知道您希望扩展文本字段:
我删除了您对 intrinsicContentSize
的覆盖并将您的约束更改为:
- 将标签的底部限制在行的顶部
- 约束线的底部到父视图的底部
- 将标签的基线约束到文本字段的基线
- 取消文本字段顶部和父视图之间的约束
- 设置标签的水平拥抱优先级。
func setupConstraints() {
label.translatesAutoresizingMaskIntoConstraints = false
edit.translatesAutoresizingMaskIntoConstraints = false
line.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
label.topAnchor.constraint(equalTo: topAnchor)
label.bottomAnchor.constraint(equalTo: line.topAnchor, constant: -8).isActive = true
edit.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 10).isActive = true
edit.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
edit.firstBaselineAnchor.constraint(equalTo: label.firstBaselineAnchor).isActive = true
line.heightAnchor.constraint(equalToConstant: 2.0).isActive = true
line.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
line.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
line.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 1.0).isActive = true
line.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
我认为这与您所追求的非常接近。
我正在尝试为 Swift 3 中的 iOS 编写一个简单的复合组件。它由一个 UILabel 和一个水平布局的 UITextField 组成,然后是它们下面的一行。但是发生的事情是 UILabel 消失了,UITextField 出现在父视图上并且行也消失了。
My design in sketch
What it actually looks like in the Storyboard
My component's constraints in the view controller
我的意图是使用自动布局,将标签锚定到视图的顶部和前导锚点,将文本字段锚定到视图的顶部和标签的尾随锚点,并使用常量,这样它们就会并排显示.
我确实在这方面做了很多研究,一个看起来非常接近我想要的网站是 https://www.raywenderlich.com/125718/coding-auto-layout,我想我或多或少地遵循了相同的方法。
我正在做一些明显错误的事情,但无法弄清楚是什么。非常感谢任何帮助,我已经做了几天了。
import UIKit
@IBDesignable
class OTextEdit: UIView {
@IBInspectable var LabelText: String = "Label"
@IBInspectable var SecureText: Bool = false
@IBInspectable var Color: UIColor = UIColor.black
@IBInspectable var Text: String = "" {
didSet {
edit.text = Text
}
}
fileprivate let label = UILabel(frame: CGRect(x: 0, y: 0, width: 200, height: 35))
fileprivate let edit = UITextField(frame: CGRect(x: 210, y: 0, width: 200, height: 35))
fileprivate let line: UIView = UIView()
override var intrinsicContentSize: CGSize {
return CGSize(width: 300, height: 100)
}
func setup() {
label.text = LabelText
label.textColor = Color
label.font = UIFont(name: "Avenir Next Condensed", size: 24)
edit.font = UIFont(name: "Avenir Next Condensed", size: 24)
edit.borderStyle = .roundedRect
edit.isSecureTextEntry = SecureText
line.backgroundColor = UIColor.white
self.addSubview(label)
self.addSubview(edit)
self.addSubview(line)
}
override func willMove(toSuperview newSuperview: UIView?) {
super.willMove(toSuperview: newSuperview)
setup()
setupConstaints()
}
func setupConstaints() {
label.translatesAutoresizingMaskIntoConstraints = false
edit.translatesAutoresizingMaskIntoConstraints = false
line.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -10).isActive = true
label.topAnchor.constraint(equalTo: topAnchor)
edit.leadingAnchor.constraint(equalTo: label.leadingAnchor, constant: 10).isActive = true
edit.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
edit.topAnchor.constraint(equalTo: self.topAnchor)
line.heightAnchor.constraint(equalToConstant: 2.0).isActive = true
line.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
line.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
line.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 1.0).isActive = true
}
}
您没有从上到下的一系列约束,因此自动布局无法确定对象的内容大小。您已尝试通过 initrinsicContentSize
进行设置,但您不需要这样做。
您还需要为标签设置水平拥抱优先级,让自动布局知道您希望扩展文本字段:
我删除了您对 intrinsicContentSize
的覆盖并将您的约束更改为:
- 将标签的底部限制在行的顶部
- 约束线的底部到父视图的底部
- 将标签的基线约束到文本字段的基线
- 取消文本字段顶部和父视图之间的约束
- 设置标签的水平拥抱优先级。
func setupConstraints() {
label.translatesAutoresizingMaskIntoConstraints = false
edit.translatesAutoresizingMaskIntoConstraints = false
line.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10).isActive = true
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
label.topAnchor.constraint(equalTo: topAnchor)
label.bottomAnchor.constraint(equalTo: line.topAnchor, constant: -8).isActive = true
edit.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 10).isActive = true
edit.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
edit.firstBaselineAnchor.constraint(equalTo: label.firstBaselineAnchor).isActive = true
line.heightAnchor.constraint(equalToConstant: 2.0).isActive = true
line.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 10).isActive = true
line.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20).isActive = true
line.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 1.0).isActive = true
line.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
}
我认为这与您所追求的非常接近。