如果显示 1 个标签,则自动布局不起作用,但适用于 2 个标签
Auto-layout is not working in case 1 label is shown, but works with 2 labels
当标签是容器视图层次结构中的唯一标签时,标签会扩展到其容器之外。如果有 2 个标签,它工作正常并且两个标签都在容器视图中。
我的实际用例更复杂,但我尝试将其简化为以下代码。
Xcode 10.2 游乐场代码 (Swift 5):
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
print(leadingConstraint.priority)
leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
let trailingConstraint = topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
topConstraint.priority = .defaultLow
topConstraint.isActive = true
let bottomConstraint = topologyView.bottomAnchor.constraint(greaterThanOrEqualTo: containerView.bottomAnchor)
bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
label1.setContentHuggingPriority(.required, for: .horizontal)
label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
print(topologyView.contentHuggingPriority(for: .horizontal))
print(topologyView.contentCompressionResistancePriority(for: .horizontal))
print(containerView.contentHuggingPriority(for: .horizontal))
print(containerView.contentCompressionResistancePriority(for: .horizontal))
结果如下图所示:
如果我尝试使用 2 个标签,它将产生正确的结果,这样标签就不会扩展其容器的宽度:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
print(leadingConstraint.priority)
leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
let trailingConstraint = topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
topConstraint.priority = .defaultLow
topConstraint.isActive = true
let bottomConstraint = topologyView.bottomAnchor.constraint(greaterThanOrEqualTo: containerView.bottomAnchor)
bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
label1.setContentHuggingPriority(.required, for: .horizontal)
label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "123124128"
label2.setContentHuggingPriority(.required, for: .horizontal)
label2.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label2)
label2.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label2.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label2.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
print(topologyView.contentHuggingPriority(for: .horizontal))
print(topologyView.contentCompressionResistancePriority(for: .horizontal))
print(containerView.contentHuggingPriority(for: .horizontal))
print(containerView.contentCompressionResistancePriority(for: .horizontal))
结果如下图所示:
我希望当我只显示 1 个标签时,标签不会扩展到其容器之外。
我想知道为什么前导和尾随约束在第一种情况下(有 1 个标签)不能正常工作,但在第二种情况下(有 2 个标签)却能正常工作?
我发现你在设置 label1.setContentHuggingPriority(.required, for: .horizontal)
。请尝试将优先级降低到 high
而不是 require
。
你有一些地方出了问题。
使用您的 "two label" playground 页面 as-is,如果您将 label2
的文本更改为:
label2.text = "01234567890 ABCDEFGHIJ"
你会得到这个:
如您所见,有两个标签并不 "solve the problem" ...它只是看起来有,因为您为第二个标签使用了非常短的字符串。
发生的事情是:当 auto-layout 处理约束并发现它不能完全满足所有约束时,它会使用优先级来确定它可以打破哪些约束而不会引发错误。在您的情况下,您正在设置各种约束和优先级,这些约束和优先级 不正确 授予 auto-layout 更改布局的权限。
所以,首先,我不知道您是从哪里想到将 topologyView
前导、尾随、顶部和底部约束的优先级设置为 .defaultLow
的。这样做是 显式地 告诉 auto-layout 在需要时忽略这些约束。然后,您添加一个比 topologyView
更宽的标签,并且 auto-layout 遵循您的指示并打破约束。
在您的 "two label" 示例中,auto-layout 优先于 label2
-- 这只是 发生 以使其看起来正确(直到你把标签加宽了)。
接下来,您使用 greaterThanOrEqualTo
不正确。通过设置:
topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
你是说“让 topologyView
的后缘 超越 containerView
的后缘 。你真正想要的是 小于:
topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
这将使 topologyView
的后缘小于 containerView
的后缘。
现在,不清楚您是否希望标签适合 containerView
的整个宽度,或者如果它们都很短,您是否希望它们居中。
如果全宽,使用 equalTo
...如果居中,使用 greatThanOrEqualTo
前导,lessThanOrEqualTo
尾随。
同样的事情也适用于底部约束。
所以...您的 "single label" 示例变为:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
导致(短标签):
或(长标签):
而您的 "two label" 示例是:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let label2 = UILabel()
label2.backgroundColor = .orange
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "012345 ABCDE"
// we can leave Hugging and Compression at default Priority
//label2.setContentHuggingPriority(.required, for: .horizontal)
//label2.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label2)
label2.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label2.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label2.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
短标签和长标签结果:
当标签是容器视图层次结构中的唯一标签时,标签会扩展到其容器之外。如果有 2 个标签,它工作正常并且两个标签都在容器视图中。
我的实际用例更复杂,但我尝试将其简化为以下代码。
Xcode 10.2 游乐场代码 (Swift 5):
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
print(leadingConstraint.priority)
leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
let trailingConstraint = topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
topConstraint.priority = .defaultLow
topConstraint.isActive = true
let bottomConstraint = topologyView.bottomAnchor.constraint(greaterThanOrEqualTo: containerView.bottomAnchor)
bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
label1.setContentHuggingPriority(.required, for: .horizontal)
label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
print(topologyView.contentHuggingPriority(for: .horizontal))
print(topologyView.contentCompressionResistancePriority(for: .horizontal))
print(containerView.contentHuggingPriority(for: .horizontal))
print(containerView.contentCompressionResistancePriority(for: .horizontal))
结果如下图所示:
如果我尝试使用 2 个标签,它将产生正确的结果,这样标签就不会扩展其容器的宽度:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
print(leadingConstraint.priority)
leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
let trailingConstraint = topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
topConstraint.priority = .defaultLow
topConstraint.isActive = true
let bottomConstraint = topologyView.bottomAnchor.constraint(greaterThanOrEqualTo: containerView.bottomAnchor)
bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
label1.setContentHuggingPriority(.required, for: .horizontal)
label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let label2 = UILabel()
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "123124128"
label2.setContentHuggingPriority(.required, for: .horizontal)
label2.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label2)
label2.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label2.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label2.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
print(topologyView.contentHuggingPriority(for: .horizontal))
print(topologyView.contentCompressionResistancePriority(for: .horizontal))
print(containerView.contentHuggingPriority(for: .horizontal))
print(containerView.contentCompressionResistancePriority(for: .horizontal))
结果如下图所示:
我希望当我只显示 1 个标签时,标签不会扩展到其容器之外。
我想知道为什么前导和尾随约束在第一种情况下(有 1 个标签)不能正常工作,但在第二种情况下(有 2 个标签)却能正常工作?
我发现你在设置 label1.setContentHuggingPriority(.required, for: .horizontal)
。请尝试将优先级降低到 high
而不是 require
。
你有一些地方出了问题。
使用您的 "two label" playground 页面 as-is,如果您将 label2
的文本更改为:
label2.text = "01234567890 ABCDEFGHIJ"
你会得到这个:
如您所见,有两个标签并不 "solve the problem" ...它只是看起来有,因为您为第二个标签使用了非常短的字符串。
发生的事情是:当 auto-layout 处理约束并发现它不能完全满足所有约束时,它会使用优先级来确定它可以打破哪些约束而不会引发错误。在您的情况下,您正在设置各种约束和优先级,这些约束和优先级 不正确 授予 auto-layout 更改布局的权限。
所以,首先,我不知道您是从哪里想到将 topologyView
前导、尾随、顶部和底部约束的优先级设置为 .defaultLow
的。这样做是 显式地 告诉 auto-layout 在需要时忽略这些约束。然后,您添加一个比 topologyView
更宽的标签,并且 auto-layout 遵循您的指示并打破约束。
在您的 "two label" 示例中,auto-layout 优先于 label2
-- 这只是 发生 以使其看起来正确(直到你把标签加宽了)。
接下来,您使用 greaterThanOrEqualTo
不正确。通过设置:
topologyView.trailingAnchor.constraint(greaterThanOrEqualTo: containerView.trailingAnchor)
你是说“让 topologyView
的后缘 超越 containerView
的后缘 。你真正想要的是 小于:
topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
这将使 topologyView
的后缘小于 containerView
的后缘。
现在,不清楚您是否希望标签适合 containerView
的整个宽度,或者如果它们都很短,您是否希望它们居中。
如果全宽,使用 equalTo
...如果居中,使用 greatThanOrEqualTo
前导,lessThanOrEqualTo
尾随。
同样的事情也适用于底部约束。
所以...您的 "single label" 示例变为:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
导致(短标签):
或(长标签):
而您的 "two label" 示例是:
import UIKit
import Foundation
import PlaygroundSupport
let viewController = UIViewController()
viewController.view.backgroundColor = UIColor.green
let containerView = UIView()
containerView.backgroundColor = .gray
containerView.translatesAutoresizingMaskIntoConstraints = false
viewController.view.addSubview(containerView)
containerView.widthAnchor.constraint(equalToConstant: 200).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 200).isActive = true
containerView.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor).isActive = true
containerView.centerYAnchor.constraint(equalTo: viewController.view.centerYAnchor).isActive = true
let topologyView = UIView()
topologyView.backgroundColor = .blue
topologyView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(topologyView)
let leadingConstraint = topologyView.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor)
// use default priority
//leadingConstraint.priority = .defaultLow
leadingConstraint.isActive = true
// use lessThanOrEqualTo
let trailingConstraint = topologyView.trailingAnchor.constraint(lessThanOrEqualTo: containerView.trailingAnchor)
// use default priority
//trailingConstraint.priority = .defaultLow
trailingConstraint.isActive = true
let topConstraint = topologyView.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor)
// use default priority
//topConstraint.priority = .defaultLow
topConstraint.isActive = true
// use lessThanOrEqualTo
let bottomConstraint = topologyView.bottomAnchor.constraint(lessThanOrEqualTo: containerView.bottomAnchor)
// use default priority
//bottomConstraint.priority = .defaultLow
bottomConstraint.isActive = true
topologyView.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
topologyView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
let label1Title = "1234"
let label1 = UILabel()
label1.backgroundColor = .yellow
label1.translatesAutoresizingMaskIntoConstraints = false
label1.text = Array(repeating: label1Title, count: 10).joined()
// we can leave Hugging and Compression at default Priority
//label1.setContentHuggingPriority(.required, for: .horizontal)
//label1.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label1)
label1.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label1.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label1.topAnchor.constraint(equalTo: topologyView.topAnchor).isActive = true
let label2 = UILabel()
label2.backgroundColor = .orange
label2.translatesAutoresizingMaskIntoConstraints = false
label2.text = "012345 ABCDE"
// we can leave Hugging and Compression at default Priority
//label2.setContentHuggingPriority(.required, for: .horizontal)
//label2.setContentCompressionResistancePriority(.required, for: .horizontal)
topologyView.addSubview(label2)
label2.leadingAnchor.constraint(equalTo: topologyView.leadingAnchor).isActive = true
label2.trailingAnchor.constraint(equalTo: topologyView.trailingAnchor).isActive = true
label2.bottomAnchor.constraint(equalTo: topologyView.bottomAnchor).isActive = true
label2.topAnchor.constraint(equalTo: label1.bottomAnchor).isActive = true
let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 350))
window.rootViewController = viewController
PlaygroundPage.current.liveView = window
PlaygroundPage.current.needsIndefiniteExecution = true
window.makeKeyAndVisible()
短标签和长标签结果: