Swift UIStackView contentHuggingPriority不';t为填补可用空间而工作
我想在水平视图中创建一个包含以下内容的聊天底部栏:Swift UIStackView contentHuggingPriority不';t为填补可用空间而工作,swift,autolayout,uistackview,Swift,Autolayout,Uistackview,我想在水平视图中创建一个包含以下内容的聊天底部栏: 左侧有一个UITextField,占用了所有可用空间 右侧固定大小的标签(默认内部内容大小) 这是我的密码: let messageTextField = UITextField() messageTextField.translatesAutoresizingMaskIntoConstraints = false messageTextField.setContentCompressionResistancePriority(.defau
- 左侧有一个
,占用了所有可用空间UITextField
- 右侧固定大小的标签(默认内部内容大小)
let messageTextField = UITextField()
messageTextField.translatesAutoresizingMaskIntoConstraints = false
messageTextField.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "SEND"
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)
label.textColor = .red
let sv = UIStackView()
sv.axis = .horizontal
sv.distribution = .fill
sv.alignment = .center
sv.translatesAutoresizingMaskIntoConstraints = false
// constraint the stack view to the bottomBar view
bottomBar.addSubview(sv)
NSLayoutConstraint.activate([
sv.leadingAnchor.constraint(equalTo: bottomBar.leadingAnchor, constant: 20),
sv.trailingAnchor.constraint(equalTo: bottomBar.trailingAnchor, constant: -20),
sv.bottomAnchor.constraint(equalTo: bottomBar.bottomAnchor, constant: -8),
sv.topAnchor.constraint(equalTo: bottomBar.topAnchor, constant: 8)
])
sv.addArrangedSubview(messageTextField)
sv.addArrangedSubview(label)
NSLayoutConstraint.activate([
messageTextField.heightAnchor.constraint(equalTo:sv.heightAnchor),
// I didn't put any width constraint for textField because it make no sense, as I want it to take all the available space on the right
])
使用此代码,标签将扩展其大小并填充右侧的所有可用空间,而文本字段不会显示(检查器表示宽度为0);与我想要的正好相反
我不明白为什么它不工作,因为我显式地配置了它,这样它就不会用以下内容扩展标签:
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
而是使用以下命令展开文本字段:
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
我错过了什么?我已经阅读了很多答案、苹果文档,并学习了各种教程和视频,但我无法完成这件看似简单的事情。我在模拟器(iPhone 12)上的Xcode 12.3上快速尝试 将默认值留给stackview和内容拥抱,这对我很有用:
override func viewDidLoad() {
super.viewDidLoad()
// Just added a view anchored to the bottom of the view controller for the purpose of the test
let bottomBar = UIView()
bottomBar.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(bottomBar)
bottomBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
bottomBar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
bottomBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
bottomBar.heightAnchor.constraint(equalToConstant: 40.0).isActive = true
bottomBar.backgroundColor = .yellow
let messageTextField = UITextField()
messageTextField.translatesAutoresizingMaskIntoConstraints = false
messageTextField.backgroundColor = .cyan
// LEAVING DEFAULTS
//messageTextField.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
//messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "SEND"
// LEAVING DEFAULTS
//label.setContentHuggingPriority(.defaultLow, for: .horizontal)
//label.setContentCompressionResistancePriority(.required, for: .horizontal)
label.textColor = .red
let sv = UIStackView()
sv.axis = .horizontal
// LEAVING DEFAULTS
//sv.distribution = .fill
//sv.alignment = .center
sv.translatesAutoresizingMaskIntoConstraints = false
// constraint the stack view to the bottomBar view
bottomBar.addSubview(sv)
NSLayoutConstraint.activate([
sv.leadingAnchor.constraint(equalTo: bottomBar.leadingAnchor, constant: 20),
sv.trailingAnchor.constraint(equalTo: bottomBar.trailingAnchor, constant: -20),
sv.bottomAnchor.constraint(equalTo: bottomBar.bottomAnchor, constant: -8),
sv.topAnchor.constraint(equalTo: bottomBar.topAnchor, constant: 8)
])
sv.addArrangedSubview(messageTextField)
sv.addArrangedSubview(label)
NSLayoutConstraint.activate([
messageTextField.heightAnchor.constraint(equalTo:sv.heightAnchor),
])
}
这就是结果:
你把它倒过来了 设置
Content-Hugging Priority
意味着“控制此元素拥抱其内容的方式”
因此,例如,如果您有一个UILabel
,其中只有字母“a”,那么高内容覆盖优先级将使标签仅与单个字母一样宽
这两条线:
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
您已经告诉自动布局:
保持messageTextField
仅与文本一样宽,并允许label
延伸到比文本更宽的位置
你想要的是:
// don't let label stretch at all
label.setContentHuggingPriority(.required, for: .horizontal)
// let message text field stretch if needed
messageTextField.setContentHuggingPriority(.defaultHigh, for: .horizontal)
然后,堆栈视图将拉伸文本字段以填充可用空间。您是否试图通过注释掉sv.distribution=.fill和sv.alignment=.center来保留堆栈视图的默认值?默认情况下,这两个“fill”都是刚刚尝试过的,但正如您指出的,这些是默认值,因此无法解决问题:/谢谢谢谢你的回答,卢卡。这很有效,但布局调试器说两个排列的子视图的大小(宽度和水平位置)都不明确。这看起来像是在雄心勃勃的情况下UIStackView的恢复行为。我的意思是,如果我有4个视图(我想在左侧添加一些按钮),会怎么样,如何分辨一个视图是拉伸的,而另一个视图是压缩的?那就是,非常感谢!我不是英语母语,我认为“拥抱”一词的意思是“巨大”就像“伟大”,因此我感到困惑!