简体   繁体   English

NSLayoutConstraint 用于设置最小和最大视图宽度

[英]NSLayoutConstraint for setting Min and Max view width

What I want to achieve in AppKit (not in SwiftUI) : [GIF] (example in SwiftUI)我想在 AppKit 中实现的(不是在 SwiftUI 中)[GIF] (在 SwiftUI 中的示例)

  • The NSWindow max width should not be limited to the NSTextField max width. NSWindow最大宽度不应限制为NSTextField最大宽度。
  • The NSWindow min width should be limited to the NSTextField min width. NSWindow最小宽度限制为NSTextField最小宽度。
  • NSTextField need to have these parameters: [ min width: 200 , max width: 400 ] NSTextField需要有这些参数: [ min width: 200 , max width: 400 ]

I had several attempts to implement this behavior in AppKit.我曾多次尝试在 AppKit 中实现这种行为。 I've been trying to do this for a few days now, but it doesn't work.这几天我一直在尝试这样做,但它不起作用。 [PIC] [GIF] [图片] [GIF]

I tried to set the low priority on Leading / Trailing constraint.我试图在前导/尾随约束上设置低优先级。
This partially fixed the situation.这部分解决了这种情况。 I was able to change the size of the window normally, but the window size was not limited to the minimum size of NSTextField .我能够正常更改 window 的大小,但 window 的大小不限于NSTextField的最小大小。 [GIF] [GIF]

The important thing to notice here is that you only want the low priority constraints to be one way .这里要注意的重要一点是,您只希望低优先级约束成为一种方式 That is, you don't want something like this:也就是说,你不想要这样的东西:

// throughout the answer, I use "tf" for the text field, and "view" for its superview
let weakLeadingConstraint = tf.leadingAnchor.constraint(equalTo: view.leadingAnchor)
let weakTrailingConstraint = tf.trailingAnchor.constraint(equalTo: view.trailingAnchor)
weakLeadingConstraint.priority = .dragThatCannotResizeWindow
weakTrailingConstraint.priority = .dragThatCannotResizeWindow

Because these constraints would break when the window is resized, allowing the window to be resizable to any width where the leading and trailing anchors are "not equal" to those of the text field.因为当 window 被调整大小时,这些约束会被打破,因此允许 window 调整大小到任何宽度,其中前导和尾随锚点与文本字段的锚点“不相等”。

Instead, the low priority constraints should be >= or <= constraints.相反,低优先级约束应该是 >= 或 <= 约束。 Think of the 2 equality constraints as the following 4 inequality constraints:将 2 个等式约束视为以下 4 个不等式约束:

  • tf.leading <= view.leading
  • tf.trailing >= view.trailing
  • tf.leading >= view.leading
  • tf.trailing <= view.trailing

It is the first 2 that you want to break, leaving the last 2 (which says that the text field should always be within the window) in tact, when you resize the window.当您调整 window 的大小时,它是您想要中断的前 2 个,而最后 2 个(表示文本字段应始终在窗口内)保持不变。

The other constraints are quite straightforward, so I'll just present the whole code here:其他约束非常简单,所以我将在这里展示整个代码:

tf.translatesAutoresizingMaskIntoConstraints = false

let weakLeadingConstraint = tf.leadingAnchor.constraint(lessThanOrEqualTo: view.leadingAnchor)
let weakTrailingConstraint = tf.trailingAnchor.constraint(greaterThanOrEqualTo: view.trailingAnchor)
weakLeadingConstraint.priority = .dragThatCannotResizeWindow
weakTrailingConstraint.priority = .dragThatCannotResizeWindow

NSLayoutConstraint.activate([
    tf.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    tf.centerYAnchor.constraint(equalTo: view.centerYAnchor),
    tf.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor),
    tf.trailingAnchor.constraint(lessThanOrEqualTo: view.trailingAnchor),
    weakLeadingConstraint,
    weakTrailingConstraint,
    tf.widthAnchor.constraint(greaterThanOrEqualToConstant: 200),
    tf.widthAnchor.constraint(lessThanOrEqualToConstant: 400),
])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM