【问题标题】:Autolayout: Can't resize window after setting constraints自动布局:设置约束后无法调整窗口大小
【发布时间】:2015-06-04 00:13:46
【问题描述】:

我需要一些有关以编程方式设置自动布局的帮助。我有一个视图,我将其设置为由情节提要管理的另一个视图。

var content = NSView(frame: NSRect(x: 0, y: 0, width: 3000, height: self.view.frame.height))
[...]
scrollingView.documentView = content

比我添加视图将始终从上到下的引脚约束:

    let topPinContraints = NSLayoutConstraint(
        item: contentView
        , attribute: NSLayoutAttribute.Top
        , relatedBy: .Equal
        , toItem: contentView.superview
        , attribute: NSLayoutAttribute.Top
        , multiplier: 1.0
        , constant: 0
    )
    let bottomPinContraints = NSLayoutConstraint(
          item: contentView
        , attribute: NSLayoutAttribute.Bottom
        , relatedBy: .Equal
        , toItem: contentView.superview
        , attribute: NSLayoutAttribute.Bottom
        , multiplier: 1.0
        , constant: 0
    )
    let heightContraints = NSLayoutConstraint(
        item: contentView
        , attribute: NSLayoutAttribute.Height
        , relatedBy: .Equal
        , toItem: contentView.superview
        , attribute: NSLayoutAttribute.Height
        , multiplier: 1.0
        , constant: 0
    )

    NSLayoutConstraint.activateConstraints([
          topPinContraints
        , bottomPinContraints
        , heightContraints
    ])

    contentView.needsLayout = true

在 NSLayoutConstraint.activateConstraints 之后,视图在父视图中从上到下填充,但是窗口的高度不再可调整大小。 我可以调整它的宽度,但高度现在是固定的。

如何在不丢失调整大小的可能性的情况下添加顶部和底部图钉?

非常感谢,

ps.

【问题讨论】:

  • content(在你的第一个 sn-p 中)和 contentView(在你的第二个中)是同一个东西吗?您是否在视图上将 translatesAutoresizingMaskIntoConstraints 设置为 false?另外,如果documentView 被固定到它的父视图,也就是剪辑视图,在什么情况下滚动视图会滚动?也就是说,文档视图什么时候会和滚动视图的内容大小不一样?
  • 嗨,肯,是的,对不起。 contentView = view,因为我将它放入 func: func autoLayout(contentView: NSView){}。当我设置 contentView.translatesAutoresizingMaskIntoConstraints = false 时,视图会完全消失。
  • 我可以设置没有 contentView.translatesAutoresizingMaskIntoConstraints 的 heightContraints 和 widthtContraints,但是滚动视图不再起作用,因为我认为宽度比 contentView.superview!.frame.with 还要大。 :-(
  • 最后一件事:我可以用 let computedWith: CGFloat = (CGFloat) (contentView.subviews.count * 130) 计算,因为我的子视图具有固定大小。但是如何更新约束呢?由于 NSConstraintBasedLayoutVisualizeMutuallyExclusiveConstraints 错误,我无法调用我的 autoLayout 函数两次。

标签: macos cocoa autolayout


【解决方案1】:

最后我得到了一些适合我的代码。但这是正确的解决方案吗?让我发布我的整个 ViewController 来向您展示我的经验。也许你可以发布你的 cmets 我可以做得更好。

import Foundation
import Cocoa

class ColoumnMasterViewController: NSViewController {

@IBOutlet weak var scrollingView: NSScrollView!

var position = 0
var contentView: NSView?
var widthtContraints: NSLayoutConstraint?

override func viewDidLoad() {
    contentView = NSView(frame: NSRect(x: 0, y: 0, width: 3000, height: self.view.frame.height))

    contentView!.wantsLayer = true
    contentView!.layer?.backgroundColor =  NSColor.redColor().CGColor

    add()
    var timer = NSTimer.scheduledTimerWithTimeInterval(1.6, target: self, selector: Selector("add"), userInfo: nil, repeats: true)

    scrollingView.documentView = contentView

    autoLayout(contentView!)
}

func add(){
    println("add view on position \(position)")
    let vc: NSViewController = self.storyboard?.instantiateControllerWithIdentifier("coloumn_view_controller") as! NSViewController
    vc.view.setFrameOrigin(NSPoint(x: (position++ * 130), y: 0))
    vc.view.setFrameSize(NSSize(width: 130, height: self.view.frame.height))
    contentView!.addSubview(vc.view)

    updateWidth()
}

func autoLayout(contentView: NSView){
    let topPinContraints = NSLayoutConstraint(
        item: contentView
        , attribute: NSLayoutAttribute.Top
        , relatedBy: .Equal
        , toItem: contentView.superview
        , attribute: NSLayoutAttribute.Top
        , multiplier: 1.0
        , constant: 0
    )
    let bottomPinContraints = NSLayoutConstraint(
          item: contentView
        , attribute: NSLayoutAttribute.Bottom
        , relatedBy: .Equal
        , toItem: contentView.superview
        , attribute: NSLayoutAttribute.Bottom
        , multiplier: 1.0
        , constant: 0
    )

    println("heightContraints \(contentView.superview!.frame.height)")
    let heightContraints = NSLayoutConstraint(
        item: contentView
        , attribute: NSLayoutAttribute.Height
        , relatedBy: .Equal
        , toItem: contentView.superview!
        , attribute: NSLayoutAttribute.Height
        , multiplier: 1.0
        , constant: 0
    )
    println("widthtContraints \(contentView.superview!.frame.width)")
    let calculatedWith: CGFloat = (CGFloat) (contentView.subviews.count * 130)
    widthtContraints = NSLayoutConstraint(
        item: contentView
        , attribute: NSLayoutAttribute.Width
        , relatedBy: .Equal
        , toItem: nil
        , attribute: NSLayoutAttribute.Width
        , multiplier: 1.0
        , constant: 0
    )
    widthtContraints!.constant = calculatedWith

    NSLayoutConstraint.activateConstraints([
          topPinContraints
         , bottomPinContraints
         , heightContraints
         , widthtContraints!
    ])

    contentView.translatesAutoresizingMaskIntoConstraints = false
    contentView.needsLayout = true

}

func updateWidth(){
    let calculatedWith: CGFloat = (CGFloat) (contentView!.subviews.count * 130)
    if (widthtContraints != nil) {
        widthtContraints!.constant = calculatedWith
    }
}

}

万分感谢,

ps

【讨论】:

  • translatesAutoresizingMaskIntoConstraints 设置为 false 对我有用。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
相关资源
最近更新 更多