iOS 应用中的布局问题 (NSLayoutConstraint)
A layout issue (NSLayoutConstraint) in an iOS app
在 iOS 应用程序中,我遇到了自动布局问题。
以下 2 个屏幕截图显示了问题。
右边的开关(UISwitch 对象)水平位移,应该固定。谁能看到发生了什么?
左边的字符串确实在改变长度,但我认为(根据我设置约束的方式)应该调整字体大小或将字符串分成两行;但开关没有移位。
这里是相关的swift代码:
import UIKit
class My_ViewController: UIViewController {
let xPanel = UILabel(), yPanel = UILabel(),
khToggle = UISwitch(), khLabel = UILabel()
....
override func viewDidLoad() {
super.viewDidLoad()
layOutUI()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
.....
toggleKeepHide(khToggle)
}
func layOutUI() {
for component in [xPanel,yPanel,khLabel,khToggle] {
component.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(component)
}
...........
khLabel.numberOfLines = 0
khLabel.adjustsFontSizeToFitWidth = true
khToggle.addTarget(self,
action: #selector(toggleKeepHide(_:)),
for: .valueChanged)
view.addConstraints([
.........
NSLayoutConstraint(item: khToggle, attribute: .right, relatedBy: .equal,
toItem: view, attribute: .right, multiplier: 1.0, constant: -30.0),
NSLayoutConstraint(item: khToggle, attribute: .top, relatedBy: .equal,
toItem: yPanel, attribute: .bottom, multiplier: 1.0,
constant: 50.0),
NSLayoutConstraint(item: khLabel, attribute: .right, relatedBy: .equal,
toItem: khToggle, attribute: .left, multiplier: 1.0, constant: -23.0),
NSLayoutConstraint(item: khLabel, attribute: .centerY, relatedBy: .equal,
toItem: khToggle, attribute: .centerY, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: khLabel, attribute: .left, relatedBy: .equal,
toItem: view, attribute: .left, multiplier: 1.0, constant: 30.0)])
}
@objc func toggleKeepHide(_ sender: UISwitch) {
if sender.isOn {khLabel.text = "Hide this object from the wyxoug list."}
else {khLabel.text = "Keep this object in the wyxoug list."}
}
}
标签和切换的水平约束相互竞争。
(如果你进入Xcode的可视化调试器,你会发现有一个警告:UISwitch
实例的宽度和水平位置不明确。)
解决方案
您为AutoLayout 提供了绝对值,它无法解析要求。要解决此问题,请通过将标签的抗压性设置为较低的值来为要求引入一些灵活性:
khLabel.setCompressionResistance(.defaultLow, for: .horizontal)
您没有提供足够的信息来重现问题。这是我的视图控制器 viewDidLoad
中代码的缩减(除了标签和开关,我删除了所有内容,修复了你的 left
和 right
(你永远不应该使用它们),并改变了两个视图之间的对齐方式为 top
而不是 center
):
khToggle = UISwitch()
khToggle.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(khToggle)
khLabel = UILabel()
khLabel.text = String(repeating: "word ", count: 40)
khLabel.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(khLabel)
// Do any additional setup after loading the view.
khLabel.numberOfLines = 0
view.addConstraints([
NSLayoutConstraint(item: khToggle!, attribute: .trailing, relatedBy: .equal,
toItem: view, attribute: .trailing, multiplier: 1.0, constant: -30.0),
NSLayoutConstraint(item: khToggle!, attribute: .top, relatedBy: .equal,
toItem: view, attribute: .top, multiplier: 1.0,
constant: 50.0),
NSLayoutConstraint(item: khLabel!, attribute: .trailing, relatedBy: .equal,
toItem: khToggle, attribute: .leading, multiplier: 1.0, constant: -23.0),
NSLayoutConstraint(item: khLabel!, attribute: .top, relatedBy: .equal,
toItem: khToggle, attribute: .top, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: khLabel!, attribute: .leading, relatedBy: .equal,
toItem: view, attribute: .leading, multiplier: 1.0, constant: 30.0)])
结果显示正常;没有约束冲突或歧义,看起来就像人们期望的那样:
在 iOS 应用程序中,我遇到了自动布局问题。
以下 2 个屏幕截图显示了问题。
右边的开关(UISwitch 对象)水平位移,应该固定。谁能看到发生了什么?
左边的字符串确实在改变长度,但我认为(根据我设置约束的方式)应该调整字体大小或将字符串分成两行;但开关没有移位。
这里是相关的swift代码:
import UIKit
class My_ViewController: UIViewController {
let xPanel = UILabel(), yPanel = UILabel(),
khToggle = UISwitch(), khLabel = UILabel()
....
override func viewDidLoad() {
super.viewDidLoad()
layOutUI()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
.....
toggleKeepHide(khToggle)
}
func layOutUI() {
for component in [xPanel,yPanel,khLabel,khToggle] {
component.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(component)
}
...........
khLabel.numberOfLines = 0
khLabel.adjustsFontSizeToFitWidth = true
khToggle.addTarget(self,
action: #selector(toggleKeepHide(_:)),
for: .valueChanged)
view.addConstraints([
.........
NSLayoutConstraint(item: khToggle, attribute: .right, relatedBy: .equal,
toItem: view, attribute: .right, multiplier: 1.0, constant: -30.0),
NSLayoutConstraint(item: khToggle, attribute: .top, relatedBy: .equal,
toItem: yPanel, attribute: .bottom, multiplier: 1.0,
constant: 50.0),
NSLayoutConstraint(item: khLabel, attribute: .right, relatedBy: .equal,
toItem: khToggle, attribute: .left, multiplier: 1.0, constant: -23.0),
NSLayoutConstraint(item: khLabel, attribute: .centerY, relatedBy: .equal,
toItem: khToggle, attribute: .centerY, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: khLabel, attribute: .left, relatedBy: .equal,
toItem: view, attribute: .left, multiplier: 1.0, constant: 30.0)])
}
@objc func toggleKeepHide(_ sender: UISwitch) {
if sender.isOn {khLabel.text = "Hide this object from the wyxoug list."}
else {khLabel.text = "Keep this object in the wyxoug list."}
}
}
标签和切换的水平约束相互竞争。
(如果你进入Xcode的可视化调试器,你会发现有一个警告:UISwitch
实例的宽度和水平位置不明确。)
解决方案
您为AutoLayout 提供了绝对值,它无法解析要求。要解决此问题,请通过将标签的抗压性设置为较低的值来为要求引入一些灵活性:
khLabel.setCompressionResistance(.defaultLow, for: .horizontal)
您没有提供足够的信息来重现问题。这是我的视图控制器 viewDidLoad
中代码的缩减(除了标签和开关,我删除了所有内容,修复了你的 left
和 right
(你永远不应该使用它们),并改变了两个视图之间的对齐方式为 top
而不是 center
):
khToggle = UISwitch()
khToggle.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(khToggle)
khLabel = UILabel()
khLabel.text = String(repeating: "word ", count: 40)
khLabel.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(khLabel)
// Do any additional setup after loading the view.
khLabel.numberOfLines = 0
view.addConstraints([
NSLayoutConstraint(item: khToggle!, attribute: .trailing, relatedBy: .equal,
toItem: view, attribute: .trailing, multiplier: 1.0, constant: -30.0),
NSLayoutConstraint(item: khToggle!, attribute: .top, relatedBy: .equal,
toItem: view, attribute: .top, multiplier: 1.0,
constant: 50.0),
NSLayoutConstraint(item: khLabel!, attribute: .trailing, relatedBy: .equal,
toItem: khToggle, attribute: .leading, multiplier: 1.0, constant: -23.0),
NSLayoutConstraint(item: khLabel!, attribute: .top, relatedBy: .equal,
toItem: khToggle, attribute: .top, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: khLabel!, attribute: .leading, relatedBy: .equal,
toItem: view, attribute: .leading, multiplier: 1.0, constant: 30.0)])
结果显示正常;没有约束冲突或歧义,看起来就像人们期望的那样: