Peter Shaw
Peter Shaw

Reputation: 1907

Autolayout: Can't resize window after setting constraints

i need some help with auto-layout setting programatically. I have a view that I set into another view that is managed by storyboard.

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

Than i add the pin constraints that the view will always be top to bottom:

    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

After NSLayoutConstraint.activateConstraints the view is filled from top to bottom in the superview, but the window is not resizable in height anymore. I can resize it in width, but the height is now fixed.

How do I add a top and bottom pin without loosing the resize possibilities?

Thanks a lot,

ps.

Upvotes: 1

Views: 1298

Answers (1)

Peter Shaw
Peter Shaw

Reputation: 1907

Finally i had some code that works for me. But is it the right solution? Let me post my whole ViewController to show you my experience. Maybe you can post your comments what I can make better.

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
    }
}

}

Thanks thousand times,

ps

Upvotes: 2

Related Questions