swift - Resize superview with autolayout depending on largest subview -
what best practice resize superview autolayout if have inner nsview
columns dynamic heights?
for example. if have 2 column layout, left column height bigger right column, superview height should right column height. than, if change right column height bigger left column height, superview height should change height of right column. how accomplish this?
i made sample project test this:
- initially have layout 2 columns,
.bottom
constraint of leftnsview
attached bottom of superview.
- if press
make right bigger
button, make height of rightnsview
bigger left one.
so want here superview change height depending on bigger column (right column). there practice so?
code:
import cocoa class viewcontroller: nsviewcontroller { let leftview = nsview() let rightview = nsview() let button = nsbutton() var rightviewheightconstraint: nslayoutconstraint? override func loadview() { self.view = testview() } override func viewdidload() { super.viewdidload() leftview.backgroundcolor = nscolor.redcolor() rightview.backgroundcolor = nscolor.orangecolor() layoutleft(view, insertview: leftview) layoutright(view, insertview: rightview) button.title = "make right bigger" button.target = self button.action = "makebigger:" viewcontrollerlayout.layoutbotton(view, insertview: button, bottom: -20) } func makebigger(sender: anyobject) { rightviewheightconstraint?.animator().constant = 150.0 } func layoutleft(containerview: nsview, insertview: nsview) { insertview.translatesautoresizingmaskintoconstraints = false containerview.addsubview(insertview) let c1 = nslayoutconstraint(item: insertview, attribute: .left, relatedby: .equal, toitem: containerview, attribute: .left, multiplier: 1.0, constant: 0.0) let c2 = nslayoutconstraint(item: insertview, attribute: .width, relatedby: .equal, toitem: containerview, attribute: .width, multiplier: 0.5, constant: 0.0) let c3 = nslayoutconstraint(item: insertview, attribute: .height, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1.0, constant: 100.0) let c4 = nslayoutconstraint(item: insertview, attribute: .top, relatedby: .equal, toitem: containerview, attribute: .top, multiplier: 1.0, constant: 0.0) let c5 = nslayoutconstraint(item: insertview, attribute: .bottom, relatedby: .equal, toitem: containerview, attribute: .bottom, multiplier: 1.0, constant: -60.0) containerview.addconstraint(c1) containerview.addconstraint(c2) containerview.addconstraint(c3) containerview.addconstraint(c4) containerview.addconstraint(c5) } func layoutright(containerview: nsview, insertview: nsview) { insertview.translatesautoresizingmaskintoconstraints = false containerview.addsubview(insertview) let c1 = nslayoutconstraint(item: insertview, attribute: .right, relatedby: .equal, toitem: containerview, attribute: .right, multiplier: 1.0, constant: 0.0) let c2 = nslayoutconstraint(item: insertview, attribute: .width, relatedby: .equal, toitem: containerview, attribute: .width, multiplier: 0.5, constant: 0.0) let c3 = nslayoutconstraint(item: insertview, attribute: .height, relatedby: .equal, toitem: nil, attribute: .notanattribute, multiplier: 1.0, constant: 50.0) let c4 = nslayoutconstraint(item: insertview, attribute: .top, relatedby: .equal, toitem: containerview, attribute: .top, multiplier: 1.0, constant: 0.0) let c5 = nslayoutconstraint(item: insertview, attribute: .bottom, relatedby: .equal, toitem: containerview, attribute: .bottom, multiplier: 1.0, constant: -60.0) containerview.addconstraint(c1) containerview.addconstraint(c2) containerview.addconstraint(c3) containerview.addconstraint(c4) // containerview.addconstraint(c5) // cant add .bottom constraint here, because of different column sizes. rightviewheightconstraint = c3 } } struct viewcontrollerlayout { static func layoutbotton(containerview: nsview, insertview: nsview, bottom: double) { insertview.translatesautoresizingmaskintoconstraints = false containerview.addsubview(insertview) containerview.addconstraint(nslayoutconstraint(item: insertview, attribute: .centerx, relatedby: .equal, toitem: containerview, attribute: .centerx, multiplier: 1.0, constant: 0.0)) containerview.addconstraint(nslayoutconstraint(item: insertview, attribute: .bottom, relatedby: .equal, toitem: containerview, attribute: .bottom, multiplier: 1.0, constant: cgfloat(bottom))) } }
download test project: github
first create constraint on superview height
let heightconstraint = nslayoutconstraint(item: view, attribute: nslayoutattribute.height, relatedby: nslayoutrelation.equal, toitem: nil, attribute: nslayoutattribute.notanattribute, multiplier: 1, constant: greaterheightamongtwocolumns)
as discussed in comment, can post notification , let super view know updated frame. super view check if updated height of of 2 columns greater current height , update heightconstraint declared above , call
[self layoutifneeded]
on superview's superview laid out new frame.
Comments
Post a Comment