使用contentLayoutGuide进行约束

Ham*_*pus 5 macos xcode cocoa objective-c osx-yosemite

NSTextView在WWDC上观看有关新UI高级功能的会话之后,尝试在OSX 10.10中使用新的Vibrant主题.我的文本视图未放置在标题栏旁边,因此我将内容视图设置为完全大小,以便将文本视图放在标题栏下方.

我的问题是我NSView在文本视图和标题栏之间有一个应该直接放在标题栏下面,但是我无法通过自动布局为我这样做.在视频中,他们使用以下新contentLayoutGuide属性提供此示例代码NSWindow:

NSLayoutConstraint *topEdgeConstraint = [NSLayoutConstraint constraintWithItem:myView attribute: NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:window.contentLayoutGuide attribute:NSLayoutAttributeTop];
Run Code Online (Sandbox Code Playgroud)

但是,每当我尝试安装Xcode给我的约束时,我都无法使用它

无法在视图上安装约束.约束是否引用了视图子树之外的内容?那是违法的.

我得到示例中使用的窗口属性不在视图的子树中,因为视图放在窗口内但我应该如何访问该contentLayoutGuide属性?

目前我正在尝试-awakeFromNib在子类中添加方法中的约束NSWindow.错误的方法可能吗?

提前致谢

sam*_*sam 8

在Yosemite中,约束现在具有"活动"属性,您可以将其设置为使约束处于活动状态而不将其置于共同的祖先上.我认为它是专门为这样的情况创建的,你不知道共同的祖先.

NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem: myView attribute: NSLayoutAttributeTop relatedBy: NSLayoutRelationEqual toItem: window.contentLayoutGuide attribute: NSLayoutAttributeTop];
constraint.active = YES
Run Code Online (Sandbox Code Playgroud)


Tim*_*oes 7

我最近遇到了这个问题,并认为我今天会分享推荐的处理方法。该技术可以在 WWDC 2016 Session 239“Crafting Modern Cocoa Apps”中看到。自从他们发布 API 以来,API 已经发生了变化,因此发生了一些变化。

以下代码searchField通过使用 windows contentLayoutGuide 将其限制在内容视图的顶部,将一个名为 的 NSSearchField 放在标题/工具栏区域的正下方。下面的代码被添加到一个 NSViewController 中。

@IBOutlet weak var searchField: NSSearchField!
private var titleBarConstraint: NSLayoutConstraint?

override func updateViewConstraints() {
   if titleBarConstraint == nil {
      if let topAnchor = (searchField.window?.contentLayoutGuide as? NSLayoutGuide)?.topAnchor {
         titleBarConstraint = searchField.topAnchor.constraint(equalTo: topAnchor, constant: 8)
         titleBarConstraint?.isActive = true
      }
   }

   super.updateViewConstraints()
}
Run Code Online (Sandbox Code Playgroud)

在 Interface Builder 中,NSSearchField 使用自动布局定位,以匹配运行时的外观。单击 NSSearchField 的顶部约束并启用“Placeholder Remove at build time”复选框。

contentLayoutGuide 仍然返回,Any?但它是一个 NSLayoutGuide。这就是转折。


Kon*_*hin 0

编辑:此解决方案不再可接受,因为 OS X El Capitan 在窗口框架中具有不同的视图层次结构。寻找sam 的答案,他建议使用 Yosemite 中引入的新 NSLayoutConstraint 方法和属性(约束激活)。

我昨天遇到了同样的问题。

不幸的是,文档缺乏有关在何处放置此约束的信息。新的 Xcode“捕获视图层次结构”功能可以拯救您!

当您约束两个视图的某些属性时,您必须将结果约束放置在这些视图的第一个共同祖先上。这是基本的自动布局规则。

在您的代码中,您引用了window.contentLayoutGuide,它声明为 id ,但实际上是一个NSContentLayoutView. 运行您的应用程序并捕获视图层次结构。以下是您在优胜美地应该获得的信息:

在此输入图像描述

您必须将约束添加到NSThemeFrame视图中,因为这是子树包含您myViewNSContentLayoutView. 这个私有视图由 NSWindow 管理,没有明显的属性可以从窗口实例中获取它,但我们可以轻松地遍历视图层次结构。

这是完整的代码示例:

NSWindow* window = <Get the window>;

NSLayoutConstraint* constraint = [NSLayoutConstraint constraintWithItem: myView attribute: NSLayoutAttributeTop relatedBy: NSLayoutRelationEqual toItem: window.contentLayoutGuide attribute: NSLayoutAttributeTop];

[((NSView*)window.contentLayoutGuide).superview addConstraint: constraint];
Run Code Online (Sandbox Code Playgroud)