Ios 如何通过优先级更改内部内容大小

Ios 如何通过优先级更改内部内容大小,ios,swift,autolayout,nslayoutconstraint,Ios,Swift,Autolayout,Nslayoutconstraint,我希望第二个标签(subview2)保持不变,并随着容器视图的大小减小而收缩第一个标签(subview1),但无论我如何调整优先级,第二个标签仍会收缩: 导入UIKit 导入PlaygroundSupport 让containerView=UIView(帧:CGRect(原点:.0,大小:.init(宽度:200,高度:300))) 让子视图1=UILabel() subview1.text=“你好” 子视图1.backgroundColor=.red containerView.addSubv

我希望第二个标签(
subview2
)保持不变,并随着容器视图的大小减小而收缩第一个标签(
subview1
),但无论我如何调整优先级,第二个标签仍会收缩:

导入UIKit
导入PlaygroundSupport
让containerView=UIView(帧:CGRect(原点:.0,大小:.init(宽度:200,高度:300)))
让子视图1=UILabel()
subview1.text=“你好”
子视图1.backgroundColor=.red
containerView.addSubview(子视图1)
子视图1.translatesAutoresizingMaskIntoConstraints=false
让子视图2=UILabel()
subview2.text=“你好”
subview2.backgroundColor=.cyan
containerView.addSubview(subview2)
子视图2.translatesAutoresizingMaskIntoConstraints=false
let视图:[字符串:任意]=[“子视图1”:子视图1,“子视图2”:子视图2]
让con1=NSLayoutConstraint.constraints(使用VisualFormat:|-(20)-(子视图1]”,度量值:nil,视图:视图)
让con2=NSLayoutConstraint.constraints(使用VisualFormat:|-(20)-(子视图2]”,度量值:nil,视图:视图)
设con3=NSLayoutConstraint.constraints(具有可视化格式:“H:|-(30)-(子视图1]”,度量值:nil,视图:视图)
让con4=NSLayoutConstraint.constraints(使用VisualFormat:“H:[子视图2]-(30)-|”,度量:nil,视图:视图)
设con5=NSLayoutConstraint.constraints(具有可视化格式:“H:[子视图1(>=100)]-(>=30)-[子视图2(>=100)]”,度量值:零,视图:视图)
NSLayoutConstraint.activate(con1+con2+con3+con4+con5)
子视图1.setContentCompressionResistancePriority(UILayoutPriority.defaultLow,用于:。水平)
子视图2.setContentCompressionResistancePriority(UILayoutPriority.defaultHigh,用于:。水平)
PlaygroundPage.current.NeedsDefiniteExecution=true
PlaygroundPage.current.liveView=containerView

我已尝试手动增加
子视图2
的优先级,但仍然不起作用:

let priority1=subview2.contentCompressionResistancePriority(用于:。水平)
打印(优先级1)//750
让优先级2=子视图2.contentCompressionResistancePriority(对于:。水平)
打印(优先级2)//750
子视图2.setContentCompressionResistancePriority(优先级2+100,用于:。水平)
VFL(可视格式语言)非常过时和有限。我强烈建议您切换到更现代(更灵活)的语法

也就是说,问题在于这一行:

let con5 = NSLayoutConstraint.constraints(withVisualFormat: 
            "H:[subview1(>=100)]-(>=30)-[subview2(>=100)]", metrics: nil, views: views)
您的代码是:

  • 子视图1
    宽度必须大于或等于
    100
  • 子视图2
    宽度必须大于或等于
    100
因此,
setContentCompressionResistancePriority
行没有任何作用。您已经说过“这些是所需的最小宽度。”

如果将该行更改为:

let con5 = NSLayoutConstraint.constraints(withVisualFormat:
            "H:[subview1]-(>=30)-[subview2]", metrics: nil, views: views)
你应该得到你想要的结果

不过,您的代码使用的是更现代的约束语法——您可能会发现它更符合逻辑,更容易理解:

NSLayoutConstraint.activate([

    // both labels 20-pts from containerView Top
    subview1.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 20.0),
    subview2.topAnchor.constraint(equalTo: containerView.topAnchor, constant: 20.0),

    // left label Leading 30-pts from containerView Leading
    subview1.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 30.0),

    // right label Trailing 30-pts from containerView Trailing
    subview2.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -30.0),

    // right label Leading at least 30-pts from left label Trailing
    subview2.leadingAnchor.constraint(greaterThanOrEqualTo: subview1.trailingAnchor, constant: 30.0),

])

// don't do any of this...
//let views: [String: Any] = ["subview1": subview1, "subview2": subview2]
//let con1 = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(20)-[subview1]", metrics: nil, views: views)
//let con2 = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(20)-[subview2]", metrics: nil, views: views)
//let con3 = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(30)-[subview1]", metrics: nil, views: views)
//let con4 = NSLayoutConstraint.constraints(withVisualFormat: "H:[subview2]-(30)-|", metrics: nil, views: views)
//let con5 = NSLayoutConstraint.constraints(withVisualFormat: "H:[subview1]-(>=30)-[subview2]", metrics: nil, views: views)
//NSLayoutConstraint.activate(con1 + con2 + con3 + con4 + con5)

编辑-回答评论

如果希望标签的宽度分别为
=100
,但允许压缩(左标签先压缩),则需要添加优先级小于
的宽度约束。必需的

// both labels should have a width of >= 100
let leftWidth = subview1.widthAnchor.constraint(greaterThanOrEqualToConstant: 100.0)
let rightWidth = subview2.widthAnchor.constraint(greaterThanOrEqualToConstant: 100.0)

// set the Priority on the width constraints to less than required
//  to allow auto-layout to break that constraint if needed
leftWidth.priority = .defaultHigh
rightWidth.priority = .defaultHigh

// activate the width constraints
leftWidth.isActive = true
rightWidth.isActive = true

// tell leftLabel to compress before rightLabel
subview1.setContentCompressionResistancePriority(UILayoutPriority.defaultLow, for: .horizontal)
subview2.setContentCompressionResistancePriority(UILayoutPriority.defaultHigh, for: .horizontal)

谢谢你的回答。我同意使用现代自动布局。我的方法更像是一种学术方法,了解优先级的性质和固有的内容大小,以及更改它们如何影响布局。在不完全去掉宽度常量的情况下,如何将子视图指定为“具有一定的宽度,但在容器小于给定宽度时仅减小大小”?假设一开始我希望每个视图都有100个点,如果子视图的优先级高于容器的优先级。